让文章编辑支持Markdown
现在很多写作者已经离不开 markdown 了,因此很多发文章的编辑器都需要支持。
如果要在 rails 的 webapp 里实现 markdown 支持,大概思路是,用户写文章的时候,用 markdown 格式输入,比如
# h1
## h2
some stuff
...
在文章显示的时候,将这些 markdown 格式解析成 HTML 格式来显示。这个解析的功能,一般可以用 redcarpet 这个gem。
添加 gemfile
gem 'redcarpet'
创建 renderer 类及方法
一般可以放在 /lib
目录下,比如创建一个 markdown_render.rb
class MarkdownRenderer < Redcarpet::Render::HTML
def self.render(text)
options = {
filter_html: false,
hard_wrap: true,
link_attributes: { rel: 'nofollow', target: '_blank' },
space_after_headers: true,
fenced_code_blocks: true,
with_toc_data: true
# 各项设置见 gem 说明
}
extensions = {
autolink: true,
superscript: true,
disable_indented_code_blocks: true
# 各项设置见 gem 说明
}
renderer = new(options)
markdown = Redcarpet::Markdown.new(renderer, extensions)
markdown.render(text)
end
end
创建 helper 方法
为了使用方便,还可以在 application_helper.rb
里创建解析文本的 helper
def markdown_article(text)
tag.article class: 'markdown-article' do
MarkdownRenderer.render(text || '').html_safe
end
end
在 view 中使用 helper 时,比如说文章内容存在 @post.content
,那么
<% markdown_article(@post.content) %>
根据前面写的 helper,文章的内容会包在一个 <article>
的 tag 里,带有一个 markdown-article
的 class。这样就方便我们对文章的样式进行调整。
<article class="markdown-article">
// 解析成 HTML 后的文章内容
</article>
生成文章目录
在 redcarpet 的说明中有介绍,还可以用来生成文章的目录,用的是 Redcarpet::Render::HTML_TOC
这个类。
使用方法类似,先创建一个 render 的类,同样可以放在 /lib
目录下
class MarkdownTocRenderer < Redcarpet::Render::HTML_TOC
def self.render(text)
options = {}
extensions = { with_toc_data: true }
renderer = new(options)
markdown = Redcarpet::Markdown.new(renderer, extensions)
markdown.render(text)
end
end
在 application_helper.rb
里定义个 helper
def markdown_toc(text)
tag.div class: 'markdown-toc' do
MarkdownTocRenderer.render(text || '').html_safe
end
end
解析后的效果是
<div class="markdown-toc">
<ul>
<li>
<a href="#h1-id">h1-xxxx</a>
</li>
<li>
<a href="#h2-id">h2-xxxx</a>
</li>
// ...
</ul>
</div>
生成出来的效果很难看,重新添加一些 style 就可以了。
这里有一个需要注意的地方,生成出来的目录里带的超链接,要定位到各个标题位置,其实就是链接到本页的一个 id
,那么文章中必须带有相应的标签才行。所以在解析文章内容时一定要带上 with_toc_data: true
这个参数设置。