CommonMark: una especificación formal para Markdown

Publicado: 2022-03-10
Resumen rápido ↬ Markdown es un poderoso lenguaje de marcado que permite editar y formatear en formato de texto sin formato que luego se puede analizar y representar como HTML. Tiene una sintaxis declarativa que es poderosa y fácil de aprender para personas técnicas y no técnicas. Sin embargo, debido a las ambigüedades consecuentes en su especificación original, ha habido una serie de sabores distintos (o versiones personalizadas) que tienen como objetivo borrar esas ambigüedades y ampliar el soporte de sintaxis original. Esto ha llevado a una gran divergencia entre lo que se puede analizar y lo que se representa. CommonMark tiene como objetivo proporcionar una especificación estandarizada de Markdown que refleje su uso en el mundo real.

CommonMark es una versión racionalizada de la sintaxis de Markdown con una especificación cuyo objetivo es eliminar las ambigüedades e incoherencias que rodean a la especificación Markdown original. Ofrece una especificación estandarizada que define la sintaxis común del lenguaje junto con un conjunto de pruebas integrales para validar las implementaciones de Markdown con respecto a esta especificación.

GitHub usa Markdown como lenguaje de marcado para su contenido de usuario.

"CommonMark es un proyecto ambicioso para especificar formalmente la sintaxis de Markdown utilizada por muchos sitios web en Internet de una manera que refleje su uso en el mundo real [...] Permite a las personas continuar usando Markdown de la misma manera que siempre lo han hecho mientras ofrece a los desarrolladores una especificación integral e implementaciones de referencia para interoperar y mostrar Markdown de manera consistente entre plataformas”.

— “Una especificación formal para el Markdown con sabor a GitHub”, The GitHub Blog

En 2012, GitHub procedió a crear su propio tipo de Markdown, GitHub Flavored Markdown (GFM), para combatir la falta de estandarización de Markdown y extender la sintaxis a sus necesidades. GFM se creó sobre Sundown, un analizador creado específicamente por GitHub para resolver algunas de las deficiencias de los analizadores Markdown existentes en ese momento. Cinco años después, en 2017, anunció la desaprobación de Sundown a favor de la biblioteca de procesamiento y análisis de CommonMark, cmark en Una especificación formal para GitHub Flavored Markdown.

En la sección Preguntas comunes de Markdown y Visual Studio Code, se documenta que Markdown en VSCode tiene como objetivo la especificación CommonMark Markdown mediante la biblioteca markdown-it, que en sí misma sigue la especificación CommonMark.

CommonMark se ha adoptado e implementado ampliamente (consulte la Lista de implementaciones de CommonMark) para su uso en diferentes lenguajes como C (p. ej., cmark), C# (p. ej., CommonMark.NET), JavaScript (p. ej., markdown-it), etc. Esta es una buena noticia para los desarrolladores. y los autores se están moviendo gradualmente a una nueva frontera de poder usar Markdown con una sintaxis consistente y una especificación estandarizada.

Una breve nota sobre los analizadores Markdown

Los analizadores de Markdown están en el centro de la conversión de texto de Markdown en HTML, directa o indirectamente.

Los analizadores como cmark y commonmark.js no convierten Markdown a HTML directamente, sino que lo convierten en un árbol de sintaxis abstracta (AST) y luego representan el AST como HTML, lo que hace que el proceso sea más granular y esté sujeto a manipulación. Entre el análisis, a AST, y la representación, a HTML, por ejemplo, el texto de Markdown podría extenderse.

¡Más después del salto! Continúe leyendo a continuación ↓

Compatibilidad con la sintaxis Markdown de CommonMark

Los proyectos o plataformas que ya implementan la especificación CommonMark como base de su versión específica a menudo son un superconjunto del subconjunto estricto de la especificación CommonMark Markdown. En su mayor parte, CommonMark ha mitigado muchas ambigüedades al crear una especificación que está diseñada para ser construida. GFM es un excelente ejemplo, aunque admite todas las sintaxis de CommonMark, también las amplía para adaptarse a su uso.

El soporte de sintaxis de CommonMark puede ser limitado al principio, por ejemplo, no tiene soporte para esta sintaxis de tabla, pero es importante saber que esto es por diseño como lo revela este comentario en este hilo de conversación: que la sintaxis admitida es estricta y dijo ser la sintaxis central del propio lenguaje, la misma especificada por su creador, John Gruber en Markdown: Syntax.

Al momento de escribir, aquí hay una serie de sintaxis admitidas:

  1. Párrafos y saltos de línea,
  2. Encabezados,
  3. Énfasis y fuerte énfasis,
  4. reglas horizontales,
  5. Liza,
  6. Enlaces,
  7. Imágenes,
  8. citas en bloque,
  9. Código,
  10. Bloques de código.

