Tables in pure Markdown


#117

Well, according to BabelMark, pipe tables are implemented by:

  • pandoc 1.19.2
  • RDiscount 2.1.7
  • MD4C 0.2.2
  • PHP Markdown Extra 1.2.8
  • s9e\TextFormatter (Fatdown/PHP)
  • kramdown 1.2.0
  • cebe/markdown GFM 1.1.1
  • cebe/markdown MarkdownExtra 1.1.1
  • showdown (flavor: github) 1.6.4
  • Maruku 0.7.3.beta1
  • Maruku (Math-Enabled) 0.7.3.beta1
  • Blackfriday
  • Earmark 1.1.1

These ones also support pipe tables, but Babelmark doesn’t turn it on:

Out of the ones that don’t implement pipe tables, these ones have no support for tables at all:

  • commonmark 0.27.0
  • Markdown.pl 1.0.1
  • cheapskate 0.1.0.5
  • pandoc (strict) 1.19.2 (It works in non-strict mode, see above)
  • Markdown.pl 1.0.2b8
  • lunamark 0.4.0
  • PHP Markdown 1.0.2 (It works in Extra mode, see above)
  • MD4C (strict) 0.2.2 (It works in non-strict mode, see above)

These ones support tables, but not pipe tables:

  • Gambas 3.8.90

#118

Basically. pipe tables are the most common? The reason pipe tables aren’t implemented in some is because they are following commonmark spec?

How difficult would you say implementing pipe tables would be?


#119

Some of them don’t want to implement anything outside of Markdown.pl, which doesn’t support tables. Others don’t want to support anything outside of CommonMark, yes.

This hard


#120

Around 180 lines of code, excluding tests. Plus its already written. plus it isn’t dependent on regex.

Stylistically. I am for pipe tables.

mediawiki is really its own beast.

Let us also not forget that pipe tables are human-readable in plain text form already, which I think is almost the most important part.

It’s not easy to maintain. (except if someone can prove me wrong.) but its very readable.

Another thing we’d have to decide on is whether to be strict about the markdown or not.


#121

Hello,

  1. For the same reason why **text** better than <b>text</b>
  2. Too many <td></td>, <tr></tr> it is unusable, I want to get it easy in markdown.

@zzzzBov, your answers about:

Here you right, we can create self implemintation, but I think that mediawiki markup syntax can serve as a good practices for to do this.
Nevertheless, the main reason was:

Ok, go next:

This is wrong, I am worked with markdown too much. But just now I forced to use mediawiki markup for one project.
I was surprised at how it laconic and simple for creating tables, unlike markdown.
Using markdown I try in every possible way to avoid the use of tables.
Here are the main reasons, I will describe why it so below.

OK, but what about this |:-------|-------:|------:| ?

I think it is main problem of curent markdown tables implementation.

For example this table:

What if I needed to add some new Item with long name? We have two cases here:

  1. It will be broken:
@@ -2,5 +2,6 @@
 |:-------|-------:|------:|
 | Orange |     10 |  7.00 |
 | Bread  |      4 |  3.00 |
+| Super Snickers |       1 |   1.00 |
 | Butter |      1 |  5.00 |
-| Total  |        | 15.00 |
+| Total  |        | 16.00 |
  1. Or we need to reformat ALL the table:
@@ -1,6 +1,7 @@
-|  Item  | Amount |  Cost |
-|:-------|-------:|------:|
-| Orange |     10 |  7.00 |
-| Bread  |      4 |  3.00 |
-| Butter |      1 |  5.00 |
-| Total  |        | 15.00 |
+|  Item          | Amount |  Cost |
+|:---------------|-------:|------:|
+| Orange         |     10 |  7.00 |
+| Bread          |      4 |  3.00 |
+| Super Snickers |      1 |  1.00 |
+| Butter         |      1 |  5.00 |
+| Total          |        | 16.00 |

