{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreib3fxzkqkh6q22cxy723tqq6vvtl4n3a64qgkeodwfzuk76eph54u",
"uri": "at://did:plc:t4aigbwuwix7x3q42qzjc6mn/app.bsky.feed.post/3mou75zadqkb2"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreig76snk5bmyisscs4axu4kwuzynsra4tldfvugw6zrjcb7pcvp4qu"
},
"mimeType": "image/jpeg",
"size": 22773
},
"path": "/link/535/17364843/apex-and-grid-tables",
"publishedAt": "2026-06-21T14:59:00.000Z",
"site": "https://brett.trpstra.net",
"tags": [
"Pandoc’s grid table extension",
"open an issue",
"1",
"↩",
"on Mastodon",
"Bluesky",
"Twitter",
"Click here if you'd like to help out.",
"Mastodon",
"GitHub",
"everywhere else"
],
"textContent": "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.\n\nFirst, thanks to Andreas Kraft for some pointers that got me here.\n\nThe 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.\n\n### Off by default (for now)\n\nGrid tables are **not** enabled in unified mode yet. You have to opt in:\n\n\n apex document.md --grid-tables\n\nOr in document metadata:\n\n\n grid-tables: true\n\nThere 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).\n\n### Get Apex 1.1.0 from Homebrew\n\nIf you are on macOS or Linux with Homebrew:\n\n\n brew tap ttscoff/thelab brew install ttscoff/thelab/apex\n\nCheck your version:\n\n\n apex --version\n\nYou should see 1.1.0 or newer. Then try a grid table:\n\n\n apex my-grid-doc.md --grid-tables -o my-grid-doc.html\n\n### A simple grid table\n\nThis is the classic fruit-and-price example:\n\n\n +---------------+---------------+ | Fruit | Price | +:==============+==============:+ | Bananas | $1.34 | | Oranges | $2.10 | +---------------+---------------+\n\nThe `+===+` row marks the header. Colons in the border row (`+:===+` and `+===:+`) control column alignment, same as Pandoc.\n\n### Colspan and nested grids\n\nGrid tables really shine when a cell spans the full width or contains another table inside it:\n\n\n +-------------------+-------------------+ | 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 | +-------+-------+-------+-------+-------+\n\nThat 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.\n\n### Partial separators and rowspan\n\nThis 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:\n\n\n +---------------------+----------+ | Property | Earth | +=============+=======+==========+ | | min | -89.2 °C | | Temperature +-------+----------+ | 1961-1990 | mean | 14 °C | | +-------+----------+ | | min | 56.7 °C | +-------------+-------+----------+\n\nThe `+-------+` 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.\n\n### Markdown inside cells\n\nGrid tables are not limited to plain text. Lists and other block markdown work in multiline cells:\n\n\n +---------------+---------------+--------------------+ | Fruit | Price | Advantages | +===============+===============+====================+ | Bananas | $1.34 | - built-in wrapper | | | | - bright color | +---------------+---------------+--------------------+ | Oranges | $2.10 | - cures scurvy | | | | - tasty | +---------------+---------------+--------------------+\n\nThose advantage lists render as real `<ul>` items, not a pile of `<br>` tags.\n\n### Please test it and tell me what breaks\n\nI 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.\n\nIf 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.\n\n 1. Please always use backtick code fences when posting code samples. So much easier to deal with without having to edit users’ comments. ↩\n\n\n\n\nLike or share this post on Mastodon, Bluesky, or Twitter.\n\n* * *\n\nBrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.\n\nFind Brett on Mastodon, Bluesky, GitHub, and everywhere else.",
"title": "Apex and Grid Tables",
"updatedAt": "2026-06-21T14:59:00.000Z"
}