10

我有一个 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 非常有问题,我想要一个排除 peg-markdown 和 RDiscount 的原生 Ruby 解析器)

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

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

  • 向 maruku 解析器添加一个“截断”选项,它只会解析前 x 个单词,或者直到“摘录”标记。
  • 编写/查找与解析器无关的 Markdown truncate'r
  • 编写/查找智能 HTML 截断函数
4

7 回答 7

6
  • 编写/查找智能 HTML 截断函数

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

>> puts "<p><b><a href=\"hi\">Something</a></p>".truncate_html(5, at_end = "...")
=> <p><b><a href="hi">Someth...</a></b></p>

修改后的代码:

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 = ''
    while 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 << "</#{tags.pop}>"
      when :text
        results << p_e[0][0..new_len]
        new_len -= p_e[0].length
      else
        results << "<!-- #{p_e.inspect} -->"
      end
    end
    if at_end
      results << "..."
    end
    tags.reverse.each do |tag|
      results << "</#{tag}>"
    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
于 2008-12-28T04:21:46.497 回答
2

这是一个适用于我的 Textile 解决方案。

  1. 将其转换为 HTML
  2. 截断它。
  3. 删除任何被切成两半的 HTML 标签

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

    html_string = Hpricot( html_string ).to_s 
    

我在助手中执行此操作,并且使用缓存没有性能问题。

于 2008-12-28T04:37:00.520 回答
1

您可以使用正则表达式来查找只包含“^”字符的行:

markdown_string = <<-eos
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
eos

preview = markdown_string[0...(markdown_string =~ /^\^+$/)]
puts preview
于 2008-12-28T04:10:20.887 回答
1

与其尝试截断文本,不如使用 2 个输入框,一个用于“开场白”,一个用于主要“胆量”。这样,您的作者将无需依赖某种时髦的 EOF 标记就可以准确地知道正在显示什么。

于 2008-12-28T04:45:04.170 回答
0

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

full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
于 2010-08-15T20:39:13.477 回答
0

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

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

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

于 2015-09-07T10:26:04.917 回答
0

一个更简单的选择:

truncate(markdown(item.description), length: 100, escape: false)
于 2016-01-22T00:50:00.070 回答