Yes, you can try to use pre allocated space for changes. But it’s never possible to know for sure how many space you will needed. And sooner or later it will break.
Add here the text formatting inside the cells and get the real hell on the wheels.

Yes, this is acceptable for small tables, but what if you need to make a big one?

Here is markdown example:

| Server | IP | Description |
|-|-|-|
| cl1 | 192.168.100.1 | This is my first server in the list |
| cl2 | 10.10.1.22 | This is another one server |
| windows-5BSD567DSLOS | 127.0.0.12 | This is customer windows vm. dont touch this!  |
| DFHSDDFFUCKENLONGNAME | 192.168.1.50 | Some printer |
...

Same but in mediawiki syntax:

{|
| Server
| IP
| Description
|-
| cl1
| 192.168.100.1
| This is my first server in the list
|-
| cl2
| 10.10.1.22
| This is another one server
|-
| windows-5BSD567DSLOS
| 127.0.0.12
| This is customer windows vm. dont touch this!
|-
| DFHSDDFFUCKENLONGNAME
| 192.168.1.50
| Some printer
...
|}

And this table may be very long.

Which format is more readable here?

In addition it more applicable for tracking changes in git:

@@ -12,7 +12,7 @@
 | This is another one server
 |-
 | windows-5BSD567DSLOS
-| 127.0.0.12
+| 127.0.0.13
 | This is customer windows vm. dont touch this!
 |-
 | DFHSDDFFUCKENLONGNAME

unlike markdown:

@@ -2,6 +2,6 @@
 |-|-|-|
 | cl1 | 192.168.100.1 | This is my first server in the list |
 | cl2 | 10.10.1.22 | This is another one server |
-| windows-5BSD567DSLOS | 127.0.0.12 | This is customer windows vm. dont touch this!  |
+| windows-5BSD567DSLOS | 127.0.0.13 | This is customer windows vm. dont touch this!  |
 | DFHSDDFFUCKENLONGNAME | 192.168.1.50 | Some printer |
 ...

This is wrong, because same problem may be acceptable for markdown and html tables.
You can be confused, and make mistakes anywhere.

Thanks a lot! I hope I convinced you… :slight_smile:


#122

I think we can simple solve this if just allow set “newline” before “|” symbol.

So it will look like this in markdown:

| Server
| IP
| Description
|
|-
|-
|-
|
| cl1 
| 192.168.100.1
| This is my first server in the list
|
| cl2 
| 10.10.1.22
| This is another one server
|
| windows-5BSD567DSLOS
| 127.0.0.12
| This is customer windows vm. dont touch this! 
|
| DFHSDDFFUCKENLONGNAME
| 192.168.1.50
| Some printer
|
...

Or the first table:

| Item
| Amount
| Cost
|
|:-
|-:
|-:
|
| Orange
| 10
| 7.00
|
| Bread 
| 4
| 3.00
|
| Butter
| 1
| 5.00
|
| Total 
|
| 15.00
|

#123

Or like this:

| Server | IP | Description |
|--------|----|-------------|
| cl1 
| 192.168.100.1
| This is my first server in the list
|
| cl2 
| 10.10.1.22
| This is another one server
|
| windows-5BSD567DSLOS
| 127.0.0.12
| This is customer windows vm. dont touch this! 
|
| DFHSDDFFUCKENLONGNAME
| 192.168.1.50
| Some printer
|
...

And this:

| Item | Amount | Cost |
|:-----|-------:|-----:|
| Orange
| 10
| 7.00
|
| Bread 
| 4
| 3.00
|
| Butter
| 1
| 5.00
|
| Total |      | 15.00 |

This solution gives you more space for creativity. Besides:

  • It’s no need global changes. (only one micro fix is needed)
  • It does not break anything.
  • Everyone will happy

This is the best solution, isn’t it?


#124

I agree with you that pipe tables aren’t very good for big tables. I still think they should be standardized; pipe tables are such a widely-supported Markdown extension that people expect them to work whether they’re in the spec or not.

