Tables in pure Markdown


Just brainstorming:

| title: The Title | name: The Name | ph: The Phone | <-- this introduces a table and row names
---------- <- this introduces a new row
title: value1
name: value2
ph: value3
---------- <- another row

| <- indicates the end of the table

  • Still easy to read because you have column key in front of each value
  • No matter in which order cells are desrcribed (looks more like a JSON object)
  • Easy to maintain by using keys title, name, ph, so you can still easily add / remove columns


I thought I’d chime in; we use Markdown for public documentation, internal documentation as well as a quick way to keep notes. Being able to format table has come up fairly early in each case.

  • Tables are used as a way to show information, not a way to structure it (i.e. it’s not a database). As an example, if we create a feature list, me may have the feature ID, the component and the description. This can be shown in a bullet list but becomes very hard to read; it’s much better to create columns. It becomes much more human-readable.
  • The pain of maintaining Markdown tables is smaller than the advantages they bring. Anyway, most IDEs have multiple cursors, so adding/removing spaces on all rows is usually as easy as clicking on the last character of the first row you want to expand, Ctrl+Alt+Click on the last one, then add spaces.
  • Even though colspan, rowspan and cell alignment are very nice to have, allowing basic table formatting (creating columns, maybe headers) would still be much better than nothing.

And my humble opinion: if I ask someone to make a table using a basic text editor, I expect them to create it using pipes and dashes. Maybe I’m wrong. I think it also makes it more readable in pure text, which is a huge plus when comparing in Git. I agree CSV makes the writer’s life easier, but I’ll argue that if somebody decides to use Markdown, it’s because it’s as easy to read as it is to write.


Actually this would cause issues as soon as you need to resize a column. That sounds like a recipe for annoying, bogus merge conflicts.


I’m currently implementing python’s html2text feature, which converts html tables into markdown.
I added two options - insert table as html block and as GH Flavored M******n.
Here’s example output.
So I vote for Github table syntax be included into spec. As for me, tables are needed when you write content in text editor.


I find the kramdown full syntax quite handy since it supports header/footer.



I have a job need for tables and I am concerned that without them, this specification will have less support than it might (and make life harder for those that need tables where the spec is implemented).

As this is something relevant to my interests, I’ve started working on building up the ideas I have.

If enough people are interested, I’m willing to start work on the actual spec for the ideas below and submit them to the project.

Table Syntax Ideas

  1. Pipe delimited tables appear to be the most common implementation
  2. Support for colspan and rowspan are considered nice to have by many, but critical for those that need them
  3. Tables must be human readable
  4. Idea: Make the divider a double pipe to allow more command flexibility and enable formatting directives within the pipes
  5. The example should define the syntax
||            || Column Header One || Column Header Two || Column Header Three || if this line is followed by a line of ||--|| then it is a header, also, Row Headers are indicated by an optional *empty* A1 cell
||-----------:||:------------------||:-----------------:||--------------------:|| : to indicate default column alignment as per ME
||Row Hdr 1   ||Left Aligned||Centre Aligned||Right Aligned|| whitespace should not matter
||Row Hdr 2   |>|colspan the next cell                  ||Row 2, Col 3         || Merge the cells in Col1 and 2
||Row Hdr 3   |>>|colspan the next two cells                                   || Merge the cells in Col1, 2, and 3
||Row Hdr 4   |v|rowspan the next cell down||           || Column 3            || rowspan on col1 and an empty cell
||Row Hdr 5   ||                   || Column 2          || Column 3            ||
||Row Hdr 6   |vv|merge down 2     |>| Merge right                             ||
||Row Hdr 7   ||                   || Column 2         :||: Column 3           || Row7 Col2 RAlign, Col3 LAlign (in exception to column default)
||Row Hdr 8   ||                   || Column 2         :||: Column 3           ||
  • This should produce something like the following (Yes css folks would create this differently, I just wanted to give people an idea of what the rendered table should resemble):
    <table border="2" width="0">
        <th></th><th>Column Header One</th><th>Column Header Two</th><th>Column Header Three</th>
    	<td align="right">Row Hdr 1</td><td align="left">Left Aligned</td><td align="center">Centre Aligned</td><td align="right">Right Aligned</td>
    	<td align="right">Row Hdr 2</td><td colspan="2" align="left">colspan the next cell</td><td align="right">Row 2, Col 3</td>
    	<td align="right">Row Hdr 3</td><td colspan="3" align="left">colspan the next two cells</td>
    	<td align="right">Row Hdr 4</td><td rowspan="2" align="left">rowspan the next cell down</td><td align="center"></td><td align="right">Column 3</td>
    	<td align="right">Row Hdr 5</td><td align="center">Column 2</td><td align="right">Column 3</td>
    	<td align="right">Row Hdr 6</td><td rowspan="3" align="left">Merge Down 2</td><td colspan="2" align="center">Merge Right</td>
    	<td align="right">Row Hdr 7</td><td align="right">Column 2</td><td align="left">Column 3</td>
    	<td align="right">Row Hdr 8</td><td align="right">Column 2</td><td align="left">Column 3</td>


Relevant xkcd

I don’t think it is a good idea to implement another table syntax in stmd. There is already a widely used table syntax which is the one that i.e. github is using. Everybody knows it and most people want exactly this. So I think the best idea is to implement this syntax in stmd and implement all your crazy table ideas in separate plugins.

