Skip to content

Como o Markdown funciona

Compreender o funcionamento do Markdown ajuda a tirar melhor proveito desta ferramenta. Aqui explicamos como o texto simples se torna um documento formatado.

Fluxo básico

O fluxo pode ser resumido assim:

Ficheiro Markdown (.md) → Parser de Markdown → Documento HTML → Renderização no navegador

1) Escrever o ficheiro Markdown

Cria um .md em qualquer editor e escreve com a sintaxe Markdown:

markdown
# O meu documento

Este é um parágrafo **importante**.

## Exemplo de lista

- Item 1
- Item 2
- Item 3

2) Parsing pelo parser de Markdown

O parser lê o .md, reconhece elementos de sintaxe e converte para HTML:

html
<h1>O meu documento</h1>
<p>Este é um <strong>parágrafo</strong> importante.</p>
<h2>Exemplo de lista</h2>
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

3) Renderização no navegador

O HTML é apresentado como documento formatado no navegador.

Como funciona o parser

Análise lexical

Primeiro, o texto é tokenizado:

  • # reconhecido como título
  • **texto** como negrito
  • - item como item de lista

Análise sintática

Depois constrói‑se a AST (árvore de sintaxe abstrata):

Documento
├── Título(nível1): "O meu documento"
├── Parágrafo
│   ├── Texto: "Este é um"
│   ├── Negrito: "parágrafo"
│   └── Texto: " importante."
├── Título(nível2): "Exemplo de lista"
└── Lista não ordenada
    ├── Item: "Item 1"
    ├── Item: "Item 2"
    └── Item: "Item 3"

Geração de HTML

Por fim, percorre‑se a árvore e gera‑se o HTML.

Parsers populares

CommonMark

  • Especificação padrão – uniformiza parsing
  • Definições rigorosas – reduz ambiguidades
  • Amplo suporte – adotado por vários parsers

GitHub Flavored Markdown (GFM)

Baseado no CommonMark, adiciona:

  • Tabelas
  • Risco
  • Listas de tarefas
  • Auto‑link
  • Blocos de código com linguagem

Outros parsers

ParserLinguagemCaracterísticas
markedJavaScriptRápido e leve
markdown-itJavaScriptPluginável, muito extensível
Python-MarkdownPythonRico em funcionalidades
kramdownRubySuporta vários formatos
PandocHaskellConversor universal

Motores de renderização

Renderização no cliente

Parsing em tempo real no navegador:

javascript
// Com marked.js
const html = marked.parse('# Hello World');
document.body.innerHTML = html;

Vantagens:

  • Sem processamento no servidor
  • Pré‑visualização imediata
  • Menos carga no servidor

Desvantagens:

  • Depende de JavaScript
  • SEO mais fraco
  • Carregamento inicial lento

Renderização no servidor

HTML gerado previamente no servidor:

javascript
// Exemplo em Node.js
const fs = require('fs');
const marked = require('marked');

const markdown = fs.readFileSync('document.md', 'utf8');
const html = marked.parse(markdown);

Vantagens:

  • Melhor SEO
  • Carregamento mais rápido
  • Não depende de JS no cliente

Desvantagens:

  • Custo no servidor
  • Cache mais complexo

Geração de sites estáticos

Pré‑geração de todas as páginas em build:

bash
# Com VitePress
npm run build

Vantagens:

  • Maior velocidade
  • Melhor SEO
  • Elevada segurança
  • Fácil de alojar

Desvantagens:

  • Suporte limitado a conteúdo dinâmico
  • Tempo de build mais longo

Mecanismos de extensão

Sistema de plugins

Muitos parsers suportam plugins:

javascript
// Exemplo de plugins em markdown-it
const md = require('markdown-it')()
  .use(require('markdown-it-footnote'))
  .use(require('markdown-it-deflist'))
  .use(require('markdown-it-abbr'));

Renderizadores personalizados

javascript
// Link com target=_blank
const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
  return `<a href="${href}" target="_blank">${text}</a>`;
};

Otimização de desempenho

Cache

javascript
const cache = new Map();

function parseMarkdown(content) {
  const hash = generateHash(content);
  if (cache.has(hash)) {
    return cache.get(hash);
  }
  
  const result = marked.parse(content);
  cache.set(hash, result);
  return result;
}

Lazy loading

javascript
// Processar apenas o que está visível
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      parseAndRender(entry.target);
    }
  });
});

Processamento em stream

javascript
// Parsing em stream para ficheiros grandes
const fs = require('fs');
const { Transform } = require('stream');

const markdownTransform = new Transform({
  transform(chunk, encoding, callback) {
    const html = marked.parse(chunk.toString());
    callback(null, html);
  }
});

fs.createReadStream('large-document.md')
  .pipe(markdownTransform)
  .pipe(fs.createWriteStream('output.html'));

Questões comuns

1) Quebras de linha

Parsers tratam quebras de forma diferente:

markdown
Linha 1
Linha 2        ← pode ser o mesmo parágrafo

Linha 1  
Linha 2        ← dois espaços forçam quebra

Linha 1

Linha 2        ← linha vazia separa parágrafos

2) HTML misto

markdown
Isto é **Markdown** com <em>HTML</em> misto.

Atenção ao fecho e à aninhagem correta de etiquetas HTML.

3) Escape de caracteres

markdown
É necessário escapar os caracteres \* e \_.

Aplicações práticas

1) Sistema de blogues

Artigo em Markdown → Gerador estático → Site HTML

2) Site de documentação

.md → VitePress/Docusaurus → Documentação online

3) Ficheiros README

README.md → GitHub/GitLab → Página do projeto

4) Apps de notas

Notas em Markdown → Renderização em tempo real → Exibição rich text

Próximos passos

Agora que compreendes o funcionamento do Markdown, podes:

Construído por www.markdownlang.com