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:

apex --list-plugins

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:

apex --plugins file.md

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.