Усечь уценку? - PullRequest
       27

Усечь уценку?

10 голосов
/ 28 декабря 2008

У меня есть сайт Rails, где контент написан на уценке. Я хочу отобразить фрагмент каждого из них со ссылкой "Подробнее ...".

Как мне это сделать? Простое усечение необработанного текста не будет работать, например ..

>> "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, который будет анализировать только первые x слов или до маркера «отрывка».
  • Записать / найти не зависящий от синтаксического анализатора Markdown truncate'r
  • Запись / поиск интеллектуальной функции усечения HTML

Ответы [ 7 ]

6 голосов
/ 28 декабря 2008
  • Запись / поиск интеллектуальной функции усечения 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 голосов
/ 28 декабря 2008

Вот решение, которое работает для меня с текстилем.

  1. Конвертировать в HTML
  2. Обрезать его.
  3. Удалите все HTML-теги, которые были разрезаны пополам с помощью

    html_string.gsub(/<[^>]*$/, "")
    
  4. Затем использует Hpricot для очистки и закрытия незакрытых тегов

    html_string = Hpricot( html_string ).to_s 
    

Я делаю это помощником, и с кэшированием нет проблем с производительностью.

1 голос
/ 28 декабря 2008

Вместо того, чтобы пытаться обрезать текст, почему бы не иметь 2 поля ввода, одно для «раскрывающегося всплывающего окна» и одно для основных «кишок». Таким образом, ваши авторы будут точно знать, что показывается, без необходимости полагаться на какой-то забавный маркер EOF.

1 голос
/ 28 декабря 2008

Вы можете использовать регулярное выражение, чтобы найти строку, состоящую только из символов «^»:

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
0 голосов
/ 22 января 2016

Более простой вариант, который просто работает:

truncate(markdown(item.description), length: 100, escape: false)
0 голосов
/ 07 сентября 2015

Не уверен, относится ли это к этому случаю, но добавим приведенное ниже решение для полноты картины. Вы можете использовать метод strip_tags, если вы усекаете отображаемое в Markdown содержимое:

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

Источник: http://devblog.boonecommunitynetwork.com/rails-and-markdown/

0 голосов
/ 16 августа 2010

Мне придется согласиться с подходом «двух входов», и создателю контента не нужно будет беспокоиться, поскольку вы можете изменить фоновую логику, смешивая два входа в один при отображении полного контента.

full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...