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
È stato utile?

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.

  1. Converti in HTML
  2. Tronca esso.
  3. Rimuovi tutti i tag HTML che ha tagliato a metà con

    html_string.gsub(/<[^>]*$/, "")
    
  4. 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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top