Redcarpet/Bluecloth 不允许标题?
Posted
技术标签:
【中文标题】Redcarpet/Bluecloth 不允许标题?【英文标题】:Redcarpet/Bluecloth not allowing headers? 【发布时间】:2011-09-24 07:53:40 【问题描述】:有没有办法使用 Redcarpet 或 Bluecloth,这样当它插入 markdown 时就不会产生任何标题?
例如:
#header 1
产量:
标题 1
标题 1(首选)
还有:
##header 2
产量:
标题 2
标题 2(首选)
【问题讨论】:
为什么不用一点 CSS 来设置标题的样式,让它们看起来像你想要的那样? 【参考方案1】:嗯,你可以在 Markdown 中转义字符:
# header 1
\# header 1
## header 2
\## header 2
...给出:
标题 1
#标题1
标题 2
## 标题 2
如果您不想这样做,或者您正在解析其他人的 Markdown 并且没有选择,我建议您对传入的 Markdown 进行预处理以为您执行上述操作:
def pound_filter text
text.gsub /^#/, '\#'
end
使用 Redcarpet 您可以验证它是否有效:
text = <<-END
# Hello
## World
END
Markdown.new(text.to_html)
# => <h1>Hello</h1>
#
# <h2>World</h2>
Markdown.new(pound_filter text).to_html
# => <p># Hello
# ## World</p>
当然,因为 HTML 中的换行符实际上并不会像这样呈现——它会显示为一行:
#你好##世界”
...您可能想要增强它:
def pound_filter text
text.gsub( /((\A^)|([^\A]^))#/ ) |match| "\n" == match[0] ? "\n\n\\#" : '\#'
end
pound_filter text
# => \# Hello
#
# \## World
Markdown.new(pound_filter text).to_html
# => <p>\# Hello</p>
#
# <p>\## World</p>
最后一个将显示为:
#你好
##世界
不幸的是,您最终会进入像这样的奇怪领域,其中标题位于引号内:
> ## Heading
...但我把它留给读者作为练习。
【讨论】:
【参考方案2】:看到类似的解决方案here 是这样的:
class RenderWithoutWrap < Redcarpet::Render::HTML
def postprocess(full_document)
Regexp.new(/\A<p>(.*)<\/p>\Z/m).match(full_document)[1] rescue full_document
end
end
它会删除所有 <p>
和 </p>
标记。我就这样使用它并且它起作用了。我将该类放在一个名为/config/initializers/render_without_wrap.rb
的新文件中。你可以对所有<h1>
-<h6>
标签做类似的事情
class RenderWithoutHeaders < Redcarpet::Render::HTML
def postprocess(full_document)
Regexp.new(/\A<h1>(.*)<\/h1>\Z/m).match(full_document)[1] rescue full_document
Regexp.new(/\A<h2>(.*)<\/h2>\Z/m).match(full_document)[1] rescue full_document
Regexp.new(/\A<h3>(.*)<\/h3>\Z/m).match(full_document)[1] rescue full_document
...(you get the idea)
end
end
你可以这样使用它
def custom_markdown_parse(text)
markdown = Redcarpet::Markdown.new(RenderWithoutHeaders.new(
filter_html: true,
hard_wrap: true,
other_options: its_your_call
))
markdown.render(text).html_safe
end
我没有测试过,但这是一个想法。
【讨论】:
这是一个很好的解决方案。但是,对于标题标签,您可能不需要正则表达式中的 \A 和 \Z,这仅仅是因为标题标签不一定像标签那样包装整段文本。此外,如果有多个 h2 或多个 h3,这也不起作用。知道如何使正则表达式在这种情况下工作吗?
@DelPiero 不是。我只是在反省我所看到的。不过我敢肯定有办法。研究它并在这里发布!【参考方案3】:1。您应该能够使用反斜杠转义 Markdown 源文本:
\# not a header
2。您也可以对其进行猴子修补:
module RedCloth::Formatters::HTML
[:h1, :h2, :h3, :h4, :h5, :h6].each do |m|
define_method(m) do |opts|
"#opts[:text]\n"
end
end
end
【讨论】:
不幸的是,猴子修补 HTML 格式化程序具有同时禁用下划线样式 (----
/====
) 标头的副作用,这可能不是 OP 的意图。为了防止在不影响其他标题的情况下解析 ##
s,您必须在 C 中实际修补 BlueCloth/Sundown/Discount。【参考方案4】:
考虑到对 Markdown 进行预解析很困难,而且 Markdown 允许插入 HTML,如何从生成的 HTML 中去除标题元素呢?
【讨论】:
以上是关于Redcarpet/Bluecloth 不允许标题?的主要内容,如果未能解决你的问题,请参考以下文章