用Ruby中的markdown(Github Markdown-style)解释换行符

时间:2010-11-20 00:07:03

标签: ruby-on-rails ruby formatting markdown

我正在使用markdown在我的网站上发表评论,我希望用户能够通过按输入而不是 space space来创建换行符 输入see this meta question for more details on this idea

我如何在Ruby中执行此操作?你会认为Github Flavored Markdown正是我所需要的,但(令人惊讶的是),这是非常错误的。

Here's their implementation

# in very clear cases, let newlines become <br /> tags
text.gsub!(/^[\w\<][^\n]*\n+/) do |x|
  x =~ /\n{2}/ ? x : (x.strip!; x << "  \n")
end

此逻辑要求该行以\w开头,以便在末尾创建换行符以创建<br>。这个要求的原因是你不要乱用列表:(但请看下面的编辑;我甚至不确定这是否有意义)

* we don't want a <br>
* between these two list items

然而,在这些情况下逻辑突破:

[some](http://google.com)
[links](http://google.com)
*this line is in italics*
another line
> the start of a blockquote!
another line

即,在所有这些情况下,第一行末尾应该有<br>,但GFM不会添加一个

奇怪的是,这在javascript version of GFM中正常工作。

有没有人在Ruby中有“新行到<br> s”的工作实现?

编辑:它变得更加令人困惑!

如果你查看了Github的official Github Flavored Markdown repository,你会发现又是<br>正则表达式的新行!

# in very clear cases, let newlines become <br /> tags
text.gsub!(/(\A|^$\n)(^\w[^\n]*\n)(^\w[^\n]*$)+/m) do |x|
  x.gsub(/^(.+)$/, "\\1  ")
end

我不知道这个正则表达式意味着什么,但在上述测试用例中没有做得更好。

,它看起来不像“不要乱用列表”,因为要求以字符开头的行开头是有效的。即,无论是否添加2个尾随空格,标准降价列表语义都不会改变。这里:

  • 第1项
  • 第2项
  • 第3项

在这个问题的来源中,在“第1项”之后有2个尾随空格,但是如果你看一下HTML,就没有多余的<br>

这让我觉得将换行符转换为<br>的最佳正则表达式只是:

text.gsub!(/^[^\n]+\n+/) do |x|
  x =~ /\n{2}/ ? x : (x.strip!; x << "  \n")
end

思想?

2 个答案:

答案 0 :(得分:2)

我不确定这是否会有所帮助,但我只是使用simple_format() 来自ActionView :: Helpers :: TextHelper

ActionView simple_format

my_text = "Here is some basic text...\n...with a line break."

simple_format(my_text)

output => "<p>Here is some basic text...\n<br />...with a line break.</p>"

即使它不符合您的规格,查看simple_format()源代码.gsub!方法可能会帮助您编写自己的所需降价版本。

答案 1 :(得分:2)

有点太晚了,但也许对其他人有用。我已经通过使用正则表达式预处理文本来使用它(但没有经过彻底的测试),就像这样。由于缺乏零宽度的外观,这很可怕,但是很好。

# Append two spaces to a simple line, if it ends in newline, to render the
# markdown properly. Note: do not do this for lists, instead insert two newlines. Also, leave double newlines
# alone.
text.gsub! /^ ([\*\+\-]\s+|\d+\s+)? (.+?) (\ \ )? \r?\n (\r?\n|[\*\+\-]\s+|\d+\s+)? /xi do
  full, pre, line, spaces, post = $~.to_a
  if post != "\n" && pre.blank? && post.blank? && spaces.blank?
    "#{pre}#{line}  \n#{post}"
  elsif pre.present? || post.present?
    "#{pre}#{line}\n\n#{post}"
  else
    full
  end
end