Ir para o conteúdo
OneKitly

Construir uma tabela Markdown de raiz, sem contar travessões à mão

Publicado a 30/07/2026 · 13 min de leitura · Ferramentas para programadores

Daniel Okonkwo

Daniel OkonkwoProgramador front-end e redator de Tecnologia na OneKitly

Desempenho web · Formatos de ficheiro

Verificado a partir de 4 fontes

Ver perfil
Em resumo

A tabela Markdown mínima válida são duas linhas, não três: uma linha de cabeçalho e uma linha delimitadora por baixo. | Nome | Papel | seguido de | --- | --- | é uma tabela do GitHub completa e válida, com cabeçalho e sem corpo — a especificação di-lo explicitamente, e o HTML que produz simplesmente não tem tbody. O que não pode fazer é omitir a linha delimitadora. Uma linha de cabeçalho sozinha é um parágrafo com barras dentro, e aparecerá como texto literal. Essa fila não é adorno nem açúcar de alinhamento: em GitHub Flavored Markdown é o sinal que transforma um parágrafo comum numa tabela, e por isso é obrigatória aqui, ao passo que motores com outra sintaxe de tabelas não precisam dela. Daí saem duas regras. A linha delimitadora tem de ter exatamente tantas células como o cabeçalho, ou a tabela não é reconhecida de todo. E qualquer outra fila pode ter o número de células que for: a menos, são inseridas células vazias; a mais, o excesso é descartado. As barras do início e do fim são facultativas — a especificação recomenda-as por clareza — e os espaços que alinham as colunas não afetam o resultado em nada. As tabelas de barras não fazem parte do CommonMark. A especificação central, versão 0.31.2, define blocos folha e blocos contentor e não contém construção de tabela nenhuma; as do GitHub são uma extensão por cima. Uma tabela perfeita num pull request pode portanto sair como texto cru num processador CommonMark estrito, e o Markdown original de 2004 também não tinha tabelas. Antes de escrever uma, veja que motor a vai ler.

A coisa mais pequena que ainda é uma tabela são duas linhas: uma linha de cabeçalho e uma linha delimitadora. Aqui está porque é que a segunda é obrigatória em GitHub Flavored Markdown, onde as tabelas de barras não existem de todo, e o que um gerador faz que escrever à mão não consegue.

A coisa mais pequena que ainda é uma tabela

Escreva uma linha no gerador — Nome,Papel — e ele produz duas: | Nome | Papel | em cima, | --- | --- | por baixo. É a tabela toda. Tem cabeçalho, nenhuma fila de dados, e é válida: a especificação do GitHub Flavored Markdown inclui um exemplo exatamente com esta forma e nota apenas que não é gerado nenhum elemento tbody no HTML. Não falta nada. Se isso é útil é outra questão, mas a sintaxe está completa.

Agora apague a segunda linha e não tem nada. Uma linha de cabeçalho sozinha é um parágrafo que contém barras verticais, e qualquer motor GFM vai imprimi-lo como tal: Nome | Papel, em texto, barras incluídas. É a causa número um de uma tabela escrita à mão falhar, e a razão é estrutural e não estilística. Um analisador Markdown decide o que é um bloco olhando para como começa. Um cardinal faz um título, um sinal de maior uma citação, quatro espaços código. Um parágrafo com barras podia ser qualquer coisa: um encadeamento de shell, uma tabela de verdade, um pedaço de prosa sobre probabilidade. A linha delimitadora é a única coisa que diz ao analisador que aquele parágrafo é uma tabela, e não há forma de o deduzir sem ela.

O gerador não pode esquecê-la, e é aí que está quase todo o valor de usar um. Constrói o cabeçalho, a linha delimitadora e cada fila de dados a partir de uma única contagem de colunas, por isso as três nunca podem divergir. Dê-lhe um cabeçalho sem corpo e produz a tabela de duas linhas. Desligue o interruptor de «a primeira linha é o cabeçalho» e ele inventa Coluna 1, Coluna 2 e assim por diante, porque a sintaxe não tem forma sem cabeçalho e inventar nomes é a única coisa honesta que resta. Dê-lhe filas de comprimento desigual e ele quadra-as, enchendo as curtas com células vazias e dizendo-lhe, por cima do resultado, quantas filas teve de preencher.

Onde a tabela de barras simplesmente não existe

