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

它会删除所有 &lt;p&gt;&lt;/p&gt; 标记。我就这样使用它并且它起作用了。我将该类放在一个名为/config/initializers/render_without_wrap.rb 的新文件中。你可以对所有&lt;h1&gt;-&lt;h6&gt; 标签做类似的事情

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 不允许标题?的主要内容,如果未能解决你的问题,请参考以下文章

“方法不允许 请求的 URL 不允许该方法。”

ListView Android 不允许选择器工作,也不允许选择

方法不允许。请求的 URL 不允许该方法。在烧瓶上

捕获“访问控制允许来源不允许来源”错误

不允许访问控制允许标头

不允许的方法 (POST):/profiles/flash/ 不允许的方法:/profiles/flash/