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.
Markdig's processing flow has three stages:
Markdown text → [Block Parsing] → [Inline Parsing] → AST (MarkdownDocument)
↓
[Rendering] → Output (HTML, etc.)
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.
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.).
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.
| 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 |
| 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 |