Developer guide

Markdig is designed to be deeply extensible. This guide covers how the parsing pipeline works, how to traverse and manipulate the AST, and how to create your own extensions with custom block parsers, inline parsers, and renderers.

Architecture overview

Markdig's processing flow has three stages:

Markdown text → [Block Parsing] → [Inline Parsing] → AST (MarkdownDocument)
                                                        ↓
                                              [Rendering] → Output (HTML, etc.)
  1. Block parsing — The BlockProcessor walks through the source text line by line, using registered BlockParser objects to identify block-level elements (paragraphs, headings, lists, code blocks, etc.) and build the AST skeleton.

  2. Inline parsing — The InlineProcessor visits every LeafBlock in the AST and runs registered InlineParser objects over the block's text to identify inline elements (emphasis, links, code spans, etc.).

  3. Rendering — A renderer (typically HtmlRenderer) walks the complete AST and dispatches each node to a matching ObjectRenderer for output.

Extensions can modify any of these stages: adding new parsers, modifying existing ones, or registering custom renderers.

Guides

Guide What you'll learn
Abstract syntax tree Structure of block/inline nodes, traversal with Descendants, source spans
Pipeline architecture How MarkdownPipeline, MarkdownPipelineBuilder, and extensions interact
Creating extensions Implement IMarkdownExtension — from simple to complex
Parser authoring API Authoring contracts and advanced APIs for parser/AST parity
Block parsers Write custom BlockParser subclasses — TryOpen, TryContinue, BlockState
Inline parsers Write custom InlineParser subclasses — Match, StringSlice, post-processing
Renderers Implement HtmlObjectRenderer<T> or build a completely custom renderer
Performance Tips for maintaining high throughput — allocation-free patterns, pooling, Span-based parsing
Migration notes Compatibility risks and future contract tightening to avoid depending on ambiguous behavior

Quick reference: key types

Type Role
Markdown Static entry point — Parse, ToHtml, Convert
MarkdownPipeline Immutable, thread-safe configuration object
MarkdownPipelineBuilder Fluent builder for MarkdownPipeline
IMarkdownExtension Interface all extensions implement
BlockParser Abstract base for block-level parsers
InlineParser Abstract base for inline-level parsers
MarkdownDocument Root AST node (a ContainerBlock)
Block Base for all block AST nodes
Inline Base for all inline AST nodes
MarkdownObject Base for all AST nodes — provides Span, Line, Column, data storage
HtmlRenderer Built-in HTML output renderer
HtmlObjectRenderer<T> Base for per-type HTML rendering
IMarkdownRenderer Interface for custom renderers