My two biggest projects over the last week have been Markdown Fixup and Apex. It seemed worthwhile to integrate the two in some useful way.
A quick update on Markdown Fixup: I fixed the regex replacement engine to handle multi-line replacements. This is kind of a big deal if you’re trying to convert things like BBCode to Markdown as part of the pipeline.
I’ve added a new plugin that integrates md-fixup directly into Apex’s processing pipeline. If you haven’t been tracking md-fixup, it’s an opinionated markdown linter and fixer that can normalize spacing, fix emphasis markers, and apply custom regex replacements to your markdown files. And if you haven’t been following Apex, it’s my “universal markdown processor” project that handles all kinds of Markdown extensions in one place.
Why a plugin?
You could always just pipe md-fixup into apex:
md-fixup file.md | apex --mode kramdown
That works fine for simple cases, but if you want to run md-fixup as part of a pipeline with other Apex plugins, the plugin version is the way to go. Plugins run in a deterministic order, and you can enable or disable them as needed without changing your workflow.
When it runs
The md-fixup plugin runs in the pre_parse phase, which means it processes your raw markdown text before Apex parses it. This is important for a couple of reasons:
- Compatibility: md-fixup can normalize your markdown to ensure it’s compatible with Apex’s formatting expectations
- Regex replacements: Most importantly, if you’re using custom regex replacements in your
replacements.yml file, those run before Apex processes the text. This means you can transform markdown syntax itself, not just the final HTML output
Installation
The plugin is available in the Apex plugin directory. You can see it listed with:
Install it with:
apex --install-plugin md-fixup
The plugin assumes you already have the md-fixup binary installed and available in your PATH. (And it uses the Rust version, which is what brew install md-fixup will install.)
Configuring replacements
After installation, the plugin creates a support directory at ~/.config/apex/support/md-fixup/ with a template replacements.yml file. Edit this file to add your custom regex replacements.
The file uses YAML format with a replacements: array. Each replacement has:
name: A descriptive name for the replacement
pattern: A regex pattern to match
replacement: The replacement text (can use regex groups like $1, $2)
timing: When to apply (before or after other processing)
in_code_blocks: Whether to apply inside code blocks (true/false)
in_frontmatter: Whether to apply in frontmatter (true/false)
Here’s an example:
replacements:
- name: "normalize-http"
pattern: "http://"
replacement: "https://"
timing: after
in_code_blocks: false
in_frontmatter: false
- name: "fix-double-spaces"
pattern: " +"
replacement: " "
timing: after
in_code_blocks: false
in_frontmatter: false
Running with plugins
To use the plugins on a file, you can enable it globally, or run them for a specific conversion:
The plugin runs automatically if you’ve enabled plugins globally.
The plugin is hosted at https://github.com/ApexMarkdown/apex-plugin-md-fixup if you want to check out the code or contribute improvements.
And if you haven’t, check out Apex.
Quick side note: it’s been pointed out that md-fixup makes a great
Marked preprocessor. Marked 3 adds enough search and replace
capabilities that it might not be necessary, but for Marked 2, or if you
prefer to edit all your replacements in a dedicated YAML file, you can
just set md-fixup as your Custom Proprocessor.