¿Cómo harías para analizar a Markdown?

Editar: Recientemente descubrí un proyecto llamado CommonMark, que identifica correctamente y trata las ambigüedades en la especificación de Markdown original. http://commonmark.org/ Tiene una gran compatibilidad con la biblioteca C #.

Puedes encontrar la syntax aquí .

La fuente que sigue con la descarga está escrita en Perl , que no tengo intenciones de honrar. Está plagado de expresiones regulares, y se basa en hashes MD5 para escapar de ciertos caracteres. Algo está mal acerca de eso!

Estoy a punto de codificar un analizador para Markdown . ¿Qué es la experiencia con esto?

Si no tienes nada significativo que decir sobre el análisis real de Markdown, perdóname el tiempo. (Esto puede sonar duro, pero sí, estoy buscando información, no una solución, es decir, una biblioteca de terceros).

Para ayudar un poco con las respuestas, ¡las expresiones regulares están destinadas a identificar patrones ! NO analizar una gramática completa. Que las personas consideren hacerlo es foobar.

  • Si piensas en Markdown, se basa fundamentalmente en el concepto de párrafos.
  • Como tal, un enfoque razonable podría ser dividir la entrada en párrafos.
  • Hay muchos tipos de párrafos, por ejemplo, encabezado, texto, lista, blockquote y código.
  • El desafío es, por lo tanto, identificar estos párrafos y en qué contexto ocurren.

Volveré con una solución, una vez que encuentre que es digno de ser compartido.

La única implementación de rebajas que conozco, que usa un analizador real, es la reducción de paridad de Jon MacFarleane . Su analizador está basado en un generador de analizador gtwigtical de expresión de análisis llamado peg .


EDITAR: Mauricio Fernández lanzó recientemente su analizador de Markdown Simple Markup , que escribió como parte de su motor de blogs OcsiBlog . Como el analizador está escrito en OCaml , es extremadamente simple y corto (268 SLOC para el analizador , 43 SLOC para el emisor HTML ), pero sorprendentemente rápido (20% más rápido que el descuento (escrito en C optimizado para mano) y seiscientos veces más rápido que BlueCloth ( Ruby )), a pesar de que aún no está optimizado para el rendimiento. Debido a que solo está destinado para uso interno por el propio Mauricio para su weblog, hay algunas desviaciones de la especificación oficial de Markdown , pero Mauricio ha creado una twig que revierte la mayoría de esos cambios .

Lancé una nueva implementación de Markdown Java basada en el analizador la semana pasada, llamada pegdown . pegdown usa un analizador PEG para construir primero un árbol de syntax abstracta, que luego se escribe en HTML. Como tal, es bastante limpio y mucho más fácil de leer, mantener y ampliar que un enfoque basado en expresiones regex. La gramática PEG se basa en la implementación de John MacFarlanes C “peg-markdown”.

Tal vez algo de tu interés …

Si tuviera que intentar analizar el descuento (y su extensión Markdown extra ), creo que trataría de usar una máquina de estado y analizarla de a una por vez, vinculando algunas estructuras internas que representan fragmentos de texto a medida que avanzo, una vez todo se analiza, generando el resultado de todos los objetos entrelazados.

Básicamente, construiría un árbol tipo mini-DOM cuando leyera el archivo de entrada.
Para generar una salida, simplemente atravesaría el árbol y obtendría HTML o cualquier otra cosa (PS, LaTex, RTF, …)

Cosas que pueden boost la complejidad:

  • El hecho de que puedes mezclar HTML y markdown, aunque la regla podría ser fácil de implementar: simplemente ignora todo lo que esté entre dos tags balanceadas y cuéntalo textualmente.

  • Las URL y las notas pueden tener su referencia en la parte inferior del texto. El uso de estructuras de datos para hipervínculos podría simplemente grabar algo como:

    [my text to a link][linkkey] results in a structure like: URLStructure: | InnerText : "my text to a link" | Key : "linkkey" | URL :  
  • Los encabezados se pueden definir con un subrayado, que podría obligarnos a usar una estructura de datos simple para un párrafo genérico y modificar sus propiedades a medida que leemos el archivo:

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

De todos modos, solo algunos pensamientos.

Estoy seguro de que hay muchos pequeños detalles que cuidar y estoy bastante seguro de que Regexes podría ser útil durante el proceso.
Después de todo, estaban destinados a procesar el texto.

Probablemente habría leído la especificación de syntax suficientes veces para saberlo y tener una idea de cómo analizarlo.

Leer el código del analizador existente es, por supuesto, shiny, tanto para ver lo que parece ser la principal fuente de complejidad, y si se utilizan trucos especiales inteligentes. El uso de la sum de comprobación MD5 parece un poco raro, pero no he estudiado el código lo suficiente como para entender por qué se está haciendo. Un comentario en una rutina llamada _EscapeSpecialChars() dice:

Estamos reemplazando cada uno de esos caracteres con su valor de sum de comprobación MD5 correspondiente; esto es probable que sea excesivo, pero debería evitar que colisionemos accidentalmente con los valores de escape.

Reemplazar un solo personaje por un MD5 completo parece extravagante, pero quizás realmente tenga sentido.

Por supuesto, sería inteligente considerar crear una syntax “verdadera” para que una herramienta como Flex salga del pantano de expresiones regulares.

Si Perl no es lo tuyo, existen implementaciones de Markdown en al menos otros 10 idiomas . Probablemente no todos tienen 100% de compatibilidad, pero tienden a ser bastante cercanos.

MarkdownPapers es otra implementación de Java cuyo analizador está definido en una gramática JavaCC .

Hay bibliotecas disponibles en varios idiomas, incluidos php, ruby, java, c #, javascript. Sugeriría mirar algunas de estas ideas.

Depende del idioma que desee utilizar, para la mejor manera de implementarlo, habrá formas idiomáticas y no idiomáticas para hacerlo.

Regexes funcionan en Perl, porque perl y regex son mejores amigos.

Si está utilizando un lenguaje de progtwigción que tiene más de otros tres usuarios, debería poder encontrar una biblioteca para analizarlo por usted. Un rápido Google-ing revela bibliotecas para CL, Haskell, Python, JavaScript, Ruby, etc. Es muy poco probable que deba reinventar esta rueda.

Si realmente tiene que escribir desde cero, le recomiendo que escriba un analizador apropiado. Con esta técnica, no tendrás que escapar de cosas con hash MD5. (Estoy de acuerdo en que si tienes que hacer algo como esto, es hora de que reconsideres tu diseño).

Markdown es un JAWL (solo otro lenguaje wiki)

Hay muchos wiki de código abierto que pueden examinar el código del analizador. La mayoría usa REGEX

Echa un vistazo a la wiki de screwturn, tiene una interesante interconexión de formateador de múltiples pasos, una técnica muy buena: mira /core/Formatter.cs y /core/FormatterPipeline.cs

Lo mejor es usar / unirse a un proyecto existente, este tipo de cosas siempre son mucho más difíciles de lo que parecen

Aquí puede encontrar una implementación de JavaScript de Markdown. También depende en gran medida de expresiones regulares, ya que esta es la forma más rápida y sencilla de analizar el texto.

Pero ahorra la parte MD5.

No puedo ayudar directamente con la encoding del análisis sintáctico, pero tal vez este enlace puede ayudarte de una forma u otra.