Truncate Markdown?

j'ai un site de Rails, où le contenu est écrit en markdown. Je souhaite afficher un extrait de chacune, avec un "Lire la suite.." lien.

Comment puis-je aller à ce sujet? Simple tronquer 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 (éventuellement) insérer un marqueur de préciser ce qu'il faut utiliser le "snippet", si non il faudrait 250 mots, et append "..."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

on pourrait penser au marqueur comme un marqueur EOF (qui peut être ignoré lors de l'affichage du document complet)

j'utilise maruku pour les Démarques de traitement (RedCloth est très biaisé en faveur de Textile, BlueCloth est extrêmement buggé, et je voulais un natif Ruby analyseur qui exclu peg-markdown et RDiscount)

alternativement (puisque le Markdown est traduit en HTML de toute façon) tronquer le HTML correctement serait une option-bien qu'il serait préférable de ne pas markdown() l'ensemble de la le document, juste pour obtenir les premières lignes.

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

  • ajouter une option "tronquer" à l'analyseur maruku, qui n'analysera que les premiers mots x, ou jusqu'au marqueur "extrait".
  • Ecrire/trouver un analyseur-agnostique Markdown tronquer r
  • Ecrire/trouver un intelligent HTML tronquer la fonction
10
demandé sur dbr 2008-12-28 06:47:06

7 réponses

  • Ecrire/trouver un intelligent HTML tronquer la fonction

The following from http://mikeburnscoder.wordpress.com/2006/11/11/truncating-html-in-ruby/, avec quelques modifications va correctement tronquer HTML, et permettre facilement l'ajout d'une chaîne de caractères avant 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
6
répondu dbr 2008-12-28 04:21:46

Voici une solution qui fonctionne pour moi avec le Textile.

  1. Convertir en HTML
  2. la tronquer.
  3. supprimez toutes les balises HTML qui ont été coupées en deux avec

    html_string.gsub(/<[^>]*$/, "")
    
  4. puis, utilise Hpricot pour nettoyer et fermer les étiquettes non fermées

    html_string = Hpricot( html_string ).to_s 
    

je le fais dans un helper, et avec la mise en cache il n'y a pas de problème de performance.

2
répondu nicholaides 2008-12-28 04:37:00

Vous pouvez utiliser une expression régulière pour trouver une ligne constituée de rien, mais "^" 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
1
répondu csexton 2008-12-28 04:27:14

Plutôt que d'essayer de tronquer le texte, pourquoi ne pas avoir 2 zones de saisie, l'un pour le "argumentaire d'ouverture" et l'un des principaux "tripes". De cette façon, vos auteurs sauront exactement ce qui est affiché sans avoir à se fier à une sorte de marqueur funkly EOF.

1
répondu diclophis 2008-12-28 04:45:04

je devrai être d'accord avec l'approche" deux entrées", et l'auteur de contenu n'aura pas besoin de s'inquiéter, puisque vous pouvez modifier la logique de fond pour mélanger les deux entrées en une lors de la présentation du contenu complet.

full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
0
répondu Elland 2010-08-15 20:39:13

Je ne suis pas sûr que cela s'applique à ce cas, mais en ajoutant la solution ci-dessous par souci d'exhaustivité. Vous pouvez utiliser la méthode strip_tags si vous tronquez les contenus rendus Markdown:

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

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

0
répondu wondersz1 2015-10-01 17:27:11

Une option plus simple qui fonctionne bien:

truncate(markdown(item.description), length: 100, escape: false)
0
répondu ChrisEstanol 2016-01-22 01:43:52