Para seguir con los ejemplos, se recomienda que utilice el editor dingus de commonmark.js para probar la sintaxis y obtener la vista previa renderizada, HTML generado y AST.

Párrafos y saltos de línea

En Markdown, los párrafos son líneas continuas de texto separadas por al menos una línea en blanco.

Las siguientes reglas definen un párrafo:

  1. Los párrafos Markdown se representan en HTML como el elemento Párrafo, <p>.
  2. Los diferentes párrafos se separan con una o más líneas en blanco entre ellos.
  3. Para un salto de línea, un párrafo debe corregirse con dos espacios en blanco (o su equivalente de tabulación) o una barra invertida ( \ ).
Sintaxis HTML renderizado
Esta es una línea de texto. <p>Esta es una línea de texto</p>
Esta es una línea de texto.
Y otra linea de texto
Y otro pero el
mismo párrafo
<p>Esta es una línea de texto
Y otra linea de texto
Y otro pero el
mismo párrafo</p>
Este es un párrafo

y otro parrafo

Y otro
<p>Esto es un párrafo</p>
<p>Y otro párrafo</p>
<p>Y otro</p>
Dos espacios después de una línea de texto
O una barra invertida posfija\
Ambos significan un salto de línea
<p>Dos espacios después de una línea de texto<br /><br>O una barra invertida fija posterior<br /><br>Ambos significan un salto de línea</p>
  • Tutorial interactivo para aprender sobre los párrafos.
  • Dingus enlace permanente consulte el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre los párrafos.

encabezados

Los encabezados en Markdown representan uno de los elementos de encabezado HTML. Hay dos formas de definir los encabezados:

  1. Encabezado ATX.
  2. Encabezado de texto.