On the other hand, I think you’re unfairly characterizing HTML tables. You don’t have to put in the end tags for rows or cells. This is fine (at least, it’s specified by HTML5 to work the way we want it to):

<table>
<tr>
<th> Server
<th> IP
<th> Description
<tr>
<td> cl1
<td> 192.168.100.1
<td> This is my first server in the list
<tr>
<td> cl2
<td> 10.10.1.22
<td> This is another one server
<tr>
<td> windows-5BSD567DSLOS
<td> 127.0.0.12
<td> This is customer windows vm. dont touch this!
<tr>
<td> DFHSDDFFUCKENLONGNAME
<td> 192.168.1.50
<td> Some printer
..
</table>

I guess that MediaWiki tables are better. I’m not convinced that they’re so much better that CommonMark should add them to the spec when they’re so rare among existing implementations.


#125

Yes, I see, html5 tables it’s quite simple, thanks for this. But I love markdown and I want to make it better to using with tables too.
I described the main problem to using markdown tables to you.

I don’t want fully mediawiki tables implementation in the markdown, but I want to have opportunity to make tables in vertically mode.

This solution, is fully solves this problem.
It is needed only simple check for newline symbol before pipe in the code.
So it will allow to use common markdown tables in vertically mode too.
Why not? It is not breaking anything, but may be very useful for all users.
And it is same yet markdown tables…


#126

I agree with your implementation.
But I would remove the alingment beneath the headers and put them into the headers themselves.

I think this is the best solution. and the most flexable. and people can have a grid table or a list style table Which is something I like


#127

I find it odd that no-one mentioned the necessity of row headers (i.e. ths to describe rows not columns). For some reason all the current Markdown flavours which support tables only support column headers. But it is really important for accessibility to support both!

Just consider the following table of pizzas and their cost:

				Small    Large
Salami			8.99     10.99
Hawaii			9.49     11.49
Margherita		7.99      9.99

For screen reader users to understand, e.g. the cell with “11.49”, they would need to have read out the pizza (row header = Hawaii) and the size (column header = Large). Just the one or the other is not enough to understand what the content of a cell means.

Most simple text markup languages allow a header cell anywhere in a table with a quite simple syntax, e.g.

  • Creole: |=
  • txt2tags: ||
  • DokuWiki: ^
  • Textile: |_.
  • I personally like: |# (because users already associate # with a heading in Markdown)

Colspans and rowspans are also important for accessibility. Wrongly empty cells can confuse screen readers. But unless they happen in header cells, they are not a big barrier.

Depending on length and complexity, not having header cells marked up correctly can make a table very difficult or impossible to understand for screen reader users.


#128

I agree that row headers are important, but marking them up may become clumsy – perhaps add a colon before the pipe:

|          | Small | Large |  
| -------- | ----- | ----- |  
|  Salami :|  8.99 | 10.99 |  
|  Hawaii :|  9.49 | 11.49 |  
|  Marge. :|  7.99 |  9.99 |  

Another observation I want to throw in here: Fallback rendering for pipe tables is improved in most implementations if each line is ended by a double space. The only exception is Blackfriday which does not render a table then.

## With double space

| Column Header | Second Column |  
| ------------- | ------------- |  
| data cell     | second cell   |  
| third cell    | fourth cell   |  

## Without double space

| Column Header | Second Column |
| ------------- | ------------- |
| data cell     | second cell   |
| third cell    | fourth cell   |

#129

Could the parser automatically figure out that it is a row header based on the empty cell in the top row?


#130

It could, but that’s not always the case. Too unreliable.


#131

John, given that it’s been 3½ years since you wrote that, and since in that time GitHub and many others have adopted CommonMark, should the core be settled without further delay?


#132

I would like to say at this point, I don’t care much about what table format is supported, but rather, that any are.


#133

There is already a tables extension as part of the GitHub Flavored Markdown spec (which is a superset of CommonMark). You can use this today. If a tables extension is ever formalised as part of the CommonMark project, it would need to aim for compatibility with GFM since the GFM table syntax is already widely used and the goal of CommonMark is to be highly compatible with existing implementations.


#134

I agree that compatibility with the widely used pipe table syntax is a good idea. Here are some thoughts I wrote up a couple years ago, towards a spec for tables that is largely compatible with existing pipe tables but more flexible:

I tentatively agree with the current syntax’s decision that pipes | create cell structure, and that literal pipes need to be escaped even inside code backticks. This is a departure from the general principle that nothing needs to be escaped inside code backticks, but it conforms to the general commonmark idea that block structure is discerned prior to inline structure.

Headers should be optional. So, this should be a table:

| a | b |

This too:

|:--:|--:|
| a  | b |

I think | should be required at the beginning and end of the row. I’d like to reserve this syntax for line blocks:

| 15 Main St.
| Chicago, IL

Note that existing pipe tables allow the leading and trailing pipe to be skipped. However, this makes it harder for parsers to tell right away whether we have a table line, and there’s also the issue flagged above about line blocks. Finally, especially if headers are not required, this increases the probability that a line with a literal | will be wrongly treated as a table.

Alignments should be supported, in the now-standard way:

| right | left | center |
| ---:  | :--- | :----: |

What to do if the rows have different numbers of columns? Presumably just add empty columns to all the rows. But there’s a question whether we should take the headers to determine the number of columns (and truncate body rows if needed) or just take the maximum number of cells in any row.

That would be the minimum.

I think colspans could be supported thus:

| this spans two columns  || third column |
| this spans three columns              |||
| aaa      | bbb          |  cccc         |

This means that if you want a blank cell you need space between the ||s. This would be a departure from the way pipe tables currently work.

Maybe for rowspans:

| this spans two rows |  bbb |
|^                    |  ccc |

These can be combined:

| this spans two rows and two colums|| bbb |
|^                                  || ccc |
| aaa             | bbb              | ccc |

One more thing that would be attractive in table syntax is a way to include long paragraphs in cells (or even multiple block elements).

For long paragraphs, one could do something like this:

| aaa | this is really long so I just |
!     | continue down here            |
| new | row here                      |

Here the exclamation marks say: add the contents of these cells to the cells above them. One could even have a list in a table cell using this syntax:

| aaa | - item one         |
!     | - item two         |
| new | row here           |

The ! is very similar to the |, which has its good points and its bad points. Alternatively one could choose a different character with more contrast.

| aaa | - item one         |
+     | - item two         |
| new | row here           |

Note that allowing long cell contents, and especially block level content inside cells, raises some issues about table layout. In HTML output this isn’t a problem, since browsers compute column widths that (usually) make sense for the content. But in other output formats, like latex, one must explicitly specify column widths. So one question is whether to have something in the syntax that represents relative column widths. Pandoc does this by using the lines of - under the headers, but only in cases where the cells are too long to be represented without wrapping.

EDIT: fixed initial |s in code blocks, which this forum converted to > for some reason… @codinghorror - this seems to be a bug in discourse’s processing of posts received by HTML.


#135

I’ve tried to find an implementation of it to no avail.

Joel Gerber


#136

We should be very careful to not create Catch-22. Consider a paragraph with many code spans, each having a pipe in it. It might be easily misinterpreted as a table. Yes, you may escape the pipes to prevent that. Alas, when not table, all the escapes are not escapes anymore but literal \| in a normal code span.

IMHO, it would be absolutely awesome if such ideas are included somewhere in CommonMark repo, even in such a short and informal way as your previous post. E.g. something in contrib/ or staging/ subdir which would contain proposals of future CommonMark features.

It could get CommonMark some momentum for discussing them and it would allow PRs which incrementally change them into more formal spec-like wording, and incrementally bringing them to the level required for inclusion into the core spec as a new chapter. Also implementations of them would go in (more likely) in the right direction instead of reinventing something way too incompatible.

The activity in the form of PRs or some discussion referring them would also make some natural metrics about demand for those features, allowing some prioritization.