Fontlex Markdown

The box below is a plain text box holding Markdown. The font renders it: the text engine that lays out the letters runs GitHub Flavored Markdown's rules, line by line, hides the markup and styles the text. The characters you type stay exactly as typed. No script on this page does any of it. It comes in two editions: monospaced, and proportional with code in a monospaced font, so the box looks like the rendered page.

Turn off "Render Markdown" to see the characters. Each line is read on its own: the font sees one line at a time, as the browser lays it out.

What it renders

How exact it is

TextLinesMonospaceProportional
CommonMark's one-line spec examples447100.0%100.0%
GitHub's one-line extension examples23100.0%100.0%
Random lines of Markdown syntax19,526100.0%100.0%
Random lines behind block markup4,902100.0%100.0%

Each character's glyph (hidden, or its style) is compared with what GitHub makes of the line read as a document, as computed by ports of the reference implementations: commonmark.js 0.31.2, and cmark-gfm 0.29.0.gfm.13 (github.com's parser) for the extensions. Lines past one of the font's bounds (below) are left out of the count; many of them still come out right.

How a font can parse Markdown

OpenType lets a font substitute glyphs by context, one lookup after another, each a pass over the line from left to right or from right to left. The font's 150 or so passes carry what they learn in glyph variants. The trick that makes Markdown possible is that most passes only see the characters they care about: a pass matching * and _ skips every letter in between, so a pair of markers is next to each other however much text separates them.

  1. Right to left: what lies ahead of each character. Whether a code span's closing backticks follow, whether a link destination (…) follows a ], whether a valid tag or autolink starts at a <, and what the line's block markup needs to know.
  2. Left to right, after that: the line's block markup, read from its start; a scan that settles code spans, link destinations and raw HTML; then brackets and emphasis are matched in rounds, where each round pairs every opener with the closer right after it and matched pairs drop out, so the next round sees the next level of nesting; then each glyph is drawn in its style.

So CommonMark's inline syntax takes one change of direction. It can't take none: whether a run of backticks opens a code span depends on what follows, and whether it is inside one depends on what precedes. GitHub's extensions add a few right-to-left passes later on: where a bare URL's trailing punctuation starts, and email addresses, which GitHub only looks for once emphasis is settled. Markdown's nesting is unbounded, which no finite set of passes can follow, so the font has bounds: emphasis runs of up to 6 characters, nested 6 deep; 3 brackets open at once; backtick runs of up to 8; parentheses 3 deep in a destination.

Limits

Base fonts: JetBrains Mono, and Noto Sans with code in JetBrains Mono, each with its bold and italic (SIL Open Font License).