Como você analisaria o Markdown? [fechadas]

126

Edit: Eu aprendi recentemente sobre um projeto chamado CommonMark, que identifica e lida corretamente com as ambiguidades na especificação Markdown original. http://commonmark.org/ Possui excelente suporte à biblioteca C #.

Você pode encontrar a sintaxe aqui .

A fonte que se segue ao download está escrita em Perl , que não tenho a intenção de honrar. É repleto de expressões regulares e conta com hashes MD5 para escapar de certos caracteres. Algo está errado nisso!

Estou prestes a codificar um analisador para Markdown . O que é experiência com isso?

Se você não tem nada significativo a dizer sobre a análise real de Markdown, me poupe tempo. (Isso pode parecer difícil, mas sim, estou procurando informações, não uma solução, ou seja, uma biblioteca de terceiros).

Para ajudar um pouco nas respostas, expressões regulares são destinadas a identificar padrões ! NÃO para analisar uma gramática inteira. O fato de as pessoas considerarem isso é foobar.

  • Se você pensa em Markdown, é fundamentalmente baseado no conceito de parágrafos.
  • Como tal, uma abordagem razoável pode ser dividir a entrada em parágrafos.
  • Existem muitos tipos de parágrafos, por exemplo, cabeçalho, texto, lista, citação em bloco e código.
  • O desafio é, portanto, identificar esses parágrafos e em que contexto eles ocorrem.

Voltarei com uma solução, quando achar que vale a pena ser compartilhada.

John Leidegren
fonte
2
@cletus está escrevendo um analisador de remarcação, consulte cforcoding.com/search/label/markdown
Alex Angas
Acabei fazendo o mesmo. No entanto, não estou tentando analisar a remarcação como se fosse uma gramática formal, porque claramente não é. Apliquei diferentes expressões regulares de maneira recursiva. E em várias passagens. Isso funcionou muito bem.
John Leidegren
@JohnLeidegren, alguma chance de outros usuários curiosos como eu poderem ver sua tentativa de analisar a remarcação?
jmlopez
@jmlopez Desculpe, não tenho mais acesso a essa fonte; se você precisar de um analisador de descontos, existe um pacote NuGet disponível que pode ser usado. A idéia é bastante simples, basta aplicar uma série de expressões regulares em passes, começar por particionar a entrada em parágrafos e tentar identificar que tipo de parágrafo é, e assim por diante. Por fim, analise os links e os estilos de caracteres nos próprios parágrafos.
John Leidegren
2
Você deve olhar para Parsedown . Ele divide o texto em linhas. Depois, analisa como essas linhas começam e se relacionam.
Emanuil Rusev

Respostas:

69

A única implementação remarcação eu conheço, que usa um analisador real, é Jon MacFarleane ‘s peg-remarcação . Seu analisador é baseado em um gerador de analisador de Gramática de Expressão de Análise chamado peg .


EDIT: Mauricio Fernandez lançou recentemente seu analisador Simple Markup Markdown , que ele escreveu como parte de seu OcsiBlog Weblog Engine. Como o analisador é escrito em OCaml , é extremamente simples e curto (268 SLOC para o analisador , 43 SLOC para o emissor HTML ), mas extremamente rápido (20% mais rápido que o desconto (escrito em C otimizado à mão) e seiscentas vezes mais rápido que BlueCloth ( Ruby)), apesar de ainda não estar otimizado para desempenho. Como ele é destinado apenas ao uso interno do próprio Mauricio para o seu blog, existem alguns desvios da especificação oficial do Markdown , mas o Mauricio criou um ramo que reverte a maioria dessas alterações .

Jörg W Mittag
fonte
1
interessante. talvez eu vou tentar converter isso como um projeto f #
ShuggyCoUk
@Benjol Mesma história antiga: sem tempo: /
ShuggyCoUk
1
Terrence Parr (co-autor do ANTLR) escreveu um para o ANTLR 4: github.com/parrt/mini-markdown #
Chris S
17

Lancei uma nova implementação Java Markdown baseada em analisador na semana passada, chamada pegdown . O pegdown usa um analisador PEG para criar primeiro uma árvore de sintaxe abstrata, que é gravada posteriormente em HTML. Como tal, é bastante limpo e muito mais fácil de ler, manter e estender do que uma abordagem baseada em regex. A gramática PEG é baseada na implementação "peg-markdown" de John MacFarlanes C.

Talvez algo de seu interesse ...

Mathias
fonte
1
Este é agora oficialmente obsoleto
Fabich
7

Se eu tentasse analisar markdown (e sua extensão Markdown extra ), acho que tentaria usar uma máquina de estado e analisá-la um caractere de cada vez, vinculando algumas estruturas internas que representam bits de texto à medida que avança, uma vez tudo é analisado, gerando a saída dos objetos todos juntos.

Basicamente, eu construí uma árvore semelhante a um mini-DOM enquanto leio o arquivo de entrada.
Para gerar uma saída, eu apenas atravessaria a árvore e exibia HTML ou qualquer outra coisa (PS, LaTex, RTF, ...)

