Comment procéderiez-vous pour analyser Markdown? [fermé]


126

Edit: J'ai récemment appris l'existence d'un projet appelé CommonMark, qui identifie et traite correctement 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 repose sur les 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 le temps. (Cela peut sembler dur, mais oui, je recherche un aperçu, 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 des modèles ! NE PAS analyser une grammaire entière. Que les gens envisagent de le faire est foobar.

  • Si vous pensez à Markdown, il est fondamentalement basé sur le concept de paragraphes.
  • En tant que telle, une approche raisonnable pourrait consister à diviser l’entrée en paragraphes.
  • Il existe de nombreux types de paragraphes, par exemple l'en-tête, le texte, la liste, le blockquote et le code.
  • L'enjeu est donc d'identifier ces paragraphes et dans quel contexte ils s'inscrivent.

Je serai de retour avec une solution, une fois que je trouverai qu'elle vaut la peine d'être partagée.


2
@cletus est en train d'écrire un analyseur de démarques, voir cforcoding.com/search/label/markdown
Alex Angas le

J'ai fini par faire de même. Cependant, je n'essaie pas d'analyser le démarquage comme s'il s'agissait d'une grammaire formelle, car ce n'est clairement pas le cas. J'ai appliqué différentes expressions régulières de manière récursive. Et en plusieurs passes. Cela a très bien fonctionné.
John Leidegren

@JohnLeidegren, est-ce que d'autres utilisateurs curieux comme moi peuvent voir votre tentative d'analyse de démarque?
jmlopez

@jmlopez Désolé, je n'ai plus accès à cette source, si vous avez besoin d'un analyseur de démarques, il existe un package NuGet disponible qui peut être utilisé. L'idée est cependant assez simple, il suffit d'appliquer une série d'expressions régulières par passes, de commencer par partitionner l'entrée en paragraphes puis d'essayer d'identifier de quel type de paragraphe il s'agit, et ainsi de suite. Enfin, analysez les liens et les styles de caractères dans les paragraphes eux-mêmes.
John Leidegren

2
Vous devriez regarder Parsedown . Il divise le texte en lignes. Ensuite, il examine comment ces lignes commencent et se rapportent les unes aux autres.
Emanuil Rusev

Réponses:


69

La seule implémentation de démarque que je connaisse, qui utilise un analyseur réel, est le peg-markdown de Jon MacFarleane . Son analyseur est basé sur un générateur d'analyseur de grammaire d'expression appelé peg .


EDIT: Mauricio Fernandez a récemment publié son analyseur Simple Markup Markdown , qu'il a écrit dans le cadre de son moteur de blog OcsiBlog . Comme l'analyseur est écrit en OCaml , il est extrêmement simple et court (268 SLOC pour l' analyseur , 43 SLOC pour l' émetteur HTML ), mais incroyablement rapide (20% plus rapide que discount (é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 officielle de Markdown , mais Mauricio a créé une branche qui annule la plupart de ces changements .


1
intéressant. peut-être que je vais essayer de convertir cela en un projet f #
ShuggyCoUk

@Benjol Même vieille histoire: pas de temps: /
ShuggyCoUk

1
Terrence Parr (co-auteur de ANTLR) en a écrit un pour ANTLR 4: github.com/parrt/mini-markdown
Chris S

17

J'ai publié la semaine dernière une nouvelle implémentation Java Markdown basée sur un analyseur, appelée pegdown . pegdown utilise un analyseur PEG pour construire d'abord un arbre de syntaxe abstraite, qui est ensuite écrit en HTML. En tant que tel, il est assez propre et beaucoup plus facile à lire, maintenir et étendre qu'une approche basée sur les regex. La grammaire PEG est basée sur l'implémentation «peg-markdown» de John MacFarlanes C.

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


1
Ceci est maintenant officiellement obsolète
Fabich

7

Si je devais essayer d'analyser 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 des structures internes représentant des morceaux de texte au fur et à mesure, une fois tout est analysé, générant la sortie des objets tous enchaînés.

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

Choses qui peuvent augmenter la complexité:

  • Le fait que vous puissiez mélanger HTML et markdown, 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 forcer à utiliser une structure de données simple pour un paragraphe générique et à modifier ses propriétés au fur et à mesure que nous lisons le 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 compte et je suis presque sûr que les expressions régulières pourraient devenir utiles pendant le processus.
Après tout, ils étaient destinés à traiter du texte.


3

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 si des astuces spéciales sont utilisées. L'utilisation de la somme de contrôle MD5 semble un peu étrange, mais je n'ai pas suffisamment étudié le code pour comprendre pourquoi cela est fait. Un commentaire dans une routine appelée _EscapeSpecialChars()états:

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 c'est peut-être vraiment logique.

Bien sûr, il serait judicieux d'envisager de créer une «vraie» syntaxe, pour qu'un outil tel que Flex sorte de la tourbière des regex.


Ce truc MD5 me dérange toujours, aussi la manipulation excessive de chaînes doit être plus lente que n'importe quel analyseur décent réel que vous pourriez écrire vous-même.
John Leidegren

2
Flex n'est en réalité que la moitié de l'analyseur; une fois que vous avez tokenisé l'entrée, vous devez déterminer ce que signifient les jetons. C'est à cela que sert un générateur d'analyseur. Il y en a beaucoup. ("Parser combinator", "recursive-descente" et "LALR (1)" sont des mots clés à rechercher sur Google.)
jrockway

1
@jrockway: c'est vrai bien sûr, je suppose que j'ai haussé les épaules et j'ai pensé "mais s'il lit sur Flex, il trouvera Bison automatiquement". :) Merci.
détendre

2

Si Perl n'est pas votre truc, il existe 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.



1

Si vous utilisez un langage de programmation qui a plus de trois autres utilisateurs, vous devriez être en mesure de trouver une bibliothèque pour l'analyser pour vous. Un rapide Google-ing révèle des bibliothèques pour CL, Haskell, Python, JavaScript, Ruby, etc. Il est peu probable que vous ayez besoin de 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 les hachages MD5. (Je suis d'accord que si vous devez faire quelque chose comme ça, il est temps de reconsidérer votre conception.)


Je suis prêt à relever le défi. J'ai regardé les bibliothèques mais elles sont tout simplement horribles. Moche et stupide. J'envisage d'écrire l'analyseur en F # car j'ai besoin d'un projet F # mais je finirai probablement par le faire en C #.
John Leidegren

Espérons que F # a une bibliothèque comme Parsec; si tel est le cas, ce sera un projet amusant;)
jrockway

0

Il existe des bibliothèques disponibles dans un certain nombre de langues, notamment php, ruby, java, c #, javascript. Je suggérerais de regarder certains d'entre eux pour des 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.


1
Regex et perl sont les meilleurs amis parce que quelqu'un l'a dit. Il n'y a pas plus de vérité dans ce fait que son ascendance historique, qu'il a été utilisé comme ça. Je n'ai pas besoin de quelque chose comme perl.
John Leidegren

7
Alors ne l'utilisez pas. Aussi, apprenez l'ironie.
garrow

0

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 très belle technique - 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

Ici vous pouvez trouver une implémentation JavaScript de Markdown. Il repose également fortement sur les expressions régulières, car il s'agit simplement du moyen le plus rapide et le 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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.