O Markdown tal como John Gruber o publicou em 2004 não tem tabelas. Leia o documento de sintaxe original e vai encontrar títulos, citações, listas, blocos de código, linhas horizontais, ligações, ênfase, imagens e HTML em linha — e nada sobre colunas. As tabelas nunca lá estiveram, e a saída de emergência que o documento oferece para tudo o que não cobre é escrever HTML cru.

O CommonMark, o esforço para dar ao Markdown uma especificação sem ambiguidades, não as acrescentou. A versão 0.31.2, de janeiro de 2024, define blocos folha — linhas temáticas, títulos, blocos de código, blocos HTML, parágrafos — e blocos contentor — citações, itens de lista, listas — e não há secção de tabelas. A própria especificação reconhece que alguns dialetos estenderam a sintaxe original com convenções para notas de rodapé e tabelas, o que coloca as tabelas claramente fora do núcleo. As do GitHub vivem num documento à parte, a especificação GFM, sob o título Tables (extension).

A consequência prática é que o sítio onde a sua tabela renderiza depende das extensões que o processador tem ligadas, e não do Markdown enquanto tal. Um README de repositório no GitHub é seguro. Um gerador de sites estáticos, uma compilação de documentação, um cliente de chat, uma caixa de comentários num gestor de bugs: cada um é uma decisão separada de quem o montou. Se o destino conta, o teste de dois minutos é colar lá a tabela mínima de duas linhas e olhar. Se aparecer como tabela com uma linha de cabeçalho, a extensão está ligada e o resto vai funcionar; se aparecer como uma linha de texto com travessões por baixo, escreva o HTML em vez disso, ou use uma lista.

O que o gerador conta e tu não consegues

A linha delimitadora tem um piso de três carateres, e não é arbitrário: :-: é a célula mais curta que ainda consegue levar um marcador de alinhamento em cada ponta. O gerador aplica esse piso a cada coluna, por isso um cabeçalho de uma letra sai como | a | sobre | --- |, nunca sobre | - |. Também calcula a largura de cada coluna a partir da célula mais larga dessa coluna, cabeçalho incluído, que é a aritmética que ninguém quer fazer à mão numa tabela de doze filas.

O interessante é como mede uma célula, porque um carácter não é uma coluna. Este gerador conta colunas de ecrã, não carateres: os ideogramas 東京 são dois carateres e ele conta quatro, um é escrito como e mais acento combinante são dois carateres e ele conta um, um emoji solto são duas unidades UTF-16 e ele conta duas. Contar carateres é o que faz um gerador ingénuo, e desalinha a fonte assim que os dados saem do alfabeto latino. O emoji de família é o caso que apanha os contadores ingénuos: quatro figuras soldadas por juntores de largura zero, sete pontos de código, onze unidades UTF-16 e um só glifo de duas colunas. Este gerador anuncia dois, porque um juntor de largura zero não ocupa coluna nenhuma e tira a sua ao ponto de código que o segue. Nada disto chega à tabela renderizada — o enchimento existe para que a fonte fique alinhada num editor, e é o único sítio onde pode estar certo ou errado.

Existe um modo compacto que desliga o alinhamento por completo. Com ele, a separadora mantém os seus três carateres — | :-- | :-: | --: | para esquerda, centro e direita — e qualquer outra célula é escrita sem enchimento nenhum. É a definição que quer para uma tabela larga num ficheiro versionado, porque uma tabela alinhada refaz a coluna inteira assim que um valor se alonga, e uma correção de uma palavra transforma-se num diff que toca todas as filas.

Editar uma tabela que já tem

O gerador aceita como entrada uma tabela Markdown já existente, que é a forma mais rápida de acrescentar uma coluna ou corrigir uma gralha sem realinhar nada. Cole a tabela: o separador é detetado como a barra, as células vazias do início e do fim são retiradas, a fila de travessões é reconhecida e descartada, e o que resta é a sua grelha. As barras com escape sobrevivem à viagem: uma célula a dizer ps \| grep é desescapada para ps | grep à entrada e reescapada à saída, por isso a tabela volta idêntica e não uma coluna mais larga. O conversor de CSV deste site fecha o mesmo círculo pela sua própria ponta: faz o escape da contrabarra antes da barra, por isso uma célula que já levava \| sobrevive a nova conversão.

