Processamento de Markdown em TypeScript: bibliotecas, parsers e aplicação prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Trabalhando com Markdown em TypeScript: do parsing aos plugins personalizados

\n

O Markdown continua sendo uma das linguagens de marcação mais populares para documentação, blogs e plataformas educacionais. Ao desenvolver em TypeScript, surge a necessidade não apenas de exibir Markdown, mas também de gerenciar flexivelmente o processo de sua transformação. Neste artigo, abordaremos três bibliotecas principais que ajudarão você a integrar Markdown ao seu projeto TypeScript e mostraremos como criar suas próprias extensões.

\n\n

Por que o TypeScript é importante para trabalhar com Markdown?

\n

O TypeScript adiciona tipagem estrita, o que é crucial ao processar conteúdo do usuário. Você sabe exatamente quais dados vêm dos arquivos Markdown e pode evitar erros em tempo de execução. Além disso, o TypeScript simplifica a criação de plugins e middlewares para parsers.

\n\n

Visão geral das bibliotecas populares

\n
    \n
  • marked — o parser mais rápido e simples. Configuração mínima, excelente desempenho.
  • \n
  • unified / remark — ecossistema para análise sintática. Permite criar cadeias complexas de transformações (AST -> HTML -> React).
  • \n
  • showdown — uma alternativa leve com suporte a extensões, bem documentada.
  • \n
\n\n

Exemplo 1: Parsing básico com marked

\n

A biblioteca marked é ideal para um início rápido. Instale-a via npm:

\n
npm install marked
\n

Os tipos para TypeScript são fornecidos juntos. Exemplo de uso:

\n
import { marked } from 'marked';\n\nconst markdownContent = `# Olá, TypeScript!\nIsso é **texto em negrito** e `código`.\n- Item de lista\n- Mais um`;\n\nconst html = marked.parse(markdownContent);\nconsole.log(html);\n// Saída: <h1>Olá, TypeScript!</h1>\n// <p>Isso é <strong>texto em negrito</strong> e <code>código</code>.</p>\n// <ul><li>Item de lista</li><li>Mais um</li></ul>
\n

Para trabalho assíncrono, use marked.parseAsync(). Isso é útil ao carregar arquivos da rede.

\n\n

Exemplo 2: Renderizador personalizado com tipagem

\n

Às vezes, é necessário alterar o comportamento padrão. Por exemplo, adicionar classes a links ou processar imagens. Vamos criar um renderizador personalizado em TypeScript:

\n
import { marked, Renderer } from 'marked';\n\ninterface CustomRenderer extends Renderer {\n  link(href: string, title: string | null, text: string): string;\n}\n\nconst renderer: Partial<CustomRenderer> = {\n  link({ href, title, text }) {\n    return `<a href="${href}" target="_blank" rel="noopener noreferrer" class="external-link">${text}</a>`;\n  }\n};\n\nmarked.use({ renderer });\n\nconst markdown = 'Visite [PythonLib](https://pythonlib.ru)';\nconst result = marked.parse(markdown);\n// <a href="https://pythonlib.ru" target="_blank" class="external-link">PythonLib</a>
\n

O tipo Partial<CustomRenderer> garante que estamos sobrescrevendo apenas os métodos necessários.

\n\n

Exemplo 3: Trabalhando com AST através de unified e remark

\n

Se você precisa de controle total sobre a estrutura do documento, use unified e remark. Instalação:

\n
npm install unified remark-parse remark-stringify remark-html
\n

Exemplo de parsing em árvore sintática (AST) e vice-versa:

\n
import { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkStringify from 'remark-stringify';\nimport remarkHtml from 'remark-html';\n\nconst markdown = '# Título\\nIsso é **importante**.';\n\nconst file = await unified()\n  .use(remarkParse)      // Parsing para AST\n  .use(remarkStringify)  // De volta para Markdown (para verificação)\n  .process(markdown);\n\nconsole.log(String(file)); // Markdown original\n\nconst htmlFile = await unified()\n  .use(remarkParse)\n  .use(remarkHtml)       // Transformação                    

Recommendations