How CommonMark parses: blocks, then inlines

Markdown · Expert · 15 min

This model explains why indentation, blank lines and markers interact the way they do.

CommonMark parses a document in two phases.

Phase 1: block structure. Lines are consumed one at a time to build a tree of blocks:

  • Container blocks can hold other blocks: block quotes, list items, and lists (sequences of items).
  • Leaf blocks hold text: paragraphs, headings, code blocks, HTML blocks, thematic breaks, link reference definitions.

For each new line the parser checks which open containers it continues (a > for a quote, enough indentation for a list item), then whether it starts a new block, and otherwise adds it as text to the open leaf. Lazy continuation: a line that would continue a paragraph can do so even without the container's markers, which is why the > can be omitted on continuation lines of a quoted paragraph.

Block structure always takes precedence over inline structure: whether a line is a list item, a code block or a heading is decided before any * or backtick on it is looked at.

Phase 2: inlines. The raw text of each paragraph and heading is parsed for code spans, emphasis, links, images, autolinks, raw HTML, escapes and line breaks. Link reference definitions collected in phase 1 are available here, which is why definitions can appear after their uses.

Code spans and autolinks bind more tightly than emphasis and links, so ` * ` is code, not emphasis.

Example

> A quoted paragraph whose second line
lazily continues without the > marker.

- item one
paragraph text here is also a lazy continuation of the item

`*not emphasis*` because code spans bind first,
and [a link][later] can use a definition below.

[later]: https://example.com

Remember

  • Phase 1 builds block structure: containers (quotes, lists) and leaf blocks
  • Phase 2 parses inlines inside paragraphs and headings
  • Lazy continuation lets paragraph lines omit container markers

Watch out for

  • Assuming emphasis or links can span across a block boundary; inlines are parsed within one block only.

Check yourself

  1. Why can a link reference definition appear after the link that uses it?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: spec.commonmark.org/0.31.2/#appendix-a-parsing-strategy