O alinhamento também sobrevive à viagem, o que é menos óbvio do que parece, porque a fila que o transporta é precisamente a que tem de ser deitada fora. A ferramenta lê os dois pontos da fila separadora antes de a filtrar — :--- à esquerda, ---: à direita, :---: ao centro, um --- sozinho não diz nada — e arranca a definição de cada coluna com o que leu. Cole uma tabela cuja regra seja | :--- | ---: | e a coluna de números alinhada à direita volta alinhada à direita. O que define à mão continua a mandar: os seletores por coluna e os botões Predefinido, Esquerda, Centro e Direita por cima da tabela sobrepõem-se ao que foi lido, por isso pode mudar um alinhamento de propósito. O que já não pode é perder um sem dar por isso.

Cada parte de uma tabela GFM: o que é, se é obrigatória, e o que acontece quando está errada
ParteObrigatória?O que acontece se faltar ou estiver errada
Linha de cabeçalhoSimNão existe forma sem cabeçalho; o gerador inventa Coluna 1, Coluna 2 em vez de a omitir
Linha delimitadora de travessõesSimNenhuma tabela — o cabeçalho aparece como parágrafo com barras
Contagem de células delimitadoras igual ao cabeçalhoSimA tabela não é reconhecida e cai para texto literal
Filas de dadosNãoCabeçalho mais separadora é uma tabela válida; o HTML simplesmente não tem tbody
Contagem de células numa fila de dadosNãoA menos, são inseridas células vazias; a mais, o excesso é ignorado
Barras do início e do fimNãoFacultativas; a especificação recomenda-as por clareza e para evitar ambiguidade de análise
Espaços de alinhamentoNãoNenhum efeito no resultado; existem para que um humano leia a fonte
Uma linha em branco dentro da tabelaNuncaA tabela corta-se na primeira linha vazia ou ao começar outro bloco
Gerador de tabelas MarkdownCole CSV, TSV ou dados com ponto e vírgula e obtenha uma tabela Markdown alinhada, com alinhamento por coluna, escape dos | e pré-visualização em direto.Experimentar a ferramenta

Perguntas frequentes

Qual é a tabela Markdown válida mais pequena?
Duas linhas: uma linha de cabeçalho e uma linha delimitadora por baixo. | Nome | sobre | --- | é uma tabela completa com uma coluna, uma célula de cabeçalho e sem corpo, e a especificação GFM inclui um exemplo exatamente assim, notando apenas que não aparece nenhum elemento tbody no HTML. Não se pode ir mais pequeno. Não existe tabela de uma linha, nem forma de ter filas de dados sem cabeçalho: se os seus dados não têm cabeçalho natural, o gerador escreve Coluna 1, Coluna 2 e por aí fora, que é o que a sintaxe impõe. A célula delimitadora mais pequena são três carateres, porque :-: é a forma mais curta que ainda leva um marcador de alinhamento nas duas pontas.
Porque é que o GitHub precisa da fila de travessões quando outros motores não precisam?
Porque uma barra vertical não significa nada em Markdown. Qualquer outra construção de bloco anuncia-se com um carácter no início da linha — cardinal, sinal de maior, travessão, um número seguido de ponto — mas uma linha com barras é indistinguível da prosa. A sintaxe de tabelas do GitHub resolve isso exigindo uma segunda linha cujas células só contenham travessões e dois pontos facultativos, algo que nenhum parágrafo produziria por acidente. Os motores com outra sintaxe de tabelas não têm esse problema porque marcam as tabelas de outra maneira: alguns wikis usam um símbolo de abertura próprio, e formatos como o reStructuredText desenham a tabela com uma grelha de carateres. A exigência decorre da notação, não é uma regra que o GitHub tenha inventado por severidade.
Posso fazer uma tabela sem cabeçalho?
Na sintaxe, não. A primeira fila é sempre o cabeçalho, e a linha delimitadora fica sempre por baixo, por isso uma tabela sem cabeçalho não se pode exprimir. O gerador resolve isso inventando nomes — Coluna 1, Coluna 2 — quando desliga o interruptor de «a primeira linha é o cabeçalho», o que é um compromisso e não uma solução. Duas alternativas se o cabeçalho não tiver mesmo conteúdo: dê às colunas células vazias, o que é legal e aparece como fila de cabeçalho vazia no GitHub, ou escreva a tabela em HTML e retire o thead por completo. O truque do cabeçalho vazio costuma ficar melhor do que os nomes inventados, e está a uma edição de distância de qualquer um dos dois.
A minha tabela aparece no GitHub mas não no meu site de documentação. Porquê?
Porque as tabelas são uma extensão e a sua compilação de documentação não a ativou. O CommonMark 0.31.2 não tem construção de tabela nenhuma, por isso qualquer processador que implemente a especificação central e mais nada vai tratar a sua tabela como três parágrafos vulgares. As tabelas do GitHub vivem num documento à parte, sob o título Tables (extension). A maioria dos geradores de sites estáticos suporta-as, mas esse suporte é um plugin ou uma opção de configuração, não um dado adquirido. Verifique a configuração de Markdown da compilação, procure uma opção GFM ou de tabelas de barras, e se não houver, acrescente o plugin ou recorra a uma tabela HTML, que qualquer motor que permita HTML em linha mostrará bem.
Se colar outra vez uma tabela para a editar, mantém o alinhamento?
Sim. A fila separadora continua a ter de ser removida — senão os travessões chegavam como uma fila de dados —, mas os dois pontos são lidos antes e passam a ser o alinhamento inicial de cada coluna: :--- volta como :---, ---: como ---:, :---: como :---:, e um --- sozinho fica sozinho. As quatro formas do GFM fazem a ida e volta. O resto da viagem também é fiel: as células vazias das pontas são retiradas, e um \| com escape é desescapado à entrada e volta a levar escape à saída, por isso uma célula ps \| grep não se transforma em duas colunas. O que escolher continua a sobrepor-se ao que foi lido: escolha um alinhamento no seletor de uma coluna, ou um dos botões por cima da tabela, e ganha o seu. É a ordem pretendida: a tabela colada propõe, a sua definição dispõe.

