Markdown table generator
Generate a Markdown table from CSV, TSV or JSON, or realign one you already have, with per-column alignment and CJK-aware padding. Runs in your browser.
Read as CSV. Nothing identified the input, so this is the fallback — pick a format above if it is wrong.
Column alignment
| city | country | population |
| --------- | ------- | ---------- |
| 東京 | Japan | 37400068 |
| Delhi | India | 28514000 |
| São Paulo | Brazil | 21650000 |Columns: 3 · rows: 3
Four inputs, one output
A Markdown table is easy to write and miserable to maintain. Adding one word to a cell knocks every pipe below it out of line, and putting a table together from data you already have — a query result, a spreadsheet export, an API response — means retyping it by hand. This tool takes the data in whatever shape you have it and returns a clean GitHub-Flavored Markdown table.
It reads four formats, and it tells you which one it decided on rather than deciding quietly:
- A Markdown table, so a table that has drifted out of alignment can simply be pasted back in and straightened.
- CSV, parsed to RFC 4180 — a quoted field may contain commas, quotes and even line breaks, and all of them survive.
- TSV, which is what you get when you copy a range out of a spreadsheet or a database client.
- A JSON array, either of objects (the keys become the columns) or of arrays (the first row becomes the header).
Detection looks for the most distinctive evidence first: a leading bracket can only be JSON, a row of dashes can only be a Markdown delimiter row, a tab in the first line can only be TSV. Comma-separated is what is left over, so it is reported as a fallback rather than a finding — if the tool had to guess, it says so, and the format picker overrides it.
The output is Markdown and only Markdown. Converting a table back out to CSV or JSON is a different job, and this site already has tools that do it; a second general-purpose converter would only compete with them and would make this page harder to explain.
A cell is padded by width, not by length
Lining up the pipes means padding every cell in a column to the same width, which requires knowing how wide a cell is. The obvious answer — count the characters — is wrong for most of the world's writing systems, and it is wrong in both directions.
A monospaced font is not one character, one column. A Chinese or Japanese ideograph, a kana, a Hangul syllable, a fullwidth Latin letter and almost every emoji are drawn at exactly twice the width of a Latin letter. A combining mark — an accent, a Hebrew vowel point, an Arabic diacritic — is drawn on top of the letter before it and takes no width at all. Pad by character count and a column of Japanese comes out visibly short while a column of accented text comes out long.
'日本語'.length // 3 UTF-16 code units
[...'日本語'].length // 3 code points
displayWidth('日本語') // 6 columns in the editorSo the padding is measured in display columns. The text is first split into grapheme clusters — what a reader counts as one character, so an emoji built from several code points joined together stays one unit — and each cluster is measured against the East_Asian_Width property from the Unicode Character Database. That property is the one thing a browser cannot answer for itself: JavaScript exposes category, script and case through regular expressions, but not this, so a small table of the wide ranges ships with the page. Everything else comes from the engine.
One category is deliberately treated as narrow. Unicode marks a set of characters — box drawing, some Greek and Cyrillic letters, several punctuation marks — as "ambiguous": wide in a legacy East Asian font, narrow everywhere else. A Markdown file is read in an editor with a Latin default, so they are counted as one column, which is what the terminals and editors you will open the file in do.
What a Markdown table cannot hold
The format has two hard limits, and real data runs into both. A cell cannot contain a bare pipe, because that is what separates cells; it has to be written as an escaped pipe. And a table row is a single line, so a cell cannot contain a line break at all — which a CSV field is perfectly entitled to have.
Both are rewritten, and every rewrite is reported with the number of cells affected and the position of the first one. That is the point: a tool that silently turns your two-line address into one line has damaged your data without telling you. A line break becomes a break tag by default, which is what GitHub, GitLab and most renderers show as a new line inside the cell; if your renderer strips HTML, switch it to a space instead.
A row that is longer than the header is the third case. GitHub-Flavored Markdown simply drops the extra cells, which loses data quietly. Here the table is widened instead, with empty header cells, and the mismatch is reported — an odd-looking header you can fix is better than a column you never find out about. A row shorter than the header is padded with empty cells and reported the same way.
Backslashes are handled with a little more care than most tools take. A backslash is only doubled where it could swallow the pipe that follows it: before a pipe in the text, or at the very end of a cell, where the delimiter comes next. Everywhere else it is left alone, so a Windows path in a cell stays readable instead of turning into a row of double backslashes.
Alignment lives in the delimiter row
The row of dashes under the header does two jobs. It is what makes the block a table at all, and its colons set each column's alignment: a colon on the left aligns left, a colon on the right aligns right, colons on both sides centre. Without a colon the renderer uses its own default, which is left in every implementation but is not the same thing as asking for left.
Each column gets its own control here, because that is how alignment is actually used — text to the left, numbers to the right, a status column centred. And when you paste a table that already has alignment, it is read out of the delimiter row and shown in those controls, so reformatting an existing table never quietly discards the work someone did on it.
The padding follows the alignment as well. A right-aligned column is padded on the left, so the source lines up the same way the rendered table will. Markdown ignores that whitespace entirely, which is exactly why it is free to use for making the source readable.
Padded or compact, and why right-to-left text is different
Padding is worth it in a document a person edits and costs something in a repository. Every cell that grows repads its whole column, so a one-word change shows up in the diff as a change to every row of the table. The compact form writes the narrowest legal table — no padding, three dashes per column — which keeps diffs to the rows that actually changed. Both render identically. The outer pipes at the start and end of each row are optional in GitHub-Flavored Markdown but required by some older renderers, so they are a switch rather than a decision.
Padding cannot work at all for a table containing Hebrew or Arabic, and the tool says so rather than pretending. The spaces are counted correctly, but an editor lays out a mixed line by the bidirectional algorithm: the right-to-left run is reordered, and the pipes around it move with it. The characters are in the right places and the pipes still do not appear to line up, because visual position and logical position are not the same thing in that line. Nothing can fix that, so when there is right-to-left text in a cell the tool reports it and suggests the compact form, where there is no alignment to be disappointed by.
For the same reason the Markdown output on this page is always shown left to right, even when you are reading the site in Hebrew or Arabic. It is source code, and source code has a direction of its own.
Where it runs
Everything happens in your browser. The table is parsed, measured and rebuilt on your own machine, and nothing you paste is uploaded, stored or logged — which matters, because the tables people need to reformat are usually query results and exports rather than public data.
Frequently asked questions
- Is my data sent to a server?
- No. The parsing, the width measurement and the output are all computed in your browser, and nothing you paste is uploaded or logged.
- How do I turn a CSV into a Markdown table?
- Paste it. The tool recognises comma-separated text, takes the first row as the header and returns an aligned Markdown table. Quoted fields containing commas, quotes or line breaks are handled correctly, and anything that had to be rewritten to fit the format is reported.
- Why is my table with Japanese or Chinese text still not aligned?
- Check the font. The padding assumes a monospaced font in which an ideograph is exactly twice the width of a Latin letter, which is what terminals and code editors use. In a proportional font, or one whose CJK glyphs are not exactly double width, no padding can line the columns up — use the compact form there.
- What happens to a line break inside a cell?
- It becomes a break tag by default, because a Markdown table row is a single line and cannot hold a real one. Switch it to a space if your renderer strips HTML. Either way the tool reports which cells it changed.
- Why does my row with extra cells add an empty column?
- Because the alternative is losing those cells. GitHub-Flavored Markdown drops anything past the header width, so the table is widened with empty header cells instead and the mismatch is reported. Delete the column or name it once you have seen what was in it.
- Should I use the padded or the compact form?
- Padded for a document people read and edit by hand — a README, a design note — because the source is legible. Compact for anything under version control where a table changes often: padding means one edited cell repads the whole column and shows up in the diff as every row changing.
- Do I need the pipes at the start and end of each row?
- GitHub-Flavored Markdown does not require them, and neither do most modern renderers. Some older parsers do, and they make a hand-edited table easier to read, so they are on by default and can be turned off.
- Why can the tool not align a table with Hebrew or Arabic?
- Because the editor reorders the line. Bidirectional layout places a right-to-left run in visual order, and the pipes around it move with it, so the padding is arithmetically correct and visually useless. The tool reports it and suggests the compact form rather than producing a table that looks broken.