A Brief History of MultiMarkdown

(Revised 2026-03-14)

MultiMarkdown.pl / MultiMarkdown v1 - v2

https://github.com/fletcher/MultiMarkdown

The first version of MultiMarkdown (MMD) was a modification of John Gruber’s original Markdown.pl Perl script. It rapidly underwent a few development changes, and the first “real” public version was version 2. MMD added support for footnotes, tables, metadata, and a few other things.

The HTML output was then processed using Extensible Stylesheet Language Transformations (XSLT) into other formats, primarily LaTeX.

peg-multimarkdown / MultiMarkdown v3

https://github.com/fletcher/peg-multimarkdown

The next version of MMD was derived from John MacFarlane’s peg-markdown. This used a Parsing Expression Grammar (PEG) to clearly define the syntax grammar and ensure accuracy in parsing. This was my first project using C, which I had not used in quite a while. There were bugs and memory leaks that I never fully cleaned up.

peg\leg was used to generate the parser from the grammar. It worked well enough, but was not re-entrant, so it was hard to use the code for other purposes

MultiMarkdown v4

https://github.com/fletcher/MultiMarkdown-4

v4 was a complete rewrite of v3. It still used the same basic PEG, but was otherwise restructured. This fixed memory leaks and used greg instead of peg/leg to create the parser, allowing it to be re-entrant and thread-safe.

MultiMarkdown v5

https://github.com/fletcher/MultiMarkdown-5

v5 used largely the same code as v4, but was restructured to make it easier to maintain, including switching the build system to CMake. I also switched to a “light” version of the git flow approach to using a development branch and a main branch.

MultiMarkdown v6

https://github.com/fletcher/MultiMarkdown-6

v6 was a complete rewrite from scratch, without using a PEG. I ultimately settled on using re2c to generate tokens from the source text, and lemon to generate a parser that processed lines of tokens into blocks. To improve memory allocation, I added support for pools to allocate larger chunks of memory at a time. I created an algorithm to pair tokens (such as **foo**) that seemed to work accurately and quickly (though does not always agree with what CommonMark chooses to do.)

In short, v6 dramatically improved performances as compared to earlier versions. It was faster than CommonMark (0.27.0) on short files (e.g. 27 kB or less), but slower on longer files (e.g. 200 kB or more).

I also created my own test suite to confirm (and remember) various edge cases to ensure parsing accuracy. It was also the first time I used fuzz testing (with American fuzzy lop) to find bugs.

MultiMarkdown v7

https://github.com/fletcher/MultiMarkdown-7

v7 began when I experimented with trying to improve the codebase for speed, accuracy, and maintainability. I experimented with several different parser approaches to determine which was fastest and easiest to work with. I created a hand-rolled recursive descent parser to convert lines into blocks and compared this with one generated by lemon (which was the approach I used with v6).

During development I made heavier use of fuzz testing along the way. I also tried to start from scratch as much as possible, without copying large chunks of code wholesale without good reason.

MMD v7 is much faster than v6 in comparison tests.