7

在我的 rails3 应用程序中,我想使用 redcarpet 来处理用户的帖子和用户评论部分。因此,我想扩展 redcarpet 以支持将 @username 转换为指向我网站上用户的链接。我知道 redcarpet 是用 C 编写的,但是有没有简单的方法可以在 ruby​​ 中扩展它?用C编写它有多难?我应该在红地毯之外做这件事吗?

此外,我对 redcarpet 的其他一些扩展很感兴趣,这些扩展将是链接到我的应用程序中其他模型的简写。我还不确定语法,但我猜它类似于 github 处理链接到问题的方式。

4

2 回答 2

23

我发现在 Ruby 中为我的 rails 3 应用程序扩展 redcarpet 的解析器非常容易。这一点也不可怕。

首先,首先从 Redcarpet 的 HTML 渲染器派生一个类,并按照文档中的建议覆盖预处理方法。在 Rails 3.2 和 Rails 4 中,这个文件可以放在任何地方,你不需要它。我使用“服务”文件夹来保存这样的代码。

# app/services/my_flavored_markdown.rb
class MyFlavoredMarkdown < Redcarpet::Render::HTML
  def preprocess(text)
    text
  end
end

下一步是添加进行所需文本替换的方法。在这里,我使用正则表达式将看起来像“@mention”的文本包装在带有 CSS 类“提及”的 HTML 跨度标记中。

# app/services/my_flavored_markdown.rb
class MyFlavoredMarkdown < Redcarpet::Render::HTML

  def preprocess(text)
    wrap_mentions(text)
  end

  def wrap_mentions(text)
    text.gsub! /(^|\s)(@\w+)/ do
      "#{$1}<span class='mention'>#{$2}</span>"
    end
    text
  end

end

您可以轻松地查找用户的个人资料页面并将@mention 包装在锚标记中。就我而言,我还为表情符号和主题标签创建了以相同方式工作的方法,并将这些方法链接在一起。

最后一步是添加一个接受一些文本的帮助程序,创建 Redcarpet 派生类的实例,将文本传递给该类进行处理,然后返回 html 结果。

# app/helpers/application_helper.rb
def flavored_markdown_to_html(text)
  renderer = MyFlavoredMarkdown.new()
  # These options might be helpful but are not required
  options = {
    safe_links_only: true,
    no_intra_emphasis: true,
    autolink: true
  }
  Redcarpet::Markdown.new(renderer, options).render(text)
}

在您看来,您可以这样称呼它:

<%= flavored_markdown_to_html("This is something worth @mentioning") %>

输出将是:

This is something worth <span class='mention'>@mentioning</span>.

于 2013-05-10T01:25:13.503 回答
1

我曾经尝试过扩展redcarpet,但发现它非常困难。如果没有其他依赖项,redcarpet我建议您尝试rpeg-markdown使用(有点过时的)Ruby gem,提供与优秀peg-markdown的绑定。

peg-markdown是一个以形式语法编写的降价解释器。这意味着很容易用自己的语法扩展它。我已经成功地peg-markdown为我自己的项目进行了扩展(请参阅我的 fork 此处),我发现它比摆弄's 的自定义解析器代码要简单得多。redcarpet

我还发现peg-markdown错误更少。

Ruby 绑定可能必须通过更新 git 子模块来更新。(我打算提交一个拉取请求以更新rpeg-markdown到最新版本peg-markdown。)

于 2012-12-05T09:12:59.723 回答