CommonMark: uma especificação formal para Markdown
Publicados: 2022-03-10CommonMark é uma versão racionalizada da sintaxe Markdown com uma especificação cujo objetivo é remover as ambiguidades e inconsistências em torno da especificação Markdown original. Ele oferece uma especificação padronizada que define a sintaxe comum da linguagem juntamente com um conjunto de testes abrangentes para validar as implementações do Markdown em relação a essa especificação.
O GitHub usa Markdown como linguagem de marcação para o conteúdo do usuário.
“CommonMark é um projeto ambicioso para especificar formalmente a sintaxe Markdown usada por muitos sites na internet de uma maneira que reflita seu uso no mundo real [...] uma especificação abrangente e implementações de referência para interoperar e exibir o Markdown de maneira consistente entre as plataformas.”
— “Uma especificação formal para o Markdown com sabor do GitHub”, The GitHub Blog
Em 2012, o GitHub passou a criar seu próprio sabor de Markdown — GitHub Flavored Markdown (GFM) — para combater a falta de padronização do Markdown e estender a sintaxe para suas necessidades. O GFM foi construído em cima do Sundown, um analisador especificamente construído pelo GitHub para resolver algumas das deficiências dos analisadores Markdown existentes na época. Cinco anos depois, em 2017, anunciou a descontinuação do Sundown em favor da biblioteca de análise e renderização CommonMark, cmark em Uma especificação formal para o GitHub Flavored Markdown.
Na seção Perguntas comuns do Markdown e do Visual Studio Code, está documentado que o Markdown no VSCode tem como alvo a especificação CommonMark Markdown usando a biblioteca markdown-it, que por si só segue a especificação CommonMark.
O CommonMark foi amplamente adotado e implementado (veja a Lista de Implementações do CommonMark) para uso em diferentes linguagens como C (por exemplo, cmark), C# (por exemplo, CommonMark.NET), JavaScript (por exemplo, markdown-it) etc. Esta é uma boa notícia para os desenvolvedores e os autores estão gradualmente se movendo para uma nova fronteira de poder usar Markdown com uma sintaxe consistente e uma especificação padronizada.
Uma breve nota sobre analisadores de Markdown
Os analisadores de Markdown estão no centro da conversão de texto Markdown em HTML, direta ou indiretamente.
Analisadores como cmark e commonmark.js não convertem Markdown em HTML diretamente, em vez disso, eles o convertem em uma Árvore de Sintaxe Abstrata (AST) e, em seguida, renderizam o AST como HTML, tornando o processo mais granular e sujeito a manipulação. Entre a análise — para AST — e renderização — para HTML — por exemplo, o texto Markdown pode ser estendido.
Suporte à sintaxe Markdown do CommonMark
Projetos ou plataformas que já implementam a especificação CommonMark como a linha de base de seu sabor específico geralmente são superconjuntos do subconjunto estrito da especificação CommonMark Markdown. Na maior parte, o CommonMark atenuou muitas ambiguidades ao criar uma especificação criada para ser construída. O GFM é um excelente exemplo, embora suporte todas as sintaxes do CommonMark, ele também o estende para se adequar ao seu uso.
O suporte à sintaxe do CommonMark pode ser limitado no início, por exemplo, ele não tem suporte para essa sintaxe de tabela, mas é importante saber que isso ocorre por design, como este comentário neste tópico de conversa revela: que a sintaxe suportada é estrita e disse para ser a sintaxe central da própria linguagem — a mesma especificada por seu criador, John Gruber em Markdown: Syntax.
No momento da escrita, aqui estão algumas sintaxes suportadas:
- Parágrafos e quebras de linha,
- Cabeçalhos,
- Ênfase e Ênfase Forte,
- Regras horizontais,
- Listas,
- Links,
- Imagens,
- Citações em bloco,
- Código,
- Blocos de código.
Para acompanhar os exemplos, é recomendável usar o editor dingus commonmark.js para experimentar a sintaxe e obter a visualização renderizada, o HTML gerado e o AST.
Parágrafos e quebras de linha
No Markdown, os parágrafos são linhas contínuas de texto separadas por pelo menos uma linha em branco.
As seguintes regras definem um parágrafo:
- Os parágrafos Markdown são renderizados em HTML como o elemento Parágrafo, <p>.
- Diferentes parágrafos são separados por uma ou mais linhas em branco entre eles.
- Para uma quebra de linha, um parágrafo deve ser pós-fixado com dois espaços em branco (ou seu equivalente de tabulação) ou uma barra invertida (
\
).
Sintaxe | HTML renderizado |
---|---|
Esta é uma linha de texto | <p>Esta é uma linha de texto</p> |
Esta é uma linha de texto E outra linha de texto E outro, mas o mesmo parágrafo | <p>Esta é uma linha de texto E outra linha de texto E outro, mas o mesmo parágrafo</p> |
Este é um parágrafo E outro parágrafo E outro | <p>Este é um parágrafo</p> <p>E outro parágrafo</p> <p>E outro</p> |
Dois espaços após uma linha de texto Ou uma barra invertida pós-fixada\ Ambos significam uma quebra de linha | <p>Dois espaços após uma linha de texto<br /><br>Ou uma barra invertida pós-fixada<br /><br>Ambos significa uma quebra de linha</p> |
- Tutorial interativo para aprender sobre parágrafos.
- Dingus permalink confira o exemplo completo com o Preview e AST.
- Saiba mais sobre os parágrafos.
Títulos
Headings em Markdown representa um dos elementos HTML Heading. Existem duas maneiras de definir títulos:
- título ATX.
- Cabeçalho Setext.
As seguintes regras definem os cabeçalhos ATX:
- Nível de título 1 (
h1
), até o nível de título 6, (h6
) são suportados. - Os títulos no estilo Atx são prefixados com o símbolo de hash (
#
). - Deve haver pelo menos um espaço em branco separando o texto e o símbolo de hash (
#
). - A contagem de hashes é equivalente ao número cardinal do título. Um hash é
h1
, dois hashes,h2
, 6 hashes,h6
. - Também é possível anexar um número arbitrário de símbolos de hash aos títulos, embora isso não cause nenhum efeito (por exemplo,
# Heading 1 #
)
Sintaxe | HTML renderizado |
---|---|
# Cabeçallho 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>Título 4</h4> |
##### Título 5 | <h5>Título 5</h5> |
###### Título 6 | <h6>Título 6</h6> |
## Título 2 ## | <h2>Título 2</h2> |
As seguintes regras definem os cabeçalhos do Setext:
- Somente o nível de título 1 (h1) e o nível de título 2 (h2) são suportados.
- A definição do estilo Setext é feita com os símbolos de igual (=) e traço, respectivamente.
- Com Setext, é necessário pelo menos um símbolo de igual ou traço.
Sintaxe | HTML renderizado |
---|---|
Cabeçallho 1 = | <h1>Título 1</h1> |
Título 2 - | <h2>Título 2</h2> |
- Tutorial interativo para aprender sobre títulos.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre cabeçalhos ATX.
- Saiba mais sobre os títulos Setext.
Ênfase e Ênfase Forte
A ênfase no Markdown pode ser em itálico ou negrito (ênfase forte).
As seguintes regras definem a ênfase:
- A ênfase comum e forte são renderizadas em HTML como o elemento Emphasis, <em>, e Strong, <strong>, respectivamente.
- Um texto delimitado por um único asterisco (
*
) ou sublinhado (_
) será uma ênfase. - Um texto delimitado por asteriscos duplos ou sublinhado será uma forte ênfase.
- Os símbolos delimitadores (asteriscos ou sublinhados) devem corresponder.
- Não deve haver espaço entre os símbolos e o texto incluído.
Sintaxe | HTML renderizado |
---|---|
_Italic_ | <em>Itálico</em> |
*Italic* | <em>Itálico</em> |
__Bold__ | <strong>Negrito</strong> |
**Bold** | <strong>Negrito</strong> |
- Tutorial interativo para aprender sobre ênfase.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre Ênfase e ênfase forte.
Regra horizontal
Uma regra Horizontal, <hr/> é criada com três ou mais asteriscos ( *
), hifens ( -
) ou sublinhados ( _
), em uma nova linha. Os símbolos são separados por qualquer número de espaços, ou não.
Sintaxe | HTML renderizado |
---|---|
*** | <hr /> |
* * * | <hr /> |
--- | <hr /> |
- - - | <hr /> |
___ | <hr /> |
_ _ _ | <hr /> |
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre as pausas temáticas.
Listas
As listas no Markdown são uma lista de marcadores (não ordenada) ou uma lista ordenada.
As seguintes regras definem uma lista:
- As listas de marcadores são renderizadas em HTML como o elemento de lista não ordenada, <ul>.
- As listas ordenadas são renderizadas em HTML como o elemento de lista ordenada, <ol>.
- As listas de marcadores usam asteriscos, sinais de adição e hífens como marcadores.
- As listas ordenadas usam números seguidos por pontos ou parênteses de fechamento.
- Os marcadores devem ser consistentes (você deve usar apenas o marcador inicial para o restante da definição dos itens da lista).
Sintaxe | HTML renderizado |
---|---|
* 1 * dois * três | <ul> <li>um</li> <li>dois</li> <li>três</li> </ul> |
+ um + dois + três | <ul> <li>um</li> <li>dois</li> <li>três</li> </ul> |
- 1 - dois - três | <ul> <li>um</li> <li>dois</li> <li>três</li> </ul> |
- 1 - dois + três | <ul> <li>um</li> <li>dois</li> </ul> <ul> <li>três</li> </ul> |
1 um 2. dois 3. três | <ol> <li>um</li> <li>dois</li> <li>três</li> </ol> |
3. três 4. quatro 5. cinco | <ol start="3"> <li>três</li> <li>quatro</li> <li>cinco</li> </ol> |
1 um 2. dois 3. três | <ol> <li>um</li> <li>dois</li> <li>três</li> </ol> |
- Tutorial interativo para aprender sobre listas.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre os itens de listas.
Links
Os links são suportados com o formato embutido e de referência .
As regras a seguir definem um link:
- Os links são renderizados como o elemento HTML Anchor, <a>.
- O formato embutido tem a sintaxe:
[value](URL "optional-title")
sem espaço entre colchetes. - O formato de referência tem a sintaxe:
[value][id]
para a referência e[id]: href "optional-title"
para o rótulo do hiperlink, separado por pelo menos uma linha. - O
id
é o Identificador de Definição e pode consistir em letras, números, espaços e pontuação. - Os identificadores de definição não diferenciam maiúsculas de minúsculas.
- Há também suporte para Links Automáticos, onde o URL é limitado pelo símbolo menor que (<) e maior que (>) e exibido 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 interativo para aprender sobre links.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre Links.
Imagens
As imagens no Markdown seguem os formatos inline e de referência para links.
As regras a seguir definem imagens:
- As imagens são renderizadas como o elemento de imagem HTML, <img>.
- O formato embutido tem a sintaxe:
![alt text](image-url "optional-title")
. - O formato de referência tem a sintaxe:
![alt text][id]
para a referência e[id]: image-url "optional-title"
para o rótulo da imagem. Ambos devem ser separados por pelo menos uma linha em branco. - O título da imagem é opcional e o URL da imagem pode ser relativo.
<!--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 interativo para aprender sobre imagens.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre Imagens.
Citações em bloco
O elemento HTML Block Quotation, <blockquote>, pode ser criado prefixando uma nova linha com o símbolo maior 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>
As citações em bloco podem ser aninhadas:
<!--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>
Eles também podem conter outros elementos Markdown, como cabeçalhos, código, itens de lista e assim por diante.
<!--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 interativo para aprender sobre blockquotes.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre Blockquotes.
Código
O elemento HTML Inline Code, <code>, também é suportado. Para criar um, delimite o texto com acentos graves (`), ou acentos duplos se for necessário haver um acento literal no texto anexo.
<!--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 interativo para aprender sobre código.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre períodos de código.
Blocos de código
O elemento de texto pré-formatado HTML, <pre>, também é suportado. Isso pode ser feito com pelo menos três e um número igual de back-ticks delimitadores ( `
), ou tils ( ~
) — normalmente referido como code-fence, ou uma nova linha iniciando recuo de pelo menos 4 espaços.
<!--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 interativo para aprender sobre código.
- Permalink do Dingus para conferir o exemplo completo com o Preview e o AST.
- Saiba mais sobre blocos de código cercados e recuados.
Usando HTML embutido
De acordo com a nota de especificação original de John Grubers sobre HTML embutido, qualquer marcação que não seja coberta pela sintaxe do Markdown, você simplesmente usa o próprio HTML, com As únicas restrições são que os elementos HTML em nível de bloco - por exemplo, <div>
, <table>
, <pre>
, <p>
, etc. — devem ser separados do conteúdo ao redor por linhas em branco, e as tags de início e fim do bloco não devem ser recuadas com tabulações ou espaços.
No entanto, a menos que você provavelmente seja uma das pessoas por trás do próprio CommonMark, ou por aí, você provavelmente escreverá Markdown com um sabor que já foi estendido para lidar com um grande número de sintaxes não suportadas atualmente pelo CommonMark.
Daqui para frente
O CommonMark é um trabalho constante em andamento com suas especificações atualizadas pela última vez em 6 de abril de 2019. Há vários aplicativos populares que o suportam no conjunto de ferramentas Markdown. Com a consciência do esforço do CommonMark em direção à padronização, acho que é suficiente concluir que, na simplicidade do Markdown, há muito trabalho acontecendo nos bastidores e que é uma coisa boa para o esforço do CommonMark que a especificação formal do GitHub Flavored Markdown é baseado na especificação.
A mudança em direção ao esforço de padronização do CommonMark não impede a criação de variações para estender sua sintaxe suportada e, à medida que o CommonMark se prepara para a versão 1.0 com problemas que devem ser resolvidos, existem alguns recursos interessantes sobre o esforço contínuo que você pode usar para seu leitura.
Recursos
- Apresentando Markdown por John Gruber
- Site oficial da CommonMark
- Especificações de Markdown com sabor do GitHub
- repositório oficial cmark
- Fork do cmark do GitHub
- Markdown na Wikipedia
- Guia de remarcação