Come analizzeresti Markdown? [chiuso]


126

Modifica: Di recente ho appreso di un progetto chiamato CommonMark, che identifica e affronta correttamente le ambiguità nella specifica Markdown originale. http://commonmark.org/ Ha un ottimo supporto per la libreria C #.

Puoi trovare la sintassi qui .

La fonte che segue con il download è scritta in Perl , che non ho intenzione di onorare. È pieno di espressioni regolari e si basa su hash MD5 per sfuggire a determinati personaggi. C'è qualcosa di sbagliato in questo!

Sto per codificare un parser per Markdown . Che cos'è l'esperienza con questo?

Se non hai niente di significativo da dire sull'analisi effettiva di Markdown, risparmia tempo. (Questo potrebbe sembrare duro, ma sì, sto cercando informazioni, non una soluzione, cioè una libreria di terze parti).

Per aiutare un po 'con le risposte, le espressioni regolari hanno lo scopo di identificare gli schemi ! NON analizzare un'intera grammatica. Che la gente pensi di farlo è fobare.

  • Se pensi a Markdown, è fondamentalmente basato sul concetto di paragrafi.
  • Pertanto, un approccio ragionevole potrebbe essere quello di dividere l'input in paragrafi.
  • Esistono molti tipi di paragrafi, ad esempio intestazione, testo, elenco, blockquote e codice.
  • La sfida è quindi quella di identificare questi paragrafi e in quale contesto si verificano.

Tornerò con una soluzione, una volta trovata degna di essere condivisa.


2
@cletus sta scrivendo un parser markdown
Alex Angas

Ho finito per fare lo stesso. Tuttavia, non sto cercando di analizzare il markdown come se fosse una grammatica formale, perché chiaramente non lo è. Ho applicato diverse espressioni regolari in modo ricorsivo. E in più passaggi. Ha funzionato molto bene.
John Leidegren,

@JohnLeidegren, qualche possibilità che altri utenti curiosi come me possano vedere il tuo tentativo di analizzare il markdown?
jmlopez,

@jmlopez Siamo spiacenti, non ho più accesso a quella fonte, se hai bisogno di un parser markdown, c'è un pacchetto NuGet disponibile che può essere usato. L'idea è abbastanza semplice, basta applicare una serie di espressioni regolari in passaggi, iniziare partizionando l'input in paragrafi, quindi provare a identificare il tipo di paragrafo che è, e così via. Infine, analizza i collegamenti e gli stili di carattere all'interno dei paragrafi stessi.
John Leidegren,

2
Dovresti guardare Parsedown . Divide il testo in righe. Quindi osserva come iniziano e si collegano queste linee.
Emanuil Rusev,

Risposte:


69

L'unica implementazione di markdown che conosco, che utilizza un vero parser, è il peg- markdown di Jon MacFarleane . Il suo parser si basa su un generatore di parser Parsing Expression Grammar chiamato peg .


