Markdig

Markdig is a fast, powerfull, CommonMark compliant, extensible Markdown processor for .NET.
NOTE: The repository is under construction. There will be a dedicated website and proper documentation at some point!
Features
- Very fast parser (no-regexp), very lightweight in terms of GC pressure. See benchmarks
- Abstract Syntax Tree
- Converter to HTML
- Passing more than 600+ tests from the latest CommonMark specs
- Includes all the core elements of CommonMark:
- including GFM fenced code blocks.
- Extensible architecture
- Even the core Markdown/CommonMark parsing is pluggable, so it allows to disable builtin Markdown/Commonmark parsing (e.g Disable HTML parsing) or change behaviour (e.g change matching
#of a headers with@)
- Even the core Markdown/CommonMark parsing is pluggable, so it allows to disable builtin Markdown/Commonmark parsing (e.g Disable HTML parsing) or change behaviour (e.g change matching
- Built-in with 18+ extensions, including:
- 2 kind of tables:
- Pipe tables (inspired from Github tables and PanDoc - Pipe Tables)
- Grid tables (inspired from Pandoc - Grid Tables)
- Extra emphasis (inspired from Pandoc - Emphasis and Markdown-it)
- strike through
~~, - Subscript
~ - Superscript
^ - Inserted
++ - Marked
==
- strike through
- Special attributes or attached HTML attributes (inspired from PHP Markdown Extra - Special Attributes)
- Definition lists (inspired from PHP Markdown Extra - Definitions Lists)
- Footnotes (inspired from PHP Markdown Extra - Footnotes)
- Auto-identifiers for headings (similar to Pandoc - Auto Identifiers)
- Extra bullet lists, supporting alpha bullet
a.b.and roman bullet (i,ii...etc.) - Media support for media url (youtube, vimeo, mp4...etc.) (inspired from this CommonMark discussion)
- Abbreviations (inspired from PHP Markdown Extra - Abbreviations)
- Citation text by enclosing
""...""(inspired by this CommonMark discussion ) - Custom containers similar to fenced code block
:::for generating a proper<div>...</div>instead (inspired by this CommonMark discussion ) - Figures (inspired from this CommonMark discussion)
- Footers (inspired from this CommonMark discussion)
- Mathematics/Latex extension by enclosing
$$for block and$for inline math (inspired from this CommonMark discussion) - Soft lines as hard lines
- Emoji support (inspired from Markdown-it)
- SmartyPants (inspired from Daring Fireball - SmartyPants)
- Bootstrap class (to output bootstrap class)
- 2 kind of tables:
- Compatible with .NET 3.5, 4.0+ and .NET Core (
netstandard1.1+)
Download
Markdig is available as a NuGet package:
Usage
The main entry point for the API is the Markdig.Markdown class:
By default, without any options, Markdig is using the plain CommonMark parser:
var result = Markdown.ToHtml("This is a text with some *emphasis*");
Console.WriteLine(result); // prints: <p>This is a text with some <em>emphasis</em></p>
In order to activate most of all advanced extensions (except Emoji, SoftLine as HarLine and SmartyPants)
// Configure the pipeline with all advanced extensions active
var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
var result = Markdown.ToHtml("This is a text with some *emphasis*", pipeline);
You can have a look at the MarkdownExtensions that describes all actionable extensions (by modifying the MarkdownPipeline)
License
This software is released under the BSD-Clause 2 license.
Benchmarking
This is an early preview of the benchmarking against various implementations:
- Markdig: itself
- CommonMarkCpp: cmark, Reference C implementation of CommonMark, no support for extensions
- CommonMark.NET: CommonMark implementation for .NET, no support for extensions, port of cmark
- CommonMarkNet (devel): An evolution of CommonMark.NET, supports extensions, not released yet
- MarkdownDeep another .NET implementation
- MarkdownSharp: Open source C# implementation of Markdown processor, as featured on Stack Overflow, regexp based.
- Moonshine: popular C Markdown processor
Markdig is roughly x100 times faster than MarkdownSharp and extremelly competitive to other implems (that are not feature wise comparable)
Performance in x86:
// * Summary *
BenchmarkDotNet-Dev=v0.9.6.0+
OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, ProcessorCount=8
Frequency=3319351 ticks, Resolution=301.2637 ns, Timer=TSC
HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
JitModules=clrjit-v4.6.1080.0
Type=Program Mode=SingleRun LaunchCount=2
WarmupCount=2 TargetCount=10
Method | Median | StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
--------------------- |---------- |---------- |------- |------ |------- |------------------- |
TestMarkdig | 5.4870 ms | 0.0158 ms | 193.00 | 12.00 | 84.00 | 1,425,192.72 |
TestCommonMarkCpp | 4.0134 ms | 0.1008 ms | - | - | 180.00 | 454,859.74 |
TestCommonMarkNet | 4.6139 ms | 0.0581 ms | 193.00 | 12.00 | 84.00 | 1,406,367.27 |
TestCommonMarkNetNew | 5.5327 ms | 0.0461 ms | 193.00 | 96.00 | 84.00 | 1,738,465.42 |
TestMarkdownDeep | 7.5910 ms | 0.1006 ms | 205.00 | 96.00 | 84.00 | 1,758,383.79 |
TestMoonshine | 5.8843 ms | 0.1758 ms | - | - | 215.00 | 565,000.73 |
// * Diagnostic Output - MemoryDiagnoser *
// ***** BenchmarkRunner: End *****
Performance for x64:
// * Summary *
BenchmarkDotNet-Dev=v0.9.6.0+
OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, ProcessorCount=8
Frequency=3319351 ticks, Resolution=301.2637 ns, Timer=TSC
HostCLR=MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]
JitModules=clrjit-v4.6.1080.0
Type=Program Mode=SingleRun LaunchCount=2
WarmupCount=2 TargetCount=10
Method | Median | StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
--------------------- |---------- |---------- |------- |------- |------ |------------------- |
TestMarkdig | 5.9539 ms | 0.0495 ms | 157.00 | 96.00 | 84.00 | 1,767,834.52 |
TestCommonMarkNet | 4.3158 ms | 0.0161 ms | 157.00 | 96.00 | 84.00 | 1,747,432.06 |
TestCommonMarkNetNew | 5.3421 ms | 0.0435 ms | 229.00 | 168.00 | 84.00 | 2,323,922.97 |
TestMarkdownDeep | 7.4750 ms | 0.0281 ms | 318.00 | 186.00 | 84.00 | 2,576,728.69 |
// * Diagnostic Output - MemoryDiagnoser *
// ***** BenchmarkRunner: End *****
Credits
Thanks to the fantastic work done by John Mac Farlane for the CommonMark specs and all the people involved in making Markdown a better standard!
This project would not have been possible without this huge foundation.
Thanks also to the project BenchmarkDotNet that makes benchmarking so easy to setup!
Author
Alexandre MUTEL aka xoofx