Tronca Markdown?
-
29-08-2019 - |
Domanda
Ho un sito Rails, in cui il contenuto è scritto in Markdown. Desidero visualizzare un frammento di ciascuno, con un "Continua .." collegamento.
Come posso fare questo? Semplice troncando il testo grezzo non funziona, per esempio ..
>> "This is an [example](http://example.com)"[0..25]
=> "This is an [example](http:"
Idealmente voglio permettere all'autore di (opzionale) inserire un marcatore per specificare cosa utilizzare come "frammento", se non ci vorrebbe 250 parole, e aggiungere "..." - per esempio ..
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
Il marcatore potrebbe essere pensato come un indicatore EOF (che può essere ignorato quando si visualizza il documento completo)
maruku per la lavorazione Markdown (RedCloth è molto sbilanciata verso tessile, BlueCloth è estremamente buggy, e volevo un nativo-rubino parser, che ha escluso peg-markdown e RDiscount)
In alternativa (dal momento che il Markdown è tradotto in HTML in ogni caso) troncando il codice HTML in modo corretto sarebbe un'opzione -. Anche se sarebbe preferibile non markdown()
l'intero documento, solo per ottenere le prime righe
Quindi, le opzioni che ho in mente sono (in ordine di preferenza) ..
- Aggiungi un "troncare" per il parser maruku, che analizzare solo le prime x parole, o fino al marcatore "estratto".
- Scrivi / trovare un Markdown parser-agnostic truncate'r
- Scrivi / trovare una funzione di troncare HTML intelligenti
Soluzione
- Scrivi / trovare una funzione di troncare HTML intelligente
Il seguente da http: //mikeburnscoder.wordpress. com / 2006/11/11 / troncando-html-in-ruby / , con alcune modifiche saranno correttamente troncherà HTML, e facilmente consentire aggiungendo una stringa prima che i tag di chiusura.
>> puts "<p><b><a href=\"hi\">Something</a></p>".truncate_html(5, at_end = "...")
=> <p><b><a href="hi">Someth...</a></b></p>
Il codice modificato:
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
Altri suggerimenti
Ecco una soluzione che funziona per me in tessuto.
- Converti in HTML
- Tronca esso.
-
Rimuovi tutti i tag HTML che ha tagliato a metà con
html_string.gsub(/<[^>]*$/, "")
-
Poi, usa Hpricot per ripulirlo e chiudere i tag non chiusi
html_string = Hpricot( html_string ).to_s
Lo faccio in un aiutante, e con il caching non c'è nessun problema di prestazioni.
Si potrebbe usare un'espressione regolare per trovare una linea composta da nulla, ma "^" caratteri:
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
Invece di cercare di troncare il testo, perché non avere 2 caselle di input, uno per il "Blurb apertura" e uno per i principali "coraggio". In questo modo i vostri autori sapranno esattamente ciò che viene spettacolo quando, senza dover fare affidamento su una sorta di marcatore funkly EOF.
Io sono d'accordo con l'approccio "due ingressi", e lo scrittore contenuti avrei bisogno di non preoccuparsi, dato che è possibile modificare la logica di fondo di mescolare i due ingressi in un solo quando mostra l'intero contenuto.
full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
Non sono sicuro se si applica a questo caso, ma aggiungendo la soluzione qui di seguito per ragioni di completezza. È possibile utilizzare strip_tags metodo se si troncare contenuto Markdown-rendered:
truncate(strip_tags(markdown(article.contents)), length: 50)
Provenienti da: http://devblog.boonecommunitynetwork.com/rails-and-markdown/
Una soluzione semplice che funziona:
truncate(markdown(item.description), length: 100, escape: false)