Apex was designed to make using existing Markdown syntax from a range of tools (CommonMark, GFM, MultiMarkdown, Kramdown, mmark) easier — not to add a bunch of new or special syntax. Plugins allow you to add your own syntax and even entirely new tools to markdown generation, keeping the core focused while giving you the flexibility to extend it however you need.
The new plugin architecture is a flexible system that lets you extend the core Markdown engine without patching the main binary. You can browse the full details, plugin types, and environment variables on the wiki’s plugins page: Apex Plugins.
The First Plugin: kbd
The first “official” example is the kbd plugin, which adds support for {% kbd cmd-shift-p %} or {% kbd $@p %}-style inline Liquid markup that renders as semantic <kbd> keyboard shortcuts, ordering and formatting based on Apple’s guidelines. To install it:
Install Apex (now easier via Homebrew):
brew tap ttscoff/thelab && brew install ttscoff/thelab/apex
If you already have the tap added, just run:
brew update && brew install apex
This now installs a precompiled binary from GitHub, so it no longer builds from source and does not require Xcode (just the usual Command Line Tools Homebrew expects).
Install the kbd plugin:
apex --install-plugin kbd
This clones the plugin (based on an entry/id in the directory) into your local Apex plugins directory and runs any optional post-install step defined in the plugin’s plugin.yml. After installation, the plugin is automatically available whenever you run apex on your documents—no extra flags required.
You can also install a plugin directly from a GitHub repository, so plugins can be distributed directly (this will result in a security warning when installing). Just run apex --install-plugin https://github.com/user/repo.git or just apex --install-plugin user/repo.
You can use apex --list-plugins to show your locally-installed plugins as well as those available in the directory (which, right now, is only kbd).
Running With Plugins
Apex does not enable plugins by default. Because they shell out and run
external scripts, plugins can greatly increase
the processing time, and I want to keep it snappy by default. To run
with plugins, you need to include the --plugins flag when running,
e.g. apex --plugins mydocument.md.
There’s a new setup that allows you to create a YAML configuration at
~/.config/apex/config.yml and include a line like plugins: true to
always run plugins when you run apex. This is true for all possible
command line options, and is equivalent to running --meta-file
config.yml (which parses and merges YAML or MMD metadata into every
document it parses in that command).
Plugin Bundles
Plugin bundles let a single repository ship multiple related plugins behind one install. Instead of publishing separate repos for kbd, menubar, prefpane, and other documentation helpers, you can define them all in one plugin.yml using a bundle: array, each with its own id, phase, and handler or regex. Apex treats each entry as an independent plugin at runtime (with its own ID, phase, and priority), but shares common metadata like author, homepage, or repo and allows you to install and update the entire group with a single --install-plugin command. This makes it much easier to organize families of plugins (for example, a "documentation" bundle or a "theming" bundle), keep them in sync, and let users opt into a whole set of related behavior with one step.
Build and Share
For more examples and ideas on building your own plugins, see the Plugins page on the wiki.
I’ve set up a central plugin repository that can be used to share plugins. If you create a plugin and are willing to share it, I’d love to build a little community around Apex as it grows. Details for submitting to the directory are included in the wiki page above.
A New GitHub Organization
Apex now lives under the ApexMarkdown organization on GitHub at https://github.com/ApexMarkdown/apex.
The old repository location redirects there automatically, but using the new URL makes it clear where active development happens.
Looking forward to hearing more about how it works out for you, and please keep hitting me with feature requests!