Artigos que podem interessar-lhe

Todos os guias
GuiaColar uma tabela num pull request: o que parte, e os dois carateres que partem tudoUma tabela Markdown proíbe exatamente dois carateres dentro de uma célula: a barra vertical e a quebra de linha. Aqui está o que cada um faz, como um conversor os trata, porque é que o escape tem de ser aplicado na ordem certa, e porque é que o alinhamento da fonte nunca conta.TutorialMarkdown: guia para principiantesFormate texto simples com alguns símbolos: # para títulos, ** para negrito, - para listas. Eis o que é markdown, a sintaxe básica, porque está em todo o lado e os truques.GuiaTranspor uma tabela cujas linhas deviam ter sido colunasO que acontece à linha de cabeçalho, às linhas de comprimento desigual, aos tipos — e a única coisa com que transpor é regularmente confundido e que não consegue fazer.GuiaAs listas de tarefas em Markdown e o que se apresenta realmente em cada sítioAs listas de tarefas não estão no CommonMark. São uma extensão do GitHub Flavored Markdown, e por isso o mesmo ficheiro mostra caixas num sítio e parênteses retos literais noutro. A regra exata do marcador, o que faz o aninhamento e uma tabela do que é CommonMark, do que é GFM e do que não é nenhum — verificado contra ambas as especificações e quatro motores de apresentação.ExplicaçãoContagem de palavras: tempo de leitura e limitesUma contagem de palavras são palavras separadas por espaços. Eis como se conta, porque existem limites, como se traduz em páginas e tempo de leitura, e quando contam os caracteres.GuiaEmbelezar ou minificar: para que serve cada um e o que faz ao pesoQuatro folhas de estilo reais passadas pelo minificador, medidas em bruto e depois de gzip. Retirar todos os espaços poupou 48, 103, 104 e 147 bytes comprimidos; retirar os comentários, 57, 1 358, 2 420 e 1 042. E as cinco entradas que este minificador parte.

Ferramentas relacionadas

Isto descreve como se comportam um formato de ficheiro e um motor de renderização, verificado face à especificação citada e ao código da ferramenta tal como está hoje. Os motores divergem: GitHub, GitLab, um gerador de sites estáticos e a pré-visualização do seu editor são quatro implementações diferentes, e o que funciona numa pode não funcionar noutra. Nada aqui é uma garantia sobre a sua cadeia de publicação — teste o resultado onde ele vai mesmo ser publicado, e trate qualquer ferramenta, esta incluída, como algo a verificar e não a acreditar.

Fontes

Detetaste um erro neste artigo?