Motivation
This proposal is about making Markdown pipe tables legible without requiring special renderers – even when these tables provide rich information.
For the motivation, I would like to start off with a premise, recalling Markdown’s overriding design goal, which is about legibility of the source itself. For this, I quote directly from https://daringfireball.net/projects/markdown/:
The overriding design goal for Markdown’s formatting syntax is to make it as readable as possible. The idea is that a Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions. While Markdown’s syntax has been influenced by several existing text-to-HTML filters, the single biggest source of inspiration for Markdown’s syntax is the format of plain text email.
That is the whole reason to choose Markdown over HTML, LaTeX or an open word-processor format like .odt. I share this opinion, and I believe this is what made Markdown so popular.
Every construct in Markdown honors that promise, except for tables. When a paragraph, a list item, a block quote or a footnote carries more text than fits on one screen line, it can be broken across as many source lines as the author likes, so that the document stays within a readable width.
Tables are the sole exception. A table row must occupy exactly one line, no matter how long. As soon as a table carries real information rather than two-digit numbers, its rows run to two, three, four hundred columns, and the file stops being readable or editable in a text editor. Note that this is not a limitation of text editors. Soft-wrapping a long row only makes things worse, since it destroys the columns on screen. But most importantly, no macro (like one can define in advanced text editors like VS Code/Emacs/vim/Sublime/etc.) can fix it either, because there is no legal way to write a row over several lines. What is missing is the syntax, not the tools.
Where pipe tables come from
The original Markdown proposal had no tables at all. Pipe tables arrived later through PHP Markdown Extra and MultiMarkdown, imitating the way people already drew tables in plain-text email. Spaces were used to pad the columns so that they line up in the text editor. That padding serves no other purpose – renderers strip it – and exists purely so that anyone reading the raw file can recognize the columns. Readability was the entire point.
What the design assumed was short cells for occasional usage. Under that assumption it works perfectly, and there was no reason to think further. Then GitHub adopted pipe tables, and they became universal. It is important here to emphasize that GitHub’s is a very particular “consumer” of pipe tables: one author writes in text (however cumbersome this is when a long table does not fit on a single screen), and far more people read through a browser renderer, essentially none of whom ever look at the source of the table. This is a great asymmetry: one author in an editor, and up to millions of readers in a browser. In that economy an awkward source line is a rational trade, because one writer’s inconvenience is amortized across a million rendered views. For GitHub’s use case, the failure mode described above was therefore not significant, which plausibly explains why GitHub standardized pipe tables the way it did.
In this forum, the long-running thread about tables (Tables in pure Markdown, open since 2014) reflects the same emphasis several other users give to this topic.
In personal and technical documents – what I care about, and certainly many other users too – the ratio is not one writer in an editor to a million readers in a browser, it is roughly one to one. Often the writer is the reader, and there is nothing to amortize against. This is where most Markdown now lives: notes, internal documentation, files exchanged with colleagues, and where tables generated by language models, with prose-length cells, arrive daily. The asymmetry that justified the trade simply is not there, and what remains is a document you cannot read without a tool.
The need is not new, and not only about personal notes: @GrahamHannington described it here in 2016, working on z/OS with 80-byte records, where colleagues already keep plain-text tables with wrapped cells by hand (post). The case for extending the format is, however, more timely than ever, since LLMs have adopted Markdown as their preferred output format. Generative AI produces tables rich in information, and users often want to keep and further edit those tables in their own notes – which today is either very cumbersome in a text editor, or requires special writing and viewing tools.
The proposal below is an attempt to correct that asymmetry: make information-rich tables as easy to read and write as everything else in Markdown.
Proposal
A line inside a table whose first character is ┆ (U+2506) continues the row above instead of starting a new one.
|Item |Description |Value|
|-----|----------------------------------------|-----|
|col 1|cell with very long text, which needs to|1000 |
┆ ┆be wrapped over multiple lines. Like in ┆ ┆
┆ ┆this example. ┆ ┆
|col 2|another line |2000 |
|col 3|and yet another |3000 |
The interpretation is the obvious one: the three lines in the middle form a single row.
For anyone who cannot easily type a non-ASCII character, |~ is an exact alias:
|col 1|cell with very long text, which needs to|1000 |
|~ |be wrapped over multiple lines. Like in | |
The remaining delimiters of a continuation row (that is, all of them after the first) may be ┆, as in the first example, or plain |, as in the second.
Both markers carry the same mnemonic, and it is why the marker belongs at the start of the line rather than the end: in technical drawing, a break line (a squiggle across a part) means “cut short here, continues”. A dashed vertical rule says the same. Someone meeting either character for the first time, with no documentation, can guess that the row has not ended.
Reflowing to single-line rows
Converting between the two table formats
- table with multi-line rows
- table with single-line rows
is mechanical. Going from the multi-line form to the single-line one, the pieces of each cell are joined in order and separated by a single space – the same thing an editor does when it unwraps a paragraph.
A viewer or an exporter would do exactly this: it unwraps the table into single-line rows first and then runs its existing toolchain unchanged.
For whom is this proposal intended
CommonMark has so far stayed lean, and pipe tables are not part of it. I would of course welcome their adoption together with this extension, but I am aware that this is a long shot, since it would mean taking on the whole GFM table syntax at once. I would still not want to rule it out, if there is openness to it. It is even possible that the illegibility described above is part of the reason why tables never entered CommonMark: as they stand today, they break the design goal Gruber stated. If this proposal removes that obstacle, the main objection to bringing tables into CommonMark would fall away.
What I hope for from this thread is a discussion of the syntax itself. If it survives that discussion, the natural next step is support in the tools whose users actually read Markdown in an editor: Obsidian, VS Code, Emacs and Vim plugins, MarkText, Quarto, and the libraries beneath them: markdown-it, remark/micromark, Pandoc, Markdig, comrak.
If GitHub adopted it as well, that would be excellent. But GitHub is, by the asymmetry described above, the one consumer of Markdown that does not really suffer from this limitation, so it is not where I would expect the change to start.
What guided the design
- Gruber’s argument (legibility first). The point is a table that a human can read and write in a simple text editor. Everything else follows from that.
- Reversible. A short filter converts a wrapped table into a single-line one and back, so the syntax is usable with existing toolchains today.
- Nothing to disambiguate. Neither marker (
┆or|~) begins an existing construct in any Markdown flavor. - Identical rendering. A table written with continuation lines produces exactly the same HTML – or PDF, or any other output – as the same table written on single lines. Only the way the text is typed in the file changes, so no renderer needs to be modified.
- Focused scope (no other feature creeping in). No spans, captions, widths or extra header rows. Those would change what is rendered; this proposal does not.
- Alignment optional. Nothing depends on columns lining up, so tables typed into a proportional-font box still work.
Entering the ┆ character
- For anyone who cannot easily type it,
|~is an exact alias and needs no special input. - macOS: press Ctrl-Cmd-Space to open the Character Viewer and search for
2506. For
repeated use, enable the “Unicode Hex Input” keyboard layout and type Option+2506. - Linux: in GTK/IBus applications, press Ctrl-Shift-U, type
2506, then Enter. - Emacs:
C-x 8 RET 2506 RET. Vim: in insert mode,Ctrl-V u 2506.
In practice one rarely types the character by hand. Most editors can define a macro that wraps a table to a chosen width, inserts the markers, and unwraps it again. But a macro alone is not enough, and this is the heart of the proposal: anyone can invent a private convention and write such a macro today, and the result is a file no colleague can read. Markdown exists because a shared format is worth more than a private one; before it, everyone was already free to invent their own. What a macro cannot supply is agreement, and this is why we need this discussion forum.
Scope and earlier attempts
Something close to this has been proposed here several times, in this forum and elsewhere:
- Continuation lines marked with
:→ borrowed frompsql(the command-line client of the PostgreSQL database), which prints a wrapped cell by putting a colon where the column border would be. |~at the start of the line → @skystar0227, 2019. This is the spelling I am adopting here as the ASCII alias.- Dots as delimiters, written
|. text .|→ part of the same @aoudad design. - No marker at all, every following line simply continuing the row → @tin-pot, 2015.
- A trailing backslash at the end of the line → not a proposal but a working implementation: MultiMarkdown, and the
markdown-it-multimd-tableplugin with itsmultilineoption.
From what I understood reading through the old threads, none of them was rejected. My guess as to why they never landed is that each bundled wrapped cells into a larger design carrying row spans, column spans, captions, multiple header rows and column widths, and the discussion stalled each time on where to stop.
So the one thing I want to do differently is to propose nothing else. Row and column spans in particular are a separate matter: they change the rendered table, they are not what makes documents unreadable, and nothing here forecloses them later.
Compatibility
Existing parsers will render a continuation line as an ordinary row. That is a genuine break until editors and export libraries adopt the syntax, but the failure is mild: content that logically belongs to one row is displayed as several rows, and the document stays understandable. Anyone who cannot yet use an editor that supports the syntax can convert the file back to single-line tables before exporting. That conversion is simple enough to be offered as a small web page or a small CLI utility: paste the document in, get the single-line version back.
How gracefully it degrades depends on which of the permitted forms is used, since only the first delimiter has to carry the marker. A continuation line that still contains pipes,
|col 1|cell with very long text, which needs to|1000 |
┆ |be wrapped over multiple lines. Like in | |
or the same line written with the |~ alias, is read by a parser that knows nothing about this proposal as an ordinary row: each fragment lands in its proper column, and only the grouping into a single row is lost.
The form with ┆ in every position is the most readable one for a human, but it contains no pipe at all, and parsers disagree about such a line. The GFM spec makes it a row with a single cell (example 202), so the table survives. Pandoc’s gfm reader instead ends the table there, and every row after it falls out of the table into a paragraph. Until the syntax is supported, the forms that keep the interior pipes are therefore the safer choice for anyone who needs the document to work with today’s tools.
One further case is worth mentioning. With the |~ alias, a first cell whose text begins with ~ (e.g., a home path such as ~/.bashrc) would look like a continuation marker. Writing it as | ~/.bashrc settles it: the leading space is trimmed by renderers / viewers according to GFM spec, so the displayed table is unchanged.
Open question
- Should a continuation line be allowed after the header row, before the delimiter row? I would go for it: a long column name has exactly the problem this proposal is about, and wrapping it is the same mechanism applied to the header rather than an additional feature. That said, I do not want feature creep to block the proposal, so if this is a point of concern I would rather drop it.
I would be glad to hear objections, particularly from implementers.