pricing official inspinia_admin inspinia iconos full buttons ruby-on-rails ruby markdown

ruby on rails - official - Truncate Markdown?



inspinia v5 (7)

Tengo un sitio de Rails, donde el contenido está escrito en rebajas. Deseo mostrar un fragmento de cada uno, con un enlace "Leer más ...".

¿Cómo hago esto? El truncado simple del texto sin formato no funcionará, por ejemplo ...

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

Idealmente, quiero permitir que el autor (opcionalmente) inserte un marcador para especificar qué usar como "fragmento", si no, tomaría 250 palabras y anexaría "...", por ejemplo ...

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

El marcador podría considerarse como un marcador EOF (que puede ignorarse al mostrar el documento completo)

Estoy usando maruku para el procesamiento de reducción (RedCloth es muy parcial hacia Textile, BlueCloth es extremadamente defectuoso, y yo quería un analizador nativo de Ruby que descartaba el peg-markdown y RDiscount)

Alternativamente (dado que Markdown se traduce a HTML de todos modos) truncar el HTML correctamente sería una opción, aunque sería preferible no markdown() todo el documento, solo para obtener las primeras líneas.

Entonces, las opciones que puedo pensar son (en orden de preferencia) ...

  • Agregue una opción "truncar" al analizador de maruku, que solo analizará las primeras x palabras, o hasta el marcador "fragmento".
  • Escribir / encontrar un analizador sintáctico de trásicos Truncate''r
  • Escribir / encontrar una función de truncado HTML inteligente

  • Escribir / encontrar una función de truncado HTML inteligente

Lo siguiente de http://mikeburnscoder.wordpress.com/2006/11/11/truncating-html-in-ruby/ , con algunas modificaciones, truncará correctamente HTML y permitirá agregar fácilmente una cadena antes de las etiquetas de cierre.

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

El código modificado:

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


Aquí hay una solución que funciona para mí con Textile.

  1. Convertirlo a HTML
  2. Truncarlo.
  3. Elimine las etiquetas HTML que se cortaron por la mitad con

    html_string.gsub(/<[^>]*$/, "")

  4. Luego, usa Hpricot para limpiarlo y cerrar las etiquetas sin cerrar

    html_string = Hpricot( html_string ).to_s

Hago esto en una ayuda, y con el almacenamiento en caché no hay problema de rendimiento.


En lugar de intentar truncar el texto, ¿por qué no tener 2 cuadros de entrada, uno para el "anuncio de apertura" y otro para las "agallas" principales? De esa forma, sus autores sabrán exactamente qué se muestra cuando no tengan que depender de algún tipo de marcador EOF funky.


Puede usar una expresión regular para encontrar una línea que consta de nada más que "^" caracteres:

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


Tendré que estar de acuerdo con el enfoque de "dos entradas", y el escritor de contenido no tendrá que preocuparse, ya que puede modificar la lógica de fondo para mezclar las dos entradas en una al mostrar todo el contenido.

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


No estoy seguro de si se aplica a este caso, pero agregando la solución a continuación para completar. Puede usar el método strip_tags si está truncando los contenidos renderizados de Markdown:

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

Procedencia de: http://devblog.boonecommunitynetwork.com/rails-and-markdown/


Una opción más simple que simplemente funciona:

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