截断Markdown?

我有一个Rails站点,其中的内容是用markdown编写的。 我希望显示每个片段,并带有“阅读更多…”链接。

我该怎么做? 简单地截断原始文本将不起作用,例如..

>> "This is an [example](http://example.com)"[0..25] => "This is an [example](http:" 

理想情况下,我希望允许作者(可选)插入标记以指定要用作“片段”的内容,如果不是,则需要250个单词,并附加“…” – 例如..

 This article is an example of something or other. This segment will be used as the snippet on the index page. ^^^^^^^^^^^^^^^ This text will be visible once clicking the "Read more.." link 

标记可以被认为是EOF标记(在显示完整文档时可以忽略)

我正在使用maruku进行Markdown处理(RedCloth非常偏向于Textile,BlueCloth是非常错误的,我想要一个本地Ruby解析器,它排除了peg-markdown和RDiscount)

或者(因为无论如何将Markdown翻译成HTML)正确地截断HTML是一种选择 – 尽管最好不要markdown()整个文档,只是为了获得前几行。

所以,我能想到的选项是(按照优先顺序)..

  • 向maruku解析器添加“truncate”选项,该解析器仅解析前x个单词,或者直到“摘录”标记。
  • 编写/找到解析器无关的Markdown truncate’r
  • 编写/查找智能HTML截断function

  • 编写/查找智能HTML截断function

以下来自http://mikeburnscoder.wordpress.com/2006/11/11/truncating-html-in-ruby/ ,经过一些修改将正确截断HTML,并且可以轻松地在结束标记之前附加字符串。

 >> puts "

Somethttps://stackoverflow.com/questions/395783/truncate-markdown/hing

".truncate_html(5, at_end = "...") =>

Someth...

修改后的代码:

 require 'rexml/parsers/pullparser' class String def truncate_html(len = 30, at_end = nil) p = REXML::Parsers::PullParser.new(self) tags = [] new_len = len results = '' whttps://stackoverflow.com/questions/395783/truncate-markdown/hile p.has_next? && new_len > 0 p_e = p.pull case p_e.event_type when :start_element tags.push p_e[0] results << "<#{tags.last}#{attrs_to_s(p_e[1])}>" when :end_element results << "" when :text results << p_e[0][0..new_len] new_len -= p_e[0].length else results << "" end end if at_end results << "..." end tags.reverse.each do |tag| results << "" end results end private def attrs_to_s(attrs) if attrs.empty? '' else ' ' + attrs.to_a.map { |attr| %{#{attr[0]}="#{attr[1]}"} }.join(' ') end end end 

这是一个适用于纺织品的解决方案。

  1. 将其转换为HTML
  2. 截断它。
  3. 删除所有切成两半的HTML标记

     html_string.gsub(/<[^>]*$/, "") 
  4. 然后,使用Hpricot清理它并关闭未关闭的标签

     html_string = Hpricot( html_string ).to_s 

我在帮助器中执行此操作,并且通过缓存,没有性能问题。

您可以使用正则表达式查找由“^”字符组成的行:

 markdown_string = <<-eos Thttps://stackoverflow.com/questions/395783/truncate-markdown/his article is an example of somethttps://stackoverflow.com/questions/395783/truncate-markdown/hing or other. Thttps://stackoverflow.com/questions/395783/truncate-markdown/his segment will be used as the snippet on the index page. ^^^^^^^^^^^^^^^ Thttps://stackoverflow.com/questions/395783/truncate-markdown/his text will be visible once clicking the "Read more.." link eos preview = markdown_string[0...(markdown_string =~ /^\^+$/)] puts preview 

而不是试图截断文本,为什么没有2个输入框,一个用于“打开模糊”,一个用于主要“胆量”。 通过这种方式,您的作者无需依赖某种有趣的EOF标记即可准确了解所显示的内容。

我将不得不同意“两个输入”方法,内容编写者不必担心,因为您可以修改后台逻辑,在显示完整内容时将两个输入混合在一起。

 full_content = input1 + input2 // perhaps with some complementary html, for a better formatting 

不确定它是否适用于这种情况,但为了完整起见,添加下面的解决方案。 如果要截断Markdown渲染的内容,可以使用strip_tags方法:

 truncate(strip_tags(markdown(article.contents)), length: 50) 

来自: http : //devblog.boonecommunitynetwork.com/rails-and-markdown/

一个更简单的选项:

 truncate(markdown(item.description), length: 100, escape: false)