web-dev-qa-db-fra.com

Comment feriez-vous pour analyser Markdown?

Edit: J'ai récemment entendu parler d'un projet appelé CommonMark, qui identifie correctement et traite les ambiguïtés de la spécification Markdown d'origine. http://commonmark.org/ Il a un excellent support de bibliothèque C #.

Vous pouvez trouver la syntaxe ici .

La source qui suit avec le téléchargement est écrite en Perl , que je n'ai aucune intention d'honorer. Il est criblé d'expressions régulières, et il s'appuie sur des hachages MD5 pour échapper à certains caractères. Quelque chose ne va pas à ce sujet!

Je suis sur le point de coder en dur un analyseur pour Markdown . Quelle est l'expérience avec cela?

Si vous n'avez rien de significatif à dire sur l'analyse réelle de Markdown, épargnez-moi du temps. (Cela peut sembler dur, mais oui, je recherche des informations, pas une solution, c'est-à-dire une bibliothèque tierce).

Pour aider un peu avec les réponses, les expressions régulières sont destinées à identifier les modèles ! NE PAS analyser une grammaire entière. Que les gens envisagent de le faire est une folie.

  • Si vous pensez à Markdown, il est fondamentalement basé sur le concept de paragraphes.
  • En tant que tel, une approche raisonnable pourrait être de diviser l'entrée en paragraphes.
  • Il existe de nombreux types de paragraphes, par exemple, en-tête, texte, liste, blockquote et code.
  • Le défi est donc d'identifier ces paragraphes et dans quel contexte ils se produisent.

Je reviendrai avec une solution, une fois que je trouverai qu'elle mérite d'être partagée.

122
John Leidegren

La seule implémentation de démarque à ma connaissance, qui utilise un analyseur réel, est Jon MacFarleane s peg-markdown . Son analyseur est basé sur un générateur d'analyse syntaxique Parsing Expression Grammar appelé peg .


EDIT: Mauricio Fernandez a récemment publié son Simple Markup Markdown parser , qu'il a écrit dans le cadre de son OcsiBlog Weblog Engine. Parce que l'analyseur est écrit en OCaml , il est extrêmement simple et court (268 SLOC pour le analyseur , 43 SLOC pour émetteur HTML ), pourtant flamboyant rapide (20% plus rapide que remise (écrit en C optimisé à la main) et six cent fois plus rapide que BlueCloth (- Ruby )), malgré le fait qu'il n'est même pas encore optimisé pour les performances. Parce qu'il est uniquement destiné à un usage interne par Mauricio lui-même pour son blog, il y a quelques écarts par rapport à la spécification Markdown officielle , mais Mauricio a créé ne branche qui annule la plupart de ces changements .

64
Jörg W Mittag

J'ai publié un nouveau Markdown basé sur l'analyseur Java la semaine dernière, appelé pegdown . Pegdown utilise un analyseur PEG pour d'abord construire une arborescence de syntaxe abstraite, qui est ensuite écrite à HTML. En tant que tel, il est assez propre et beaucoup plus facile à lire, à entretenir et à étendre qu'une approche basée sur l'expression régulière. La grammaire PEG est basée sur l'implémentation de John MacFarlanes C "peg-markdown".

Peut-être quelque chose qui vous intéresse ...

17
Mathias

Si je devais essayer d'analyser le markdown (et son extension Markdown extra ) je pense que j'essaierais d'utiliser une machine à états et de l'analyser un caractère à la fois, en reliant ensemble certaines structures internes représentant des bits de texte au fur et à mesure, une fois que tout est analysé, générant la sortie des objets tous enfilés.

Fondamentalement, je construisais un arbre de type mini-DOM en lisant le fichier d'entrée.
Pour générer une sortie, je voudrais simplement parcourir l'arborescence et sortir du HTML ou autre chose (PS, LaTex, RTF, ...)

Choses qui peuvent augmenter la complexité:

  • Le fait que vous pouvez mélanger HTML et démarque, bien que la règle puisse être facile à implémenter: ignorez simplement tout ce qui se trouve entre deux balises équilibrées et affichez-le textuellement.

  • Les URL et les notes peuvent avoir leur référence au bas du texte. L'utilisation de structures de données pour les hyperliens pourrait simplement enregistrer quelque chose comme:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • Les en-têtes peuvent être définis avec un soulignement, ce qui pourrait nous obliger à utiliser une structure de données simple pour un paragraphe générique et à modifier ses propriétés lors de la lecture du fichier:

    ParagraphStructure:
    |  InnerText    : the current paragraph text 
    |                 (beginning of line until end of line).
    |  HeadingLevel : <null> or 1-4 when we can assess 
    |                 that paragraph heading level, if any.
    

Quoi qu'il en soit, juste quelques réflexions.

Je suis sûr qu'il y a beaucoup de petits détails à prendre en charge et je suis presque sûr que les regex pourraient devenir utiles pendant le processus.
Après tout, ils étaient censés traiter du texte.

6
Renaud Bompuis

J'aurais probablement lu la spécification de syntaxe suffisamment de fois pour la connaître et avoir une idée de la façon de l'analyser.

La lecture du code de l'analyseur existant est bien sûr géniale, à la fois pour voir ce qui semble être la principale source de complexité et pour savoir si des astuces spéciales sont utilisées. L'utilisation de la somme de contrôle MD5 semble un peu bizarre, mais je n'ai pas suffisamment étudié le code pour comprendre pourquoi il est fait. Un commentaire dans une routine appelée _EscapeSpecialChars() déclare:

Nous remplaçons chacun de ces caractères par sa valeur de somme de contrôle MD5 correspondante; c'est probablement exagéré, mais cela devrait nous empêcher d'entrer en collision avec les valeurs d'échappement par accident.

Remplacer un seul caractère par un MD5 complet semble extravagant, mais peut-être que cela a vraiment du sens.

Bien sûr, il serait intelligent d'envisager de créer une "vraie" syntaxe, pour un outil tel que Flex pour sortir de la tourbière d'expression régulière.

3
unwind

Si Perl n'est pas votre truc, il y a des implémentations Markdown dans au moins 10 autres langues . Ils n'ont probablement pas tous une compatibilité à 100%, mais ont tendance à être assez proches.

2
Ken

MarkdownPapers est une autre implémentation Java dont l'analyseur est défini dans une grammaire JavaCC .

2
Larry Ruiz

Ici vous pouvez trouver une implémentation JavaScript de Markdown. Il s'appuie également fortement sur les expressions régulières, car c'est juste la façon la plus rapide et la plus simple d'analyser le texte.

Mais cela épargne la partie MD5.

Je ne peux pas aider directement avec le codage de l'analyse, mais peut-être que ce lien peut vous aider d'une manière ou d'une autre.

0
Kosi2801

Il existe des bibliothèques disponibles dans un certain nombre de langues, y compris php, Ruby, Java, c #, javascript. Je suggère de regarder certaines de ces idées.

Cela dépend de la langue que vous souhaitez utiliser, pour la meilleure façon de l'implémenter, il y aura des façons idiomatiques et non idiomatiques de le faire.

Les regex fonctionnent en Perl, car Perl et regex sont les meilleurs amis.

0
garrow

Si vous utilisez un langage de programmation qui compte plus de trois autres utilisateurs, vous devriez pouvoir trouver une bibliothèque pour l'analyser pour vous. Une rapide recherche sur Google révèle des bibliothèques pour CL, Haskell, Python, JavaScript, Ruby, etc. Il est très peu probable que vous deviez réinventer cette roue.

Si vous devez vraiment l'écrire à partir de zéro, je vous recommande d'écrire un analyseur approprié. Avec cette technique, vous n'aurez pas à vous échapper avec des hachages MD5. (Je suis d'accord que si vous devez faire quelque chose comme ça, il est temps de reconsidérer votre conception.)

0
jrockway

Markdown est un JAWL (juste un autre langage wiki)

Il existe de nombreux wiki open source sur lesquels vous pouvez examiner le code de l'analyseur. La plupart utilisent REGEX

Consultez le wiki de Screwturn, il a un pipeline de formateur multi-passes intéressant, une technique très agréable - voir /core/Formatter.cs et /core/FormatterPipeline.cs

Le mieux est d'utiliser/de rejoindre un projet existant, ce genre de choses est toujours beaucoup plus difficile qu'il n'y paraît

0
TFD