MD4C (Markdown for C)

repository·master·Indexed 23 days ago

https://github.com/mity/md4c

A high-performance, compact, and embeddable Markdown parser written in C, primarily compliant with the CommonMark specification. It utilizes a callback-based 'push model' to render Markdown into various formats without the overhead of an Abstract Syntax Tree (AST). The library includes a dedicated HTML renderer via md4c-html.h and supports numerous extensions such as GitHub-style tables, task lists, footnotes, and LaTeX math spans.

Tokens
1.4K
Snippets
0
Records
8
Agent score
30%

What's inside MD4C

  1. Compare MD4C with other Markdown parsers

    master

    When choosing a Markdown parser, consider these key differences regarding MD4C:

    • Decoupled Parsing and Generation: Unlike many implementations that entangle the parser and HTML generator, MD4C allows you to process input in ways other than just HTML conversion.
    • No AST Overhead: Most C/C++ parsers are full DOM-like parsers that construct an Abstract Syntax Tree (AST). MD4C avoids this, resulting in significantly faster performance and a lower memory footprint if you do not explicitly need an AST.
    • Linear Parsing Time: MD4C is designed to provide linear or near-linear parsing times even with complex or 'pathological' input patterns. This helps prevent Denial-of-Service (DoS) attacks that target naive parsers with quadratic or worse complexity.
    • Input Handling: MD4C follows a 'Garbage In, Garbage Out' (GIGO) philosophy. It does not perform input validation (e.g., checking for well-formed UTF-8). It treats any sequence of bytes as valid input, propagating ill-formed sequences directly to callbacks.
  2. Handle input strings in MD4C

    master

    MD4C does not work with zero-terminated strings (C-style strings).

    Why?

    1. Correctness: Markdown documents can legally contain the U+0000 character (a zero byte in UTF-8). Using zero-terminated strings would cause the parser to prematurely stop.
    2. Performance: To support zero-terminated strings, the parser would have to copy every text chunk into a temporary buffer to add a null terminator. To avoid this overhead, MD4C passes a pointer directly into the input document along with the length of the text segment to the callback.

    Action: When implementing callbacks, always use the provided length parameter rather than relying on a null terminator.

  3. How to convert Markdown to HTML

    master

    To convert Markdown directly to HTML, include md4c-html.h and link against the MD4C-HTML library (-lmd4c-html). If embedding manually, include md4c.[hc], md4c-html.[hc], and entity.[hc].

    Use the md_html() function, which takes the Markdown input and a callback function. The callback is triggered with chunks of the generated HTML output, which you can then append to a buffer or write to a file.

  4. How to use MD4C for parsing Markdown

    master

    To use MD4C as a pure parser, include md4c.h and link against the MD4C library (-lmd4c). Alternatively, you can embed the parser directly by adding md4c.[hc] to your codebase.

    The core function is md_parse(). It uses a push model: as it processes the input, it calls a series of callback functions provided by your application to notify you about the start/end of blocks and spans, and to output textual content. This allows you to convert the Markdown into any custom format or render it directly.

  5. Configure Input/Output Encoding

    master

    MD4C is largely encoding-agnostic and assumes the encoding is compatible with ASCII. However, for Unicode-specific tasks like word boundary detection and link reference matching, you must define a preprocessor macro during the build process:

    • MD4C_USE_UTF8 (Default): Assumes UTF-8 encoding. This is the standard behavior if no macro is specified.
    • MD4C_USE_UTF16 (Windows): Uses WCHAR instead of char and assumes UTF-16 encoding. Note: You must define this macro both when building MD4C and when including md4c.h in your application. This is only supported in the parser; the HTML renderer does not support UTF-16.
    • MD4C_USE_ASCII: Assumes ASCII-only input. Non-ASCII whitespace/punctuation will not be recognized, and link reference matching will only work for [a-zA-Z].
  6. Configure Markdown extensions with flags

    master

    By default, MD4C follows the CommonMark specification. You can enable various extensions by passing specific flags to the parsing functions.

    Supported Extensions

    • MD_FLAG_COLLAPSEWHITESPACE: Collapses non-trivial whitespace into a single space.
    • MD_FLAG_TABLES: Enables GitHub-style tables.
    • MD_FLAG_TASKLISTS: Enables GitHub-style task lists.
    • MD_FLAG_FOOTNOTES: Enables footnote references and definitions.
    • MD_FLAG_STRIKETHROUGH: Enables strike-through spans (e.g., ~foo bar~).
    • MD_FLAG_SPOILERS: Enables spoiler spans (e.g., ||hidden text||). The HTML renderer uses a custom <x-spoiler> tag.
    • MD_FLAG_SUPERSCRIPTS: Enables superscript spans (e.g., x^2^). The HTML renderer uses <sup>.
    • MD_FLAG_SUBSCRIPTS: Enables subscript spans (e.g., H~2~O). The HTML renderer uses <sub>.
    • MD_FLAG_HIGHLIGHT: Enables highlight spans (e.g., ==important==). The HTML renderer uses <mark>.
    • MD_FLAG_PERMISSIVEURLAUTOLINKS: Supports permissive URL autolinks.
    • MD_FLAG_PERMISSIVEEMAILAUTOLINKS: Supports permissive e-mail autolinks.
    • MD_FLAG_PERMISSIVEWWWAUTOLINKS: Supports permissive WWW autolinks (assumes http: scheme).
    • MD_FLAG_LATEXMATHSPANS: Supports LaTeX math spans ($...$ and $$...$$). The HTML renderer uses a custom <x-equation> tag.
    • MD_FLAG_WIKILINKS: Supports wiki-style links ([[link label]]). The HTML renderer uses a custom <x-wikilink> tag.
    • MD_FLAG_UNDERLINE: Uses underscore (_) for underlining instead of emphasis.
    • MD_FLAG_ADMONITIONS: Recognizes GitHub-style admonitions.

    Disabling Features

    • MD_FLAG_NOHTMLSPANS: Disables raw inline HTML.
    • MD_FLAG_NOHTMLBLOCKS: Disables raw HTML blocks.
    • MD_FLAG_NOINDENTEDCODEBLOCKS: Disables indented code blocks.