Coisas que podem aumentar a complexidade:

  • O fato de você poder misturar HTML e remarcação, embora a regra possa ser fácil de implementar: simplesmente ignore qualquer coisa que esteja entre duas tags balanceadas e a produza literalmente.

  • URLs e notas podem ter sua referência na parte inferior do texto. O uso de estruturas de dados para hiperlinks poderia simplesmente gravar algo como:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • Os cabeçalhos podem ser definidos com um sublinhado, que pode nos forçar a usar uma estrutura de dados simples para um parágrafo genérico e modificar suas propriedades à medida que lemos o arquivo:

    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.
    

Enfim, apenas alguns pensamentos.

Tenho certeza de que há muitos pequenos detalhes para tratar e tenho certeza de que os Regexes podem se tornar úteis durante o processo.
Afinal, eles foram feitos para processar texto.

Renaud Bompuis
fonte
3

Provavelmente, eu teria lido a especificação de sintaxe o suficiente para conhecê-la e ter uma ideia de como analisá-la.

A leitura do código do analisador existente é obviamente brilhante, tanto para ver qual parece ser a principal fonte de complexidade quanto para saber se estão sendo usados ​​truques inteligentes especiais. O uso da soma de verificação MD5 parece um pouco estranho, mas não estudei o código o suficiente para entender por que está sendo feito. Um comentário em uma rotina chamada _EscapeSpecialChars()estados:

Estamos substituindo cada caractere por seu valor de soma de verificação MD5 correspondente; isso provavelmente é um exagero, mas deve impedir que colidamos com os valores de escape por acidente.

Substituir um único personagem por um MD5 completo parece extravagante, mas talvez faça realmente sentido.

Obviamente, seria inteligente considerar a criação de uma sintaxe "verdadeira", para uma ferramenta como o Flex sair do pântano de regex.

descontrair
fonte
Essa coisa do MD5 ainda me incomoda, também a manipulação excessiva de strings precisa ser mais lenta do que qualquer analisador decente que você possa escrever.
John Leidegren
2
O Flex é realmente apenas metade do analisador; depois de tokenizar a entrada, você precisa determinar o que os tokens significam. É para isso que serve um gerador de analisador. Há muitos deles. ( "Analisador combinator", "recursiva-descida" e "LALR (1)" são palavras-chave no Google para.)
jrockway
1
@jrockway: isso é verdade, é claro, acho que dei de ombros e pensei "mas se ele ler o Flex, ele encontrará Bison automaticamente". :) Obrigado.
descontrair
2

Se o Perl não é o seu caso, existem implementações do Markdown em pelo menos 10 outros idiomas . Eles provavelmente nem todos têm 100% de compatibilidade, mas tendem a ser bem próximos.

Ken
fonte
2

MarkdownPapers é outra implementação Java cujo analisador é definido em uma gramática JavaCC .

Larry Ruiz
fonte
1

Se você estiver usando uma linguagem de programação com mais de três outros usuários, poderá encontrar uma biblioteca para analisá-la. Um rápido Google-ing revela bibliotecas para CL, Haskell, Python, JavaScript, Ruby e assim por diante. É altamente improvável que você precise reinventar esta roda.

Se você realmente precisar escrevê-lo do zero, recomendo escrever um analisador adequado. Com essa técnica, você não precisará escapar de coisas com os hashes MD5. (Concordo que, se você precisar fazer algo assim, é hora de reconsiderar seu design.)

jrockway
fonte
Estou pronto para o desafio. Eu olhei para bibliotecas, mas elas são horríveis. Feio e estúpido. Estou pensando em escrever o analisador em F # porque preciso de um projeto em F #, mas provavelmente acabarei fazendo isso em C #.
John Leidegren
Espero que o F # tenha uma biblioteca como o Parsec; Se assim for, este será um projeto divertido;)
jrockway
0

Existem bibliotecas disponíveis em vários idiomas, incluindo php, ruby, java, c #, javascript. Eu sugiro olhar algumas dessas idéias.

Depende do idioma que você deseja usar, para a melhor maneira de implementá-lo, haverá maneiras idiomáticas e não-idiomáticas para fazê-lo.

Regexes funcionam em perl, porque perl e regex são melhores amigos.

garrow
fonte
1
Regex e perl são melhores amigos porque alguém disse isso. Não há mais verdade nesse fato do que sua ancestralidade histórica, que tenha sido usada dessa maneira. Não tenho utilidade para algo como perl.
John Leidegren
7
Então não o use. Aprenda também a ironia.
garrow
0

Markdown é uma JAWL (apenas outra linguagem wiki)

Existem muitos wiki de código aberto por aí que você pode examinar o código do analisador. A maioria usa REGEX

Verifique o wiki do screwturn, que possui um interessante pipeline de formatador de múltiplas passagens, uma técnica muito boa - consulte /core/Formatter.cs e /core/FormatterPipeline.cs

O melhor é usar / participar de um projeto existente, esse tipo de coisa é sempre muito mais difícil do que parece

TFD
fonte
0

Aqui você pode encontrar uma implementação em JavaScript do Markdown. Também depende muito de expressões regulares, pois essa é apenas a maneira mais rápida e fácil de analisar o texto.

Mas poupa a parte MD5.

Não posso ajudar diretamente com a codificação da análise, mas talvez esse link possa ajudá-lo de uma maneira ou de outra.

Kosi2801
fonte