EDIT: Mauricio Fernandez ha recentemente rilasciato il suo parser Simple Markup Markdown , che ha scritto come parte del suo motore di blog di OcsiBlog . Poiché il parser è scritto in OCaml , è estremamente semplice e breve (268 SLOC per il parser , 43 SLOC per l' emettitore HTML ), ma incredibilmente veloce (20% più veloce dello sconto (scritto in C ottimizzato a mano) e seicento volte più veloce di BlueCloth ( Ruby)), nonostante non sia ancora ottimizzato per le prestazioni. Poiché è destinato esclusivamente all'uso interno da parte dello stesso Mauricio per il suo blog, ci sono alcune deviazioni dalle specifiche ufficiali di Markdown , ma Mauricio ha creato un ramo che ripristina la maggior parte di questi cambiamenti .


1
interessante. forse proverò a convertirlo come progetto f #
ShuggyCoUk l'

@Benjol Stessa vecchia storia: non c'è tempo: /
ShuggyCoUk

1
Terrence Parr (coautore di ANTLR) ne ha scritto uno per ANTLR 4: github.com/parrt/mini-markdown
Chris S,

17

La scorsa settimana ho rilasciato una nuova implementazione Markdown basata su parser, chiamata pegdown . pegdown utilizza un parser PEG per creare prima un albero di sintassi astratto, che viene successivamente scritto in HTML. Come tale è abbastanza pulito e molto più facile da leggere, mantenere ed estendere rispetto a un approccio basato su regex. La grammatica PEG si basa sull'implementazione "peg-markdown" di John MacFarlanes C.

Forse qualcosa di interessante per te ...


1
Questo è ora ufficialmente deprecato
Fabich,

7

Se dovessi provare ad analizzare il markdown (e la sua estensione Markdown extra ) penso che proverei a usare una macchina a stati e analizzarlo un carattere alla volta, collegando insieme alcune strutture interne che rappresentano frammenti di testo mentre procedo, una volta tutto viene analizzato, generando l'output dagli oggetti tutti messi insieme.

Fondamentalmente, costruivo un albero simile a un mini DOM mentre leggevo il file di input.
Per generare un output, attraverserei semplicemente l'albero e avrei generato HTML o qualsiasi altra cosa (PS, LaTex, RTF, ...)

Cose che possono aumentare la complessità:

  • Il fatto che sia possibile combinare HTML e markdown, sebbene la regola possa essere facile da implementare: basta ignorare tutto ciò che è tra due tag bilanciati e emetterlo alla lettera.

  • Gli URL e le note possono avere il loro riferimento nella parte inferiore del testo. L'uso delle strutture dati per i collegamenti ipertestuali potrebbe semplicemente registrare qualcosa del tipo:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • Le intestazioni possono essere definite con una sottolineatura, che potrebbe costringerci a utilizzare una semplice struttura di dati per un paragrafo generico e modificarne le proprietà mentre leggiamo il file:

    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.
    

Comunque, solo alcuni pensieri.

Sono sicuro che ci sono molti piccoli dettagli di cui occuparsi e sono abbastanza sicuro che Regexes potrebbe tornare utile durante il processo.
Dopotutto, dovevano elaborare il testo.


3

Probabilmente avrei letto le specifiche della sintassi abbastanza volte per conoscerla e avrei avuto un'idea di come analizzarla.

La lettura del codice parser esistente è ovviamente geniale, sia per vedere quale sembra essere la principale fonte di complessità, sia se vengono utilizzati speciali trucchi intelligenti. L'uso del checksum MD5 sembra un po 'strano, ma non ho studiato abbastanza il codice per capire perché sia ​​stato fatto. Un commento in una routine chiamata _EscapeSpecialChars()afferma:

Sostituiamo ciascuno di questi caratteri con il corrispondente valore di checksum MD5; questo è probabilmente eccessivo, ma dovrebbe impedirci di scontrarci con i valori di fuga per caso.

Sostituire un singolo personaggio con un MD5 completo sembra stravagante, ma forse ha davvero senso.

Certo, sarebbe intelligente prendere in considerazione la creazione di una sintassi "vera", per uno strumento come Flex per uscire dalla palude regex.


Quella cosa MD5 mi disturba ancora, anche l'eccessiva manipolazione delle stringhe deve essere più lenta di qualsiasi vero parser decente che potresti scrivere da solo.
John Leidegren,

2
Flex è in realtà solo metà del parser; una volta tokenizzato l'input, è necessario determinare cosa significano i token. Ecco a cosa serve un generatore di parser. Ce ne sono molti. ("Parser combinator", "recursive-descent" e "LALR (1)" sono parole chiave per google per.)
jrockway

1
@jrockway: questo è vero, immagino di aver scrollato le spalle e pensato "ma se legge su Flex, troverà automaticamente Bison". :) Grazie.
Rilassati il

2

Se Perl non fa per te, ci sono implementazioni di Markdown in almeno altre 10 lingue . Probabilmente non tutti hanno una compatibilità del 100%, ma tendono ad essere abbastanza vicini.



1

Se stai usando un linguaggio di programmazione che ha più di tre altri utenti, dovresti essere in grado di trovare una libreria per analizzarla. Un rapido Google-ing rivela librerie per CL, Haskell, Python, JavaScript, Ruby e così via. È altamente improbabile che dovrai reinventare questa ruota.

Se devi davvero scriverlo da zero, ti consiglio di scrivere un parser adeguato. Con questa tecnica, non dovrai sfuggire alle cose con gli hash MD5. (Sono d'accordo che se devi fare qualcosa del genere, è tempo di riconsiderare il tuo design.)


Sono pronto per la sfida. Ho guardato le biblioteche ma sono semplicemente orribili. Brutto e stupido. Sto pensando di scrivere il parser in F # perché ho bisogno di un progetto F # ma probabilmente finirò per farlo in C #.
John Leidegren,

Speriamo che F # abbia una libreria come Parsec; in tal caso, questo sarà un progetto divertente;)
jrockway

0

Esistono librerie disponibili in diverse lingue, tra cui php, ruby, java, c #, javascript. Suggerirei di esaminare alcune di queste idee.

Dipende dal linguaggio che si desidera utilizzare, per il modo migliore per implementarlo, ci saranno modi idiomatici e non idiomatici per farlo.

I regex lavorano in perl, perché perl e regex sono i migliori amici.


1
Regex e Perl sono i migliori amici perché qualcuno lo ha detto. Non c'è più verità in questo fatto di quanto non sia la sua origine storica, che sia stato usato così. Non ho alcuna utilità per qualcosa come Perl.
John Leidegren,

7
Quindi non usarlo .. Inoltre, impara l'ironia.
Garrow

0

Markdown è un JAWL (solo un altro linguaggio wiki)

Ci sono molti wiki open source là fuori che puoi esaminare il codice del parser. La maggior parte usa REGEX

Dai un'occhiata al wiki di screwturn, ha un'interessante pipeline formatter multi pass, una tecnica molto bella - vedi /core/Formatter.cs e /core/FormatterPipeline.cs

La cosa migliore è usare / partecipare a un progetto esistente, questo genere di cose è sempre molto più difficile di quanto sembri


0

Qui puoi trovare un'implementazione JavaScript di Markdown. Si basa inoltre su espressioni regolari, in quanto questo è solo il modo più rapido e semplice per analizzare il testo.

Ma risparmia la parte MD5.

Non posso aiutare direttamente con la codifica dell'analisi, ma forse questo link può aiutarti in un modo o nell'altro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.