Las siguientes reglas definen los encabezados ATX:

  1. Se admiten el nivel de encabezado 1 ( h1 ), hasta el nivel de encabezado 6, ( h6 ).
  2. Los encabezados de estilo ATX tienen el prefijo del símbolo hash ( # ).
  3. Debe haber al menos un espacio en blanco que separe el texto y el símbolo de almohadilla ( # ).
  4. El conteo de hashes es equivalente al número cardinal del encabezado. Un hash es h1 , dos hash, h2 , 6 hash, h6 .
  5. También es posible agregar un número arbitrario de símbolos hash a los encabezados, aunque esto no causa ningún efecto (es decir # Heading 1 # )
Sintaxis HTML renderizado
# Título 1 <h1>Título 1</h1>
## Título 2 <h2>Título 2</h2>
### Título 3 <h3>Título 3</h3>
#### Título 4 <h4>Encabezado 4</h4>
##### Título 5 <h5>Encabezado 5</h5>
###### Título 6 <h6>Encabezado 6</h6>
## Título 2 ## <h2>Título 2</h2>

Las siguientes reglas definen los encabezados de Setext:

  1. Solo se admiten el nivel de encabezado 1 (h1) y el nivel de encabezado 2 (h2).
  2. La definición de estilo Setext se realiza con los símbolos de igual (=) y guión respectivamente.
  3. Con Setext, se requiere al menos un símbolo igual o guión.
Sintaxis HTML renderizado
Título 1
=
<h1>Título 1</h1>
Título 2
-
<h2>Título 2</h2>
  • Tutorial interactivo para aprender sobre encabezados.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre los encabezados ATX.
  • Obtenga más información sobre los encabezados de Setext.

Énfasis y fuerte énfasis

El énfasis en Markdown puede ser cursiva o negrita (énfasis fuerte).

Las siguientes reglas definen el énfasis:

  1. El énfasis ordinario y fuerte se representan en HTML como el elemento Énfasis, <em> y Fuerte, <strong>, respectivamente.
  2. Un texto delimitado por un solo asterisco ( * ) o guión bajo ( _ ) será un énfasis.
  3. Un texto delimitado por asteriscos dobles o guión bajo será un fuerte énfasis.
  4. Los símbolos delimitadores (asteriscos o guiones bajos) deben coincidir.
  5. No debe haber espacio entre los símbolos y el texto adjunto.
Sintaxis HTML renderizado
_Italic_ <em>Cursiva</em>
*Italic* <em>Cursiva</em>
__Bold__ <strong>Negrita</strong>
**Bold** <strong>Negrita</strong>
  • Tutorial interactivo para aprender sobre el énfasis.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre Énfasis y énfasis fuerte.

Regla horizontal

Una regla horizontal, <hr/> se crea con tres o más asteriscos ( * ), guiones ( - ) o guiones bajos ( _ ), en una nueva línea. Los símbolos están separados por cualquier número de espacios, o no están separados en absoluto.

Sintaxis HTML renderizado
*** <hr />
* * * <hr />
--- <hr />
- - - <hr />
___ <hr />
_ _ _ <hr />
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre las pausas temáticas.

Liza

Las listas en Markdown son una lista con viñetas (no ordenada) o una lista ordenada.

Las siguientes reglas definen una lista:

  1. Las listas de viñetas se representan en HTML como el elemento de lista desordenada, <ul>.
  2. Las listas ordenadas se representan en HTML como el elemento de lista ordenada, <ol>.
  3. Las listas con viñetas usan asteriscos, signos más y guiones como marcadores.
  4. Las listas ordenadas utilizan números seguidos de puntos o paréntesis de cierre.
  5. Los marcadores deben ser consistentes (solo debe usar el marcador con el que comienza para el resto de la definición de elementos de la lista).
Sintaxis HTML renderizado
* una
* dos
* Tres
<ul>
<li>uno</li>
<li>dos</li>
<li>tres</li>
</ul>
+ uno
+ dos
+ tres
<ul>
<li>uno</li>
<li>dos</li>
<li>tres</li>
</ul>
- una
- dos
- Tres
<ul>
<li>uno</li>
<li>dos</li>
<li>tres</li>
</ul>
- una
- dos
+ tres
<ul>
<li>uno</li>
<li>dos</li>
</ul>
<ul>
<li>tres</li>
</ul>
1 uno
2. dos
3 tres
<ol>
<li>uno</li>
<li>dos</li>
<li>tres</li>
</ol>
3 tres
4. cuatro
5. cinco
<ol comienzo="3">
<li>tres</li>
<li>cuatro</li>
<li>cinco</li>
</ol>
1 uno
2. dos
3 tres
<ol>
<li>uno</li>
<li>dos</li>
<li>tres</li>
</ol>
  • Tutorial interactivo para aprender sobre listas.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtén más información sobre los elementos de Listas.

Enlaces

Los enlaces son compatibles con el formato en línea y de referencia .

Las siguientes reglas definen un vínculo:

  1. Los enlaces se representan como el elemento de anclaje HTML, <a>.
  2. El formato en línea tiene la sintaxis: [value](URL "optional-title") sin espacio entre corchetes.
  3. El formato de referencia tiene la sintaxis: [value][id] para la referencia, y [id]: href "optional-title" para la etiqueta del hipervínculo, separados por al menos una línea.
  4. El id es el Identificador de definición y puede constar de letras, números, espacios y signos de puntuación.
  5. Los identificadores de definición no distinguen entre mayúsculas y minúsculas.
  6. También hay soporte para enlaces automáticos, donde la URL está delimitada por el símbolo menor que (<) y mayor que (>), y se muestra literalmente.
 <!--Markdown--> [Google](https://google.com “Google”) <!--Rendered HTML--> <a href="https://google.com" title="Google">Google</a> <!--Markdown--> [Google](https://google.com) <!--Rendered HTML--> <a href="https://google.com">Google</a> <!--Markdown--> [Comparing Styling Methods in Next.js](/2020/09/comparing-styling-methods-next-js) <!--Rendered HTML--> <a href="/2020/09/comparing-styling-methods-next-js">Comparing Styling Methods In Next.js</a> <!--Markdown--> [Google][id] <!--At least a line must be in-between--> <!--Rendered HTML--> <a href="https://google.com" title="Google">Google</a> <!--Markdown--> <https://google.com> <!--Rendered HTML--> <a href="https://google.com">google.com</a> <!--Markdown--> <[email protected]> <!--Rendered HTML--> <a href="mailto:[email protected]">[email protected]</a>
  • Tutorial interactivo para aprender sobre enlaces.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre los enlaces.

Imágenes

Las imágenes en Markdown siguen los formatos en línea y de referencia para los enlaces.

Las siguientes reglas definen las imágenes:

  1. Las imágenes se representan como el elemento de imagen HTML, <img>.
  2. El formato en línea tiene la sintaxis: ![alt text](image-url "optional-title") .
  3. El formato de referencia tiene la sintaxis: ![alt text][id] para la referencia, y [id]: image-url "optional-title" para la etiqueta de la imagen. Ambos deben estar separados por al menos una línea en blanco.
  4. El título de la imagen es opcional y la URL de la imagen puede ser relativa.
 <!--Markdown--> ![alt text](image-url "optional-title") <!--Rendered HTML--> <img src="image-url" alt="alt text" title="optional-title" /> <!--Markdown--> ![alt text][id] <!--At least a line must be in-between--> <!--Markdown--> <!--Rendered HTML--> <img src="image-url" alt="alt text" title="optional-title" />
  • Tutorial interactivo para aprender sobre imágenes.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre Imágenes.

cotizaciones en bloque

El elemento de cita en bloque HTML, <blockquote>, se puede crear anteponiendo una nueva línea con el símbolo mayor que ( > ).

 <!--Markdown--> > This is a blockquote element > You can start every new line > with the greater than symbol. > That gives you greater control > over what will be rendered. <!--Rendered HTML--> <blockquote> <p>This is a blockquote element You can start every new line with the greater than symbol. That gives you greater control over what will be rendered.</p> </blockquote>

Las comillas en bloque se pueden anidar:

 <!--Markdown--> > Blockquote with a paragraph >> And another paragraph >>> And another <!--Rendered HTML--> <blockquote> <p>Blockquote with a paragraph</p> <blockquote> <p>And another paragraph</p> <blockquote> <p>And another</p> </blockquote> </blockquote> </blockquote>

También pueden contener otros elementos de Markdown, como encabezados, código, elementos de lista, etc.

 <!--Markdown--> > Blockquote with a paragraph > # Heading 1 > Heading 2 > - > 1. One > 2. Two <!--Rendered HTML--> <blockquote> <p>Blockquote with a paragraph</p> <h1>Heading 1</h1> <h2>Heading 2</h2> <ol> <li>One</li> <li>Two</li> </ol> </blockquote>
  • Tutorial interactivo para aprender sobre blockquotes.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre Blockquotes.

Código

El elemento de código en línea HTML, <code>, también es compatible. Para crear uno, delimite el texto con comillas invertidas (`) o comillas invertidas dobles si es necesario que haya una tilde invertida literal en el texto adjunto.

 <!--Markdown--> `inline code snippet` <!--Rendered HTML--> <code>inline code snippet</code> <!--Markdown--> `<button type='button'>Click Me</button>` <!--Rendered HTML--> <code><button type='button'>Click Me</button></code> <!--Markdown--> `` There's an inline back-tick (`). `` <!--Rendered HTML--> <code>There's an inline back-tick (`).</code>
  • Tutorial interactivo para aprender sobre código.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre los tramos de código.

Bloques de código

El elemento de texto preformateado HTML, <pre>, también es compatible. Esto se puede hacer con al menos tres y el mismo número de tildes ( ` ) o tildes ( ~ ), normalmente denominadas cercas de código, o una nueva sangría inicial de línea de al menos 4 espacios.

 <!--Markdown--> ``` const dedupe = (array) => [...new Set(array)]; ``` <!--Rendered HTML--> <pre><code>const dedupe = (array) => [...new Set(array)];</code></pre> <!--Markdown--> const dedupe = (array) => [...new Set(array)]; <!--Rendered HTML--> <pre><code>const dedupe = (array) => [...new Set(array)];</code></pre>
  • Tutorial interactivo para aprender sobre código.
  • Enlace permanente de Dingus para ver el ejemplo completo con la vista previa y AST.
  • Obtenga más información sobre los bloques de código delimitados y con sangría.

Uso de HTML en línea

De acuerdo con la nota de especificaciones original de John Grubers sobre HTML en línea, cualquier marcado que no esté cubierto por la sintaxis de Markdown, simplemente use el propio HTML, con Las únicas restricciones son los elementos HTML a nivel de bloque, por ejemplo, <div> , <table> , <pre> , <p> , etc.: deben estar separados del contenido circundante por líneas en blanco, y las etiquetas de inicio y fin del bloque no deben tener tabulaciones ni espacios.

Sin embargo, a menos que usted sea probablemente una de las personas detrás de CommonMark, lo más probable es que esté escribiendo Markdown con un sabor que ya está extendido para manejar una gran cantidad de sintaxis que actualmente no admite CommonMark.

Avanzando

CommonMark es un trabajo en progreso constante con su especificación actualizada por última vez el 6 de abril de 2019. Hay una serie de aplicaciones populares que lo admiten en el conjunto de herramientas de Markdown. Con el conocimiento del esfuerzo de CommonMark hacia la estandarización, creo que es suficiente concluir que en la simplicidad de Markdown, hay mucho trabajo detrás de escena y que es bueno para el esfuerzo de CommonMark que la especificación formal de GitHub Flavored Markdown se basa en la especificación.

El avance hacia el esfuerzo de estandarización de CommonMark no impide la creación de tipos para ampliar su sintaxis admitida y, a medida que CommonMark se prepara para la versión 1.0 con problemas que deben resolverse, hay algunos recursos interesantes sobre el esfuerzo continuo que puede utilizar para su lectura concienzuda.

Recursos

  • Presentamos Markdown de John Gruber
  • Sitio web oficial de CommonMark
  • Especificaciones de Markdown con sabor a GitHub
  • cmark repositorio oficial
  • La bifurcación de cmark de GitHub
  • Rebaja en Wikipedia
  • Guía de rebajas