3 votes

Redcarpet/Bluecloth n'autorise pas les en-têtes ?

Existe-t-il un moyen d'utiliser Redcarpet ou Bluecloth de telle sorte que lorsqu'ils interpolent le markdown, ils ne créent pas d'en-têtes ?

Par exemple :

#header 1

rendements :

en-tête 1

en-tête 1 (de préférence)

Et :

##header 2

rendements :

en-tête 2

en-tête 2 (de préférence)

5voto

Jordan Points 26741

Eh bien, vous pouvez échapper les caractères dans Markdown :

# header 1
\# header 1

## header 2
\## header 2

...donne :

en-tête 1

# En-tête 1

en-tête 2

## en-tête 2

Si vous ne voulez pas avoir à le faire, ou si vous analysez le Markdown d'autres personnes et que vous n'avez pas le choix, je vous recommande de prétraiter le Markdown entrant pour qu'il le fasse à votre place :

def pound_filter text
  text.gsub /^#/, '\#'
end

En utilisant Redcarpet, vous pouvez vérifier que cela fonctionne :

text = <<-END
  # Hello
  ## World
END

Markdown.new(text.to_html)
# =>  <h1>Hello</h1>
#
#     <h2>World</h2>

Markdown.new(pound_filter text).to_html
# =>  <p># Hello
#     ## World</p>

Bien sûr, comme un saut de ligne en HTML n'est pas réellement rendu comme tel, il apparaîtra comme une seule ligne :

# Hello ## World"

...vous pourriez vouloir augmenter ça :

def pound_filter text
  text.gsub( /((\A^)|([^\A]^))#/ ) {|match| "\n" == match[0] ? "\n\n\\#" : '\#' }
end

pound_filter text
# =>  \# Hello
#
#     \## World

Markdown.new(pound_filter text).to_html
# =>  <p>\# Hello</p>
#
#     <p>\## World</p>

Ce dernier apparaîtrait comme :

# Hello

## Monde

Malheureusement, on finit par se retrouver dans des situations bizarres comme celle-ci, où un titre se trouve à l'intérieur d'une citation :

> ## Heading

...mais je laisse cela comme un exercice au lecteur.

3voto

Cruz Nunez Points 1188

J'ai vu une solution similaire ici qui se passait comme ça :

class RenderWithoutWrap < Redcarpet::Render::HTML
  def postprocess(full_document)
    Regexp.new(/\A<p>(.*)<\/p>\Z/m).match(full_document)[1] rescue full_document
  end
end

Il supprime tous les <p> & </p> tags. Je l'ai utilisé comme ça et ça a marché. J'ai placé cette classe dans un nouveau fichier appelé /config/initializers/render_without_wrap.rb . Vous pourriez faire quelque chose de similaire pour tous les <h1> - <h6> tags

class RenderWithoutHeaders < Redcarpet::Render::HTML
  def postprocess(full_document)
    Regexp.new(/\A<h1>(.*)<\/h1>\Z/m).match(full_document)[1] rescue full_document
    Regexp.new(/\A<h2>(.*)<\/h2>\Z/m).match(full_document)[1] rescue full_document
    Regexp.new(/\A<h3>(.*)<\/h3>\Z/m).match(full_document)[1] rescue full_document
    ...(you get the idea)
  end
end

Vous pourriez alors l'utiliser comme suit

def custom_markdown_parse(text)
  markdown = Redcarpet::Markdown.new(RenderWithoutHeaders.new(
    filter_html: true,
    hard_wrap: true,
    other_options: its_your_call
  ))
  markdown.render(text).html_safe
end

Je ne l'ai pas testé, mais c'est une idée.

1voto

Andrew Vit Points 10630

1. Vous devriez être en mesure d'échapper à votre texte source markdown avec des antislashes :

\# not a header

2. Vous pouvez aussi faire du "monkey-patch" :

module RedCloth::Formatters::HTML

  [:h1, :h2, :h3, :h4, :h5, :h6].each do |m|
    define_method(m) do |opts|
      "#{opts[:text]}\n"
    end
  end

end

0voto

Kevin Reid Points 8806

Étant donné qu'il est difficile de modifier le pré-parsage de Markdown et que Markdown permet l'insertion de HTML, pourquoi ne pas supprimer les éléments de titre du HTML résultant ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X