Question

J'ai un site Rails où le contenu est écrit en Markdown. Je souhaite afficher un extrait de chacun, avec un lien « En savoir plus .. ».

Comment puis-je cela? Simple tronquant le texte brut ne fonctionnera pas, par exemple ..

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

Idéalement je veux permettre à l'auteur (le cas échéant) insérer un marqueur pour indiquer ce à utiliser comme « extrait », sinon il faudrait 250 mots, et d'ajouter « ... » - par exemple ..

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

Le marqueur peut être considéré comme un marqueur EOF (qui peut être ignoré lors de l'affichage du document)

J'utilise Maruku pour le traitement de Markdown (RedCloth est très biaisé en faveur du textile, BlueCloth est extrêmement bogué, et je voulais un analyseur-Ruby natif qui exclut peg-démarquage et RDiscount)

Vous pouvez également (depuis le Markdown est traduit en HTML de toute façon) tronquer correctement le HTML serait une option -. Bien qu'il serait préférable de ne pas markdown() le document entier, juste pour obtenir les premières lignes

Alors, les options que je peux penser sont (par ordre de préférence) ..

  • Ajouter une option « tronquer » à l'analyseur de Maruku, qui n'analyser les premiers mots de x, ou jusqu'à ce que le marqueur « extrait ».
  • Ecrire / trouver un analyseur agnostique Markdown truncate'r
  • Ecrire / trouver une fonction tronquer HTML intelligente
Était-ce utile?

La solution

  
      
  • Ecrire / trouver une fonction tronquer HTML intelligente
  •   

Ce qui suit de http: //mikeburnscoder.wordpress. com / 2006/11/11 / html tronquer-en-ruby / , avec quelques modifications seront correctement tronquer HTML, et permettent facilement annexant une chaîne avant que les balises de fermeture.

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

Le code modifié:

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

Autres conseils

Voici une solution qui fonctionne pour moi avec textile.

  1. Convertir en HTML
  2. tronquer.
  3. Supprimer toutes les balises HTML qui a été coupé en deux avec

    html_string.gsub(/<[^>]*$/, "")
    
  4. Ensuite, utilise hpricot pour le nettoyer et à proximité des balises non fermées

    html_string = Hpricot( html_string ).to_s 
    

Je le fais dans une aide, et avec la mise en cache, il n'y a pas de problème de performance.

Vous pouvez utiliser une expression régulière pour trouver une ligne composée de rien « ^ » caractères:

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

Plutôt que d'essayer de tronquer le texte, pourquoi ne pas avoir 2 boîtes d'entrée, un pour l ' « ouverture texte de présentation » et un pour les principaux « tripes ». De cette façon, vos auteurs savent exactement ce qui est spectacle quand sans avoir à compter sur une sorte de marqueur funkly EOF.

Je suis d'accord avec l'approche « deux entrées », et l'auteur de contenu, il conviendrait de ne pas inquiéter, puisque vous pouvez modifier la logique de fond pour mélanger les deux entrées dans un en montrant le contenu complet.

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

Je ne sais pas si elle applique à ce cas, mais en ajoutant la solution ci-dessous pour un souci d'exhaustivité. Vous pouvez utiliser strip_tags méthode si vous tronquer le contenu rendu Markdown-:

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

Provenant: http://devblog.boonecommunitynetwork.com/rails-and-markdown/

Une option plus simple qui fonctionne:

truncate(markdown(item.description), length: 100, escape: false)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top