A little help goes a long way. Find a tool/

Developer FIELD NOTES · 4 MIN READ

Markdown Tables: Syntax and How to Generate Them from Data

How Markdown table syntax works — header, separator, pipes — and how to turn CSV, tab, or space-separated data into a valid table.

A Markdown table is a fence made of punctuation: a row of cells wrapped in pipes, a line of dashes holding it up, and strict rules about who sits where. The syntax is easy to read and miserable to type — count the pipes wrong once and the whole table silently becomes a paragraph. That gap between "looks simple" and "is finicky" is exactly why generating tables from data you already have beats hand-building them.

The three parts of every table

A valid table needs exactly three things: a header row, a separator row, and the body rows. The separator is the part people underestimate — a line of at least three dashes per column, joined by pipes, is what tells the renderer "the lines above and below are table rows, not text". Take real data:

name,age,city
Alice,34,Portland
Bob,29,Austin

and the generated table is:

| name | age | city |
| --- | --- | --- |
| Alice | 34 | Portland |
| Bob | 29 | Austin |

Every cell gets its own padding spaces, and the separator uses one --- per column. Alignment variants exist — :--- for left, :--: for center, ---: for right — but the plain form renders left-aligned everywhere, which is the safe default when the goal is "table that works".

Choosing the delimiter

The generator splits your input before it builds anything, and the delimiter decides how. Comma is the default and matches what spreadsheets copy out. Tab matches what you get from pasting directly out of Excel or Google Sheets — a mode that saves you from a spreadsheet full of almost-invisible tab characters. Pipe and whitespace round it out; whitespace mode splits on any run of spaces or tabs, handy for column-aligned plain text. Cells are trimmed as they are split, so stray spaces around commas disappear into the padding the generator adds anyway. For the wider picture of where CSV comes from and why it is trickier than it looks, see How CSV Files Work.

The messy cases: ragged rows and hostile cells

Real data is not rectangular. If one row has fewer cells than the widest row, the missing cells are padded with empty strings so every output row has the same column count — a table renderer needs that symmetry. Two hazards come from the inside: a cell containing a pipe would break the table it lives in, so pipes in cell content are escaped as \|; and a literal newline inside a cell is flattened to a space, because a raw line break would end the row. Neither is magic — they are the minimum transformations that keep the output parseable as a table.

No header? Borrow one

Markdown tables require the separator row, and the separator only means "column boundary" when there is a header above it — so a table without a header is not a thing you can skip to. When you say the first row is data rather than labels, the generator invents placeholder headers Column 1, Column 2, … and shifts your real rows into the body. Feed it a\tb and 1\t2 as tab-delimited data with no header, and you get | Column 1 | Column 2 | on top and both of your rows below, intact. Rename the placeholders to real labels and the table is done.

Tables are the newest part of Markdown

Worth knowing: tables are not in the original Markdown grammar. They arrived as an extension (popularized by PHP Markdown Extra and GitHub Flavored Markdown) and are now near-universally supported, but strict CommonMark treats those pipe rows as plain text. That is why a table pasted into a renderer without table support looks like a wall of pipes. The full context of blocks, inline styles, and flavors is in Markdown Explained.

Try it yourself

Copy two rows out of a spreadsheet, paste them into the Markdown Table Generator, and switch the delimiter to tab — the table should build itself. Already have a Markdown table that is misaligned or missing its separator? The Markdown Table Formatter repairs existing tables rather than building new ones. And if the data you are tabling lives in JSON, the CSV to JSON Converter moves it between the two formats first.

Frequently asked questions

How is the table generator different from the table formatter?
The generator builds a new table from raw delimited data — CSV, tab-separated, or plain columns — and outputs valid Markdown. The formatter takes a Markdown table that already exists and repairs it: aligning pipes, normalizing spacing, adding a missing separator row. Build from data with the generator; tidy up existing tables with the formatter.
What happens if a cell contains a pipe?
A literal | would end the cell early and scramble the row, so pipes inside cell content are escaped as \| in the output. When the table is rendered, the escape disappears and the reader sees the pipe as text. Newlines inside cells are flattened to spaces for the same reason — a raw line break would start a new row.
What if my rows have different numbers of columns?
Ragged input is padded: every row is extended with empty cells until it matches the widest row, so the generated table has a consistent column count. Renderers need that symmetry; a table whose rows disagree on column count will not render as a table at all.
Which delimiters does the generator accept?
Four: comma (the default, matching what spreadsheets export), tab (matching what spreadsheets copy to the clipboard), pipe, and whitespace — the last splits on any run of spaces or tabs, which suits column-aligned plain text. Cells are trimmed as they are split, so stray padding spaces vanish.
Can I generate a table without a header row?
Markdown requires a separator row under the header, so a headerless table is not valid Markdown. If you mark your first row as data, the generator inserts placeholder headers Column 1, Column 2, and so on, and your real rows become the body. Rename the placeholders and the table is complete.