在 Ruby 中将换行符解释为 Markdown(Github Markdown 风格)中的

发布于 2024-10-03 02:42:17 字数 2310 浏览 2 评论 0 原文

我在网站上使用 Markdown 进行评论,并且希望用户能够通过按 enter 而不是 space space 来创建换行符 < kbd>输入 (有关此想法的更多详细信息,请参阅此元问题

我如何在 Ruby 中做到这一点?你可能会认为 Github Flavored Markdown 正是我所需要的,但是(令人惊讶的是),这是相当有问题的。

这是他们的实现

# 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 在末尾换行以创建
。此要求的原因是您不要弄乱列表:(但请参阅下面的编辑;我什至不确定这是否有意义)

* 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

即,在所有这些情况下应该是第一行末尾的
,但 GFM 没有添加一个

奇怪的是,这在 GFM 的 JavaScript 版本

有谁在 Ruby 中实现了“
s 的新行”吗?

编辑:这变得更加混乱!

如果您查看 Github 的官方 Github Flavored Markdown 存储库,你会发现
正则表达式又多了一个换行符!:

# 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 个尾随空格,标准 Markdown 列表语义都不会改变。这里:

  • item 1
  • item 2
  • item 3

在这个问题的源代码中,“item 1”后面有 2 个尾随空格,但是如果您查看 HTML,则没有多余的

这让我认为将换行符转换为
的最佳正则表达式就是:

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

想法?

I'm using markdown for comments on my site and I want users to be able to create line breaks by pressing enter instead of space space enter (see this meta question for more details on this idea)

How can I do this in Ruby? You'd think Github Flavored Markdown would be exactly what I need, but (surprisingly), it's quite buggy.

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

This logic requires that the line start with a \w for a linebreak at the end to create a <br>. The reason for this requirement is that you don't to mess with lists: (But see the edit below; I'm not even sure this makes sense)

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

However, the logic breaks in these cases:

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

I.e., in all of these cases there should be a <br> at the end of the first line, and yet GFM doesn't add one

Oddly, this works correctly in the javascript version of GFM.

Does anyone have a working implementation of "new lines to <br>s" in Ruby?

Edit: It gets even more confusing!

If you check out Github's official Github Flavored Markdown repository, you'll find yet another newline to <br> regex!:

# 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

I have no clue what this regex means, but it doesn't do any better on the above test cases.

Also, it doesn't look like the "don't mess with lists" justification for requiring that lines start with word characters is valid to begin with. I.e., standard markdown list semantics don't change regardless of whether you add 2 trailing spaces. Here:

  • item 1
  • item 2
  • item 3

In the source of this question there are 2 trailing spaces after "item 1", and yet if you look at the HTML, there is no superfluous <br>

This leads me to think the best regex for converting newlines to <br>s is just:

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

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扎心 2024-10-10 02:42:17

我不确定这是否有帮助,但我只是使用 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!方法可能会帮助您编写自己的所需 Markdown 版本。

I'm not sure if this will help, but I just use simple_format()
from 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>"

Even if it doesn't meet your specs, looking at the simple_format() source code .gsub! methods might help you out writing your own version of required markdown.

友谊不毕业 2024-10-10 02:42:17

有点太晚了,但也许对其他人有用。我已经通过使用正则表达式预处理文本来使其工作(但未经过彻底测试),如下所示。由于缺乏零宽度回顾,这很可怕,但是哦,好吧。

# 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

A little too late, but perhaps useful for other people. I've gotten it to work (but not thoroughly tested) by preprocessing the text using regular expressions, like so. It's hideous as a result of the lack of zero-width lookbehinds, but oh well.

# 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文