Truncar de rebajas?
-
29-08-2019 - |
Pregunta
Tengo un sitio rieles, donde el contenido está escrito en la reducción del precio. Deseo mostrar un fragmento de cada uno, con un "Leer más .." enlace.
¿Cómo hago para esto? Sencillo truncar el texto sin formato no funcionará, por ejemplo ..
>> "This is an [example](http://example.com)"[0..25]
=> "This is an [example](http:"
Lo ideal es que quieren permitir al autor (opcionalmente) insertar un marcador para especificar qué usar como el "recorte", y si no se necesitarían 250 palabras, y añadir "..." - 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 ser considerado como un marcador EOF (que puede ser ignorado cuando se muestra el documento completo)
Estoy utilizando Maruku para el procesamiento de rebajas (RedCloth está muy sesgada hacia Textil, BlueCloth es extremadamente errores, y quería un analizador nativo-Rubí, que descartó PEG-rebajas y RDiscount)
Como alternativa (ya que el de rebajas se traduce a HTML de todos modos) truncando el HTML correctamente sería una opción -. Aunque sería preferible no markdown()
todo el documento, sólo para obtener las primeras líneas
Por lo tanto, las opciones que se me ocurren son (en orden de preferencia) ..
- añadir un "truncar" opción para el analizador Maruku, que sólo va a analizar los primeros x palabras, o hasta que el marcador "fragmento".
- escritura / encontrar un analizador de rebajas agnóstica truncate'r
- escritura / encontrar un archivo HTML función truncar inteligente
Solución
- escritura / encontrar un archivo HTML función truncar inteligente
La siguiente desde http: //mikeburnscoder.wordpress. com / 2006/11/11 / truncar-html-en-rubí / , con algunas modificaciones truncará correctamente HTML y permitir fácilmente añadiendo 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
Otros consejos
Esta es una solución que funciona para mí con Textil.
- Convertir a HTML
- truncar la misma.
-
Elimina las etiquetas HTML que se cortó por la mitad con
html_string.gsub(/<[^>]*$/, "")
-
A continuación, utiliza hpricot para limpiarlo y cerrar las etiquetas sin cerrar
html_string = Hpricot( html_string ).to_s
Lo hago en un ayudante, y con el almacenamiento en caché no hay ningún problema de rendimiento.
Se puede usar una expresión regular para encontrar una línea que consiste en 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
En lugar de intentar truncar el texto, ¿por qué no tener 2 cajas de entrada, uno para la "propaganda de apertura" y uno de los principales "tripas". De esa manera sus autores sabrán exactamente lo que se está espectáculo cuando, sin tener que depender de algún tipo de marcador funkly EOF.
voy a tener que estar de acuerdo con el enfoque de "dos entradas", y el escritor de contenido tendría que no hay que preocuparse, ya que se puede modificar la lógica de fondo para mezclar las dos entradas en una hora de mostrar el contenido completo.
full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
No está seguro de si se aplica a este caso, pero la adición de la solución a continuación en aras de la exhaustividad. Puede utilizar strip_tags método si está truncando contenidos de rebajas-renderizados:
truncate(strip_tags(markdown(article.contents)), length: 50)
obtienen de: http://devblog.boonecommunitynetwork.com/rails-and-markdown/
Una opción más sencilla que simplemente funciona:
truncate(markdown(item.description), length: 100, escape: false)