I mean the whole idea of a standard is to describe what most of the people do anyways. So there should be no space for any new and fancy ideas. Thats not what a standard should be used for.


Possibly adding the footer/header support as implemented in markdownextra/kramdown for making it a little nicer than the github variation.


Tables are a widely used item and would be nice to have in the core feature set. Reading through all the replies, I did not see any mention of a style I have encountered with Atlassian products. I find this to be simpler and easier to read. It allows for header styles to be used for any cell and reduces the typing. This is my modified version to include alignment functionality and column spanning.


  • Tables must be surrounded by blank lines
  • Pipes initiate a table cell until another separate pipe is encountered or white space (including new lines)
  • Cell modifiers follow directly after the | and before the first white space.
  • A space or tab must separate a pipe and its modifiers from the content.


  • Format: |m - single pipe starts a cell followed directly by its modifiers
  • (m)odifiers:
    • | - make cell a header
    • < - left align cell
    • = - center align cell
    • > - right align cell
    • # - number of cells to span


||< th left aligned ||= th center aligned ||> th right aligned
|< td left aligned |= td center aligned |> td right aligned
|| th |<2 td with a cell span of 2 left aligned
| td ||2 th with a cell span of 2
| |2 blank cells require a space between the pipes when there are multiple columns or just the pipes when alone.

If you are one who likes everything aligned, then it supports that as well by trimming.

||< th left aligned ||= th center aligned ||> th right aligned
|<  td left aligned |=  td center aligned |>  td right aligned
||  th              |<2 td with a cell span of 2 left aligned
|   td              ||2 th with a cell span of 2
|                   |2  blank cells require a space between the pipes when there are multiple columns or just the pipes when alone.

I like this because it does not require extra spacing, dashes, or lines, but has support for advanced table formatting if one likes. And the parser just has to identify the pipe and any trailing modifiers till the next white space (including line feeds) character.

Example Output:

	<th align="left">th left aligned</th>
	<th align="center">th center aligned</th>
	<th align="right">th right aligned</th>
	<td align="left">td left aligned</td>
	<td align="center">td center aligned</td>
	<td align="right">td right aligned</td>
	<td align="left" colspan="2">td with a cell span of 2 left aligned</td>
	<th colspan="2">th with cell span of 2</th>
	<td colspan="2">blank cells require a space between the pipes when there are mu    ltiple columns or just the pipes when alone.</td>
	<td colspan="3"></td>
	<th colspan="3"></th>

Anyway, just wanted to contribute my thought for others to see.


I think a simple table syntax would be really nice to include. It’s common enough to get its own syntax, especially as the html equivalent is really horrible! And there are already M6N implementations out there which have support for some kind of table syntax.

There are some interesting suggestions here, but I would try to keep it really simple. Just enough to get some cells in a grid, no fancy alignment, column/row spans, or anything to get different “styles”. If you need ‘fancy’ tables, I think you should either use html tables or even a different document format. Or maybe an extension, but CommonMark should keep it simple and adhere to the original principles and ideas, that a M6N document should read well in plain text.

So I would like to see something along the lines of what @espadrine suggested in the first post or @jgm defined in pandoc.


agreed, as long as this simplified form is also supported:

 Header  | Another header 
 field 1 | something      
 field 2 | something else


Table caption
Column 1 | Column 2 | Column 3 | Column 4
1        | 2        | 3        | 4
five     | six      | seven    | eight
9        | 10       | 11       | 12
thirteen | fourteen | fifteen  | sixteen



One issue with tables is how they look on devices with smaller screens (e.g. smartphones). Whereas code blocks can be wrapped and large images can be swapped out with smaller resolution images, tables are difficult to shrink without becoming hard to read. With this in mind, I’m glad that tables are an extension as there are sometimes better ways of listing the same data in a reflowable way.

If tables are to be used, the Typify Markup syntax looks good.


github/markdown-extra/kramdown do support a quite rich table syntax that is widespread and regular, why focusing on a new markup? The extra “table caption” feature seems wrong to me.


The HTML5 spec explains how captions might be used. I think captions could be a worthwhile feature. Otherwise the Typify Markup syntax is very similar to the syntax in Markdown flavours which include tables.


As long there is consensus and that part could be set in stone I’d be happy:

header+footer+caption and matching the typify/markdown-extra/kramdown general markup?


I am a bit concerned with some talk in this topic of aligning column information to the left or right (with colons on the second line to mark alignment). This is a presentational feature which belongs in CSS. Or if the writer types numbers in a column, the parser could be smart enough to align the contents of the column to the right (if that is indeed the requirement) by adding a CSS class automatically.

Side Thoughts: Promoting pipe tables as a potential alternative to .CSV format (e.g. .PSV ?)

I also think that CommonMark must have tables. Markdown is great but I was always bored that tables were not part of the specifications.


@hftmarkand Tables, strikethrough and other features will likely be considered as CommonMark extensions once the core spec is complete. The core spec is intended just to be the features found in the original Markdown spec, which excludes tables. See this discussion for more details.


@chrisalley that would be sad, if improving markdown ten years later, I would expect to have all the non-standard markdown features as commonmark core features.

If not, we will still have dozens of extensions implemented or not…


The main idea is that you have core+extensions implemented in the reference implementation. But you need to sort your priorities.

  • get the core commonmark features rock solid (takes some time but not much discussion anymore)
  • get the most wanted extension ironed out (takes lots of discussion to get full agreement)