I’ve been busy improving Apex with some great new features and fixes. CSV tables, aria labels, and more.
Here are the highlights from the latest release.
Better Accessibility with ARIA Support
Accessibility has been a focus, and I’m happy to announce the new --aria flag. When enabled, it adds ARIA labels and attributes throughout your HTML output to improve screen reader support.
This automatically adds:
aria-label="Table of contents" to TOC navigation
role="figure" and role="table" attributes
aria-describedby links between tables and their captions
- Generated IDs for table captions
All of this happens without changing how your documents look—it’s purely behind-the-scenes accessibility enhancement.
Improved Plugin Installation
Installing plugins is now more flexible. You can use GitHub shorthand or full Git URLs:
apex --install-plugin user/repo
apex --install-plugin https://github.com/user/repo.git
When installing from Git sources, you’ll get an interactive confirmation prompt since plugins execute code—safety first!
Homebrew Installation Made Easy
The Homebrew installation process has been simplified. Apex now installs from precompiled universal binaries, so you no longer need CMake or Xcode build tools. Just:
brew tap ttscoff/thelab && brew install apex
To update:
Much simpler than building from source.
Script Injection and CSS Embedding
Two new output options make it easier to create self-contained HTML documents:
--script lets you inject JavaScript libraries. The argument to this flag can be a URL or shorthand keyword. I’ve included shorthands for common ones:
apex doc.md --script mermaid --script katex
Supports: mermaid, mathjax, katex, highlightjs, prism, htmx, alpine
--embed-css inlines CSS files directly into your standalone HTML:
apex doc.md --css styles.css --embed-css
This replaces the <link> tag with an inline <style> block containing the full CSS content.
Multi-file Document Modes
Two new modes for working with multiple files:
--combine: Concatenates Markdown files with include expansion and GitBook-style SUMMARY.md support
--mmd-merge: Merges MultiMarkdown index files into a single stream (see mmd_merge documentation)
Note: These can’t be used together—pick the approach that fits your workflow.
These commands don’t process Markdown syntax, they just combine multiple files (replacing include syntax) into a single document. By default this output goes to STDOUT, so you can pipe it back in to Apex (or any other CLI). Just add | apex [OPTIONS] after the --combine or --mmd-merge run.
Table Improvements
Lots of work went into making tables more robust and flexible:
- Table captions now default to appearing below tables (use
--captions above to change)
- Better detection of alignment separator rows
- Improved rowspan/colspan handling that correctly maps HTML positions to AST indices
- Support for per-cell alignment using colons (
:Text, Text:, :Text:)
- Multi-line cells using trailing backslashes
- Better handling of headerless tables and empty sections
Table header columns
If a header row of a table starts with a blank cell, then the entire column becomes a header column, with the first cell in each row being a th element.
| | Header 1 | Header 2 |
| ----: | :------- | :------- |
| Row 1 | Data 1.1 | Data 1.2 |
| Row 2 | Data 2.1 | Data 2.2 |
Renders each row as:
<tr>
<th scope="row">Row 1</th>
<td align="left">Data 1.1</td>
<td align="left">Data 1.2</td>
</tr>
Inline CSV/TSV Tables
Apex already supported CSV->Table conversion when using include syntax with an external CSV file. Now you can now create tables directly from inline CSV or TSV data using fenced code blocks:
```table
A,B,C
1,2,3
4,5,6
```
Or use a comment marker to convert following lines:
<!--TABLE-->
A,B,C
1,2,3
4,5,6
The system automatically detects whether you’re using commas or tabs, handles alignment rows , and supports captions just like regular Markdown tables.
An alignment row is a row containing just : and - characters (standard Markdown table alignment), or just the keywords left, right, center, or auto (auto = left). If this row is the first row, it creates a headerless table and adds alignment to each row. If it’s the second row, then the first row becomes a thead row of th elements.
Table header columns
If a header row of a table starts with a blank cell, then the entire column becomes a header column, with the first cell in each row being a th element.
| | Header 1 | Header 2 |
| ----: | :------- | :------- |
| Row 1 | Data 1.1 | Data 1.2 |
| Row 2 | Data 2.1 | Data 2.2 |
Renders each row as:
<tr>
<th scope="row">Row 1</th>
<td align="left">Data 1.1</td>
<td align="left">Data 1.2</td>
</tr>
Inline CSV/TSV Tables
Apex already supported CSV->Table conversion when using include syntax with an external CSV file. Now you can now create tables directly from inline CSV or TSV data using fenced code blocks:
```table
A,B,C
1,2,3
4,5,6
```
Or use a comment marker to convert following lines:
<!--TABLE-->
A,B,C
1,2,3
4,5,6
The system automatically detects whether you’re using commas or tabs, handles alignment rows , and supports captions just like regular Markdown tables.
An alignment row is a row containing just : and - characters (standard Markdown table alignment), or just the keywords left, right, center, or auto (auto = left). If this row is the first row, it creates a headerless table and adds alignment to each row. If it’s the second row, then the first row becomes a thead row of th elements.
Mode-Dependent Features
Some features now work differently depending on your mode:
- Image attributes (width, height, style, etc.): Unified and MultiMarkdown modes only
- URL encoding: Unified, MultiMarkdown, and Kramdown modes
This keeps behavior consistent with each mode’s philosophy while adding modern conveniences where they make sense.
And Much More
I’ve fixed numerous bugs around table rendering, URL encoding, image attributes, and HTML output. There are also improvements to caption detection, CSS styling for standalone output, and better handling of edge cases throughout.
For the complete list of changes, fixes, and improvements, check out the full changelog.
Get the Latest Version
Download the latest release from GitHub or update via Homebrew:
As always, I appreciate feedback and bug reports. Happy writing!