代码之家  ›  专栏  ›  技术社区  ›  dbr

截断降价?

  •  10
  • dbr  · 技术社区  · 16 年前

    我有一个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 对于降价处理(RedCloth非常偏向于纺织业,BlueCound非常麻烦,我想要一个本地Ruby解析器,它排除了Peg Markdown和RDisCount)

    或者(因为标记被翻译成HTML),正确地截断HTML是一个选项——尽管最好不要这样做。 markdown() 整个文档,只是为了得到前几行。

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

    • 向maruku解析器添加一个“truncate”选项,它只解析前x个单词,或者直到“excerpt”标记。
    • 编写/查找不可知的分析器标记截断'r
    • 编写/查找智能HTML截断函数
    7 回复  |  直到 9 年前
        1
  •  6
  •   dbr    16 年前
    • 编写/查找智能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
    
        2
  •  2
  •   nicholaides    16 年前

    这是一个适合我使用纺织品的解决方案。

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

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

      html_string = Hpricot( html_string ).to_s 
      

    我在一个助手中完成这项工作,并且在缓存中没有性能问题。

        3
  •  1
  •   dbr    16 年前

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

    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
    
        4
  •  1
  •   diclophis    16 年前

    与其试图截短文本,不如有两个输入框,一个用于“打开Blurb”,另一个用于“Guts”。这样,你的作者就可以准确地知道在不依赖某种有趣的EOF标记的情况下所展示的内容。

        5
  •  0
  •   Elland    14 年前

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

    full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
    
        6
  •  0
  •   wondersz1    9 年前

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

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

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

        7
  •  0
  •   user3335966 David Jenkins    9 年前

    一个简单的选择就是:

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