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 navegador1) Escrever o ficheiro Markdown
Cria um .md em qualquer editor e escreve com a sintaxe Markdown:
# O meu documento
Este é um parágrafo **importante**.
## Exemplo de lista
- Item 1
- Item 2
- Item 32) Parsing pelo parser de Markdown
O parser lê o .md, reconhece elementos de sintaxe e converte para 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- itemcomo 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
| Parser | Linguagem | Características |
|---|---|---|
| marked | JavaScript | Rápido e leve |
| markdown-it | JavaScript | Pluginável, muito extensível |
| Python-Markdown | Python | Rico em funcionalidades |
| kramdown | Ruby | Suporta vários formatos |
| Pandoc | Haskell | Conversor universal |
Motores de renderização
Renderização no cliente
Parsing em tempo real no navegador:
// 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:
// 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:
# Com VitePress
npm run buildVantagens:
- 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:
// 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
// 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
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
// Processar apenas o que está visível
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
parseAndRender(entry.target);
}
});
});Processamento em stream
// 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:
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ágrafos2) HTML misto
Isto é **Markdown** com <em>HTML</em> misto.Atenção ao fecho e à aninhagem correta de etiquetas HTML.
3) Escape de caracteres
É necessário escapar os caracteres \* e \_.Aplicações práticas
1) Sistema de blogues
Artigo em Markdown → Gerador estático → Site HTML2) Site de documentação
.md → VitePress/Docusaurus → Documentação online3) Ficheiros README
README.md → GitHub/GitLab → Página do projeto4) Apps de notas
Notas em Markdown → Renderização em tempo real → Exibição rich textPróximos passos
Agora que compreendes o funcionamento do Markdown, podes: