2009-03-03 13 views
112

Editar: Hace poco conocí un proyecto llamado CommonMark, que identifica correctamente y trata las ambigüedades en la especificación de reducción original . http://commonmark.org/ Tiene gran biblioteca C# soporte.¿Qué harías al analizar Markdown?

Puede encontrar la sintaxis here.

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 hash 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 tiene nada significativo que decir sobre el análisis real de Markdown, evíteme 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 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, blockquote y código.
  • El desafío es, por lo tanto, identificar estos párrafos y en qué contexto se producen.

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

+2

@cletus está escribiendo un analizador de rebajas, consulte http://www.cforcoding.com/search/label/markdown –

+0

Terminé haciendo lo mismo. Sin embargo, no estoy tratando de analizar el descuento como si se tratara de una gramática formal, porque claramente no es así. Apliqué diferentes expresiones regulares de forma recursiva. Y en varios pases. Eso funcionó muy bien. –

+0

@JohnLeidegren, ¿hay alguna posibilidad de que otros usuarios curiosos como yo veamos tu intento de analizar el descuento? – jmlopez

Respuesta

60

La única implementación de rebajas que conozco, que usa un analizador real, es Jon MacFarleane 's peg-markdown. Its parser se basa en un generador de analizador Parsing Expression Grammar llamado peg.


EDIT: Mauricio Fernandez recientemente lanzó su Simple Markup Markdown parser, que escribió como parte de su motor OcsiBlog Weblog. Debido a que el analizador está escrito en OCaml, es extremadamente simple y corto (268 SLOC para la parser, 43 SLOC para la HTML emitter), sin embargo blazingly fast (20% más rápido que discount (escrito en optimizado a mano C) y sixhundred 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 del official Markdown specification, pero Mauricio ha creado a branch which reverts most of those changes.

+0

interesante. quizás intentaré convertir eso como un proyecto de f # – ShuggyCoUk

+0

@ShuggyCoUK, ¿o sí? – Benjol

+0

@Benjol La misma vieja historia: no hay tiempo:/ – ShuggyCoUk

2

Si Perl no es lo tuyo, existen implementaciones de Markdown en at least 10 other languages. Probablemente no todos tienen 100% de compatibilidad, pero tienden a ser bastante cercanos.

3

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

Leer el código del analizador existente es, por supuesto, brillante, tanto para ver lo que parece ser la principal fuente de complejidad, y si se utilizan trucos especiales inteligentes. El uso de la suma 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() indica:

Estamos reemplazando cada carácter con su valor de suma 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 carácter por un MD5 completo parece extravagante, pero quizás realmente tenga sentido.

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

+0

Esa cosa MD5 todavía me molesta, también la excesiva manipulación de cadenas tiene que ser más lento que cualquier analizador decente real que podría escribir usted mismo. –

+2

Flex es realmente solo la mitad del analizador sintáctico; una vez que ha tokenizado la entrada , debe determinar qué significan los tokens. Esto es para lo que es un generador de analizador . Hay muchos de ellos. ("Combinador de analizador", "recursivo-descenso" y "LALR (1)" son palabras clave para google.) – jrockway

+1

@jrockway: eso es cierto, por supuesto, creo que me encogí de hombros y pensé "pero si él lee en Flex, encontrará a Bison automáticamente ". :) Gracias. – unwind

0

Here 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 codificación del análisis sintáctico, pero tal vez este enlace puede ayudarte de una forma u otra.

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.

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

+1

Regex y Perl son mejores amigos porque alguien lo dijo. No hay más verdad en este hecho que su ascendencia histórica, que se haya usado así. No tengo uso para algo como Perl. –

+6

Entonces no lo use .. Además, aprenda ironía. – garrow

0

Si está utilizando un lenguaje de programación que tiene más de otros tres usuarios de , 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 necesite para reinventar esta rueda.

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

+0

Estoy listo para el desafío. Miré las bibliotecas, pero son horribles. Feo y estúpido Estoy considerando escribir el analizador sintáctico en F # porque necesito un proyecto F # pero probablemente termine haciéndolo en C#. –

+0

Afortunadamente F # tiene una biblioteca como Parsec; si es así, este será un proyecto divertido;) – jrockway

0

de rebajas es una Jawl (sólo otro lenguaje wiki)

Hay un montón de fuera de código abierto de wiki hay que puedes examinar el código del analizador. La mayoría de REGEX

Mira la ScrewTurn wiki de uso, es interesante tiene una tubería de múltiples pase formateador, una técnica muy agradable - ver /core/Formatter.cs y /core/FormatterPipeline.cs

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

3

Si tuviera que tratar de analizar el marcado (y su extensión Markdown extra) creo que trataría de usar una máquina de estado y analizar un carácter en un tiempo, uniendo algunas estructuras internas que representan bits de texto a medida que avanzo, una vez que todo es analizado, generando el resultado de los objetos todos unidos entre sí.

Básicamente, construiría un árbol similar a mini-DOM cuando lea el archivo de entrada.
para generar una salida, me acaba de recorrer el árbol y la salida HTML o cualquier otra cosa (PS, látex, RTF, ...)

factores que pueden aumentar 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 etiquetas 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  : <null> 
    
  • encabezados se puede definir con un subrayado, que nos podría obligar a utilizar una estructura de datos simple para un párrafo genérico y modificar sus propiedades como se lee 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, sólo 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.

17

Lancé una nueva implementación de Markdown Java basada en el analizador la semana pasada, llamada pegdown. pegdown utiliza un analizador PEG para crear 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 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 interés para usted ...