Apex 1.1.0 adds support for Pandoc-style grid tables — those ASCII-art tables built with +, -, =, and | instead of the usual pipe-table separators. If you have ever copied a grid table out of a Pandoc doc or academic paper and wished your Markdown processor would just deal with it, this one is for you.

First, thanks to Andreas Kraft for some pointers that got me here.

The implementation follows Pandoc’s grid table extension: border rows, header separators, alignment markers, multiline cells, colspan, and the weird in-row partial separators that make temperature tables possible. Apex preprocesses grid blocks into pipe or HTML tables before the rest of the pipeline runs, so you get normal <table> output at the end.

Off by default (for now)

Grid tables are not enabled in unified mode yet. You have to opt in:

apex document.md --grid-tables

Or in document metadata:

grid-tables: true

There is also --no-grid-tables if you need to override metadata and force them off. I left the feature off by default on purpose — grid table parsing touches a lot of edge cases, and I would rather ship something solid and let people turn it on when they need it than break documents that happen to start lines with + (though that case should be properly handled at this point).

Get Apex 1.1.0 from Homebrew

If you are on macOS or Linux with Homebrew:

brew tap ttscoff/thelab
brew install ttscoff/thelab/apex

Check your version:

apex --version

You should see 1.1.0 or newer. Then try a grid table:

apex my-grid-doc.md --grid-tables -o my-grid-doc.html

A simple grid table

This is the classic fruit-and-price example:

+---------------+---------------+
| Fruit         | Price         |
+:==============+==============:+
| Bananas       | $1.34         |
| Oranges       | $2.10         |
+---------------+---------------+

The +===+ row marks the header. Colons in the border row (+:===+ and +===:+) control column alignment, same as Pandoc.

Colspan and nested grids

Grid tables really shine when a cell spans the full width or contains another table inside it:

+-------------------+-------------------+
| Grid Tables       | Are Beautiful     |
+===================+===================+
|                   | In code and docs  |
| Easy to read      |                   |
|                   |                   |
+-------------------+-------------------+
| Exceptionally flexible and powerful   |
+-------+-------+-------+-------+-------+
| Col 1 | Col 2 | Col 3 | Col 4 | Col 5 |
+-------+-------+-------+-------+-------+

That last row is a single cell spanning all five columns, with a nested five-column grid tucked inside. Apex converts nested grids to HTML so they render correctly inside cells that support block markdown.

Partial separators and rowspan

This is the layout that breaks most pipe-table parsers. Property and Earth in the header, then Temperature with min/mean/max rows where the label spans multiple lines:

+---------------------+----------+
| Property            | Earth    |
+=============+=======+==========+
|             | min   | -89.2 °C |
| Temperature +-------+----------+
| 1961-1990   | mean  | 14 °C    |
|             +-------+----------+
|             | min   | 56.7 °C  |
+-------------+-------+----------+

The +-------+ partial separator inside a row tells Apex that “Temperature” and “1961-1990” share a rowspan while the min/mean/min values sit in their own columns.

Markdown inside cells

Grid tables are not limited to plain text. Lists and other block markdown work in multiline cells:

+---------------+---------------+--------------------+
| Fruit         | Price         | Advantages         |
+===============+===============+====================+
| Bananas       | $1.34         | - built-in wrapper |
|               |               | - bright color     |
+---------------+---------------+--------------------+
| Oranges       | $2.10         | - cures scurvy     |
|               |               | - tasty            |
+---------------+---------------+--------------------+

Those advantage lists render as real <ul> items, not a pile of <br> tags.

Please test it and tell me what breaks

I have regression tests for the cases above and a handful of hardening checks (plus-list lines starting with + are not mistaken for grids, invalid blocks fall back to the original text, and so on). But Pandoc grid tables are flexible in ways that are hard to exhaustively test.

If you have documents with grid tables – especially weird ones from legacy Pandoc workflows – please run them through Apex with --grid-tables and open an issue if anything looks wrong. Include the source grid table1 and the HTML you got (or expected). Edge cases are exactly what I need before flipping this on by default in unified mode.

  1. Please always use backtick code fences when posting code samples. So much easier to deal with without having to edit users’ comments.