Description
As part of the overall effort to make mdbook
more modular, it'd be nice to formalise the concept of a "preprocessor". This is a bit of code that's run immediately after a Book
is loaded from disk and before it gets rendered, allowing you to apply manipulations/transformations to the original source code.
Use cases are:
- The current
{{#playpen file.rs}}
and{{#include file.md}}
"macros" - Linting for known issues to give the user better feedback (e.g. Files with spaces are not found #527)
- Replacing a
$$ ... $$
snippet with its mathjax equivalent
Rough guideline of what is involved:
- Introduce a
Preprocessor
trait - Make
MDBook
hold a list of preprocessors (Vec<Box<Preprocessor>>
) and add awith_preprocessor()
method for adding more - Extract
{{#playpen ...}}
and{{#include ...}}
(from here) into their own preprocessor types instead of being run as part of the HTML renderer (here) - In the
MDBook::build()
process, execute each preprocessor on a copy of the originalBook
- Update
MDBook::load_with_config()
so we can discover which preprocessors should be run by inspecting thebook.toml
config
Hint: most of this can actually be stolen from #507 because it'll be identical to how we discover which alternate backends to run. Look for the
determine_renderers()
function.
- Document how preprocessors work in the user guide
It looks like a big job, but that's mainly because there are several little steps which need to be tweaked. Steps 1 and 3 are actually just a dozen lines, with step 5 being the most complex (and even then you can steal 90% of the work from existing code). I'd estimate this to be a couple hundred lines of code at most, with a large proportion of that being taken up by relatively straight-forward tests and documentation.
I'm also more than happy to help mentor through the entire process 😀