Tables as Lists of Lists
A post about lightweight plaintext markup
I am always annoyed when a "plain text" markup language's idea of tables is closer to hand-typed ASCII art than to a list-of-lists.
The biggest examples, such as Markdown and Org Mode, fall in this category. Their tables look something like this:
| foo | bar | | --- | --- | | 42 | 1 |
Unless the table is profoundly trivial, that's going to require too much time or specialized table editing code to write and update. Unless the table content is fairly small, the plain text won't look reasonably legible in different display widths either, and would require specialized table-wrapping logic instead of just basic line wrapping.
The only lightweight plain text markup languages I've seen get this right are:
reStructuredText, and
Lisps with macros or functions for markup.
In those, tables can look like lists-of-lists, with some clear indicator that it's meant to be a table. In reStructuredText, you even have the choice of ASCII art tables just like in the other markups, for tables small enough to helps readability and be worth it, but when you're dealing with larger table content, you can switch to just writing this:
.. list-table:: * * foo * bar * * 1 * 2
Note that none of this syntax is table-specific - it's just a list where each entry is just another list, all indented just like any other block of text covered by a directive. Basically, if you already wrote a reStructuredText parser that covers the basics, this way of specifying tables is by far easier and simpler to implement than any other way of specifying a table, since you'd just be reusing the same common syntax, data structures, and parser logic.
reStructuredText's list-table won't let you do fancy edge cases like merged cells, but we can trivially imagine an extension for that, which should be fairly easy to implement if you ever need it, and would still be self-descriptive in plain text: a directive like `.. list-table-merge:: previous-row`, or `.. merge:: previous-column` which we write into the list entries for the cells we want to merge. If that's something you need, I imagine it would be an easy sell to propose it upstream.
Personally, I recommend this approach to tables for any markup language aiming to be lightweight and workable as plain text. I also really like that it reminds us of the fact that "table" is one arbitrary choice of presentation, just like "monospace text with this specific syntax coloring theme" is one arbitrary choice of presentation for text which is semantically marked up as code. What we really have is information which has structure which lends itself well to tabular presentation - and `.. list-table::` is just as good of a way to say that as `.. code::` is for code blocks.













