¿Cómo harías para analizar Markdown? [cerrado]

126

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

Puede encontrar la sintaxis 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 en eso!

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

Si no tiene nada significativo que decir sobre el análisis real de Markdown, permítame 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 la gente considere hacerlo es un tonto.

  • Si piensa 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, bloque de comillas 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.

John Leidegren
fuente
2
@cletus está escribiendo un analizador de rebajas, consulte cforcoding.com/search/label/markdown
Alex Angas
Terminé haciendo lo mismo. Sin embargo, no estoy tratando de analizar la rebaja como si fuera una gramática formal, porque claramente no lo es. Apliqué diferentes expresiones regulares de manera recursiva. Y en varios pases. Eso funcionó muy bien.
John Leidegren
@JohnLeidegren, ¿hay alguna posibilidad de que otros usuarios curiosos como yo puedan ver tu intento de analizar el descuento?
jmlopez
@jmlopez Lo siento, ya no tengo acceso a esa fuente, si necesita un analizador de rebajas, hay un paquete NuGet disponible que se puede usar. Sin embargo, la idea es bastante simple: simplemente aplique una serie de expresiones regulares en pasadas, comience por dividir la entrada en párrafos, luego trate de identificar qué tipo de párrafo es, y así sucesivamente. Finalmente, analice los enlaces y los estilos de caracteres dentro de los párrafos mismos.
John Leidegren
2
Deberías mirar Parsedown . Divide el texto en líneas. Luego analiza cómo comienzan y se relacionan estas líneas entre sí.
Emanuil Rusev

Respuestas:

69

La única implementación de rebajas que conozco, que usa un analizador real, es la rebaja de clavijas de Jon MacFarleane . Su analizador se basa en un generador de analizador de gramática de expresión de análisis llamado peg .


EDITAR: Mauricio Fernández lanzó recientemente su analizador Simple Markup Markdown , que escribió como parte de su motor de registro web OcsiBlog . Debido a que el analizador está escrito en OCaml , es extremadamente simple y corto (268 SLOC para el analizador , 43 SLOC para el emisor HTML ), pero increíblemente rápido (20% más rápido que el descuento (escrito en C optimizado a mano) y seiscientas 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 del propio Mauricio para su blog, hay algunas desviaciones de la especificación oficial de Markdown , pero Mauricio ha creado una rama que revierte la mayoría de esos cambios .

Jörg W Mittag
fuente
1
interesante. quizás intente convertir eso como un proyecto f #
ShuggyCoUk
@Benjol La misma historia de siempre: no hay tiempo: /
ShuggyCoUk
1
Terrence Parr (coautor de ANTLR) ha escrito uno para ANTLR 4: github.com/parrt/mini-markdown
Chris S
17

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

Quizás algo de tu interés ...

Mathias
fuente
1
Esto ahora está oficialmente en desuso
Fabich
7

Si tuviera que intentar analizar Markdown (y su extensión Markdown extra ), creo que trataría de usar una máquina de estado y analizar un carácter a la vez, uniendo algunas estructuras internas que representan fragmentos de texto a medida que avanzo, una vez todo se analiza, generando la salida de los objetos todos unidos.

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

Cosas que pueden aumentar la complejidad:

  • El hecho de que puede mezclar HTML y markdown, aunque la regla podría ser fácil de implementar: simplemente ignore cualquier cosa que esté entre dos etiquetas balanceadas y envíela al pie de la letra.

  • 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 registrar algo como:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • 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 : <null> 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 texto.

Renaud Bompuis
fuente
3

Probablemente habría leído la especificación de sintaxis suficientes veces para conocerla y tener una idea de cómo analizarla.

La lectura del código del analizador existente es, por supuesto, brillante, tanto para ver cuál parece ser la principal fuente de complejidad, como si se están utilizando trucos inteligentes especiales. El uso de la suma de comprobación MD5 parece un poco extraño, pero no he estudiado el código lo suficiente como para entender por qué se está haciendo. Un comentario en una rutina llamada _EscapeSpecialChars()estados:

Estamos reemplazando cada uno de esos caracteres con su valor de suma de comprobación MD5 correspondiente; Es probable que esto sea excesivo, pero debería evitar que choquemos con los valores de escape por accidente.

Reemplazar un solo personaje por un MD5 completo parece extravagante, pero tal vez realmente tenga sentido.

Por supuesto, sería inteligente considerar la creación de una sintaxis "verdadera", para que una herramienta como Flex salga del pantano de expresiones regulares.

relajarse
fuente
Esa cosa de MD5 todavía me molesta, también la manipulación excesiva de cadenas tiene que ser más lenta que cualquier analizador decente real que pueda escribir usted mismo.
John Leidegren 03 de
2
Flex es realmente solo la mitad del analizador; Una vez que haya tokenizado la entrada, debe determinar qué significan los tokens. Para eso es un generador de analizador sintáctico. Hay muchos de ellos. ("Combinador de analizador", "descenso recursivo" y "LALR (1)" son palabras clave para google)
Jrockway 03 de
1
@jrockway: eso es cierto, por supuesto, supongo que me encogí de hombros y pensé "pero si lee sobre Flex, encontrará a Bison automáticamente". :) Gracias.
Descanse el
2

Si Perl no es lo tuyo, hay implementaciones de Markdown en al menos otros 10 idiomas . Probablemente no todos tengan una compatibilidad del 100%, pero tienden a estar bastante cerca.

Conocido
fuente
1

Si está utilizando un lenguaje de programación que tiene más de otros tres usuarios, debería poder encontrar una biblioteca para analizarlo por usted. Una rápida búsqueda en Google revela bibliotecas para CL, Haskell, Python, JavaScript, Ruby, etc. Es muy poco probable que necesite reinventar esta rueda.

Si realmente tiene que escribirlo desde cero, le recomiendo escribir un analizador adecuado. Con esta técnica, no tendrá que escapar de las cosas con hash MD5. (Estoy de acuerdo en que si tiene que hacer algo como esto, es hora de reconsiderar su diseño).

jrockway
fuente
Estoy preparado para el desafío. Miré las bibliotecas pero son horribles. Feo y estúpido. Estoy considerando escribir el analizador en F # porque necesito un proyecto F # pero probablemente terminaré haciéndolo en C #.
John Leidegren 03 de
Esperemos que F # tenga una biblioteca como Parsec; si es así, este será un proyecto divertido;)
jrockway 03 de
0

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 de hacerlo.

Las expresiones regulares funcionan en perl, porque perl y regex son mejores amigos.

garrow
fuente
1
Regex y Perl son mejores amigos porque alguien así lo dijo. No hay más verdad en ese hecho que su ascendencia histórica, que se ha utilizado así. No tengo uso para algo como Perl.
John Leidegren 03 de
77
Entonces no lo uses ... Además, aprende ironía.
Garrow 03 de
0

Markdown es un JAWL (solo otro lenguaje wiki)

Hay un montón de wiki de código abierto por ahí que puede examinar el código del analizador. La mayoría usa REGEX

Echa un vistazo a la wiki de tornillo, tiene una tubería de formateador de múltiples pasadas interesante, una técnica muy agradable - ver /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

TFD
fuente
0

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

Pero ahorra la parte MD5.

No puedo ayudar directamente con la codificación del análisis, pero tal vez este enlace pueda ayudarlo de una forma u otra.

Kosi2801
fuente