cmark

repository·master·Indexed 24 days ago

https://github.com/commonmark/cmark

The C reference implementation of CommonMark. It provides a command-line tool and a shared library (libcmark) for parsing, manipulating, and rendering CommonMark Markdown into formats including HTML, groff man, LaTeX, CommonMark, and XML. The library features a high-level API for quick conversions and a low-level AST-based API for complex document transformations, supporting custom memory allocators and streaming parsing.

Tokens
2.8K
Snippets
8
Records
21
Agent score
84%

What's inside cmark

  1. Overview of cmark capabilities

    master

    cmark is the C reference implementation of CommonMark. It provides two main components:

    1. libcmark (Shared Library): Provides functions to parse CommonMark documents into an Abstract Syntax Tree (AST), manipulate the AST, and render it into several formats including:
      • HTML
      • groff man
      • LaTeX
      • CommonMark
      • XML (representation of the AST)
    2. cmark (Command-line Program): A tool for parsing and rendering CommonMark documents via the CLI.

    Key advantages include high performance, portability (standard C99, no external dependencies), and strict adherence to the CommonMark specification.

  2. Install cmark on Windows

    master

    To compile cmark on Windows using MSVC and NMAKE, use the provided NMAKE file:

    nmake /f Makefile.nmake

    If you are on Linux and want to cross-compile a Windows binary and DLL, you can use the mingw32 compiler:

    make mingw

    The resulting binaries will be located in build-mingw/windows/bin.

  3. Install cmark using GNU Make

    master

    If you have GNU make, you can build the cmark executable and libcmark shared library using the provided Makefile. This process uses cmake internally to create a build environment.

    To build, test, and install:

    make
    make test
    make install

    The binaries are located in build/src. The default installation prefix is /usr/local. To specify a different installation directory, pass the INSTALL_PREFIX variable:

    make INSTALL_PREFIX=path
  4. Install cmark using CMake

    master

    For a more portable build process, you can use cmake directly. This is useful for various build systems or platforms like FreeBSD.

    To configure, build, test, and install:

    cmake -S . -B build  # optionally: -DCMAKE_INSTALL_PREFIX=path
    cmake --build build  # executable will be created as build/src/cmark
    ctest --test-dir build
    cmake --install build
    cmake -S . -B build
    cmake --build build
    ctest --test-dir build
    cmake --install build
  5. Configure unsafe content in cmark

    master

    By default, libcmark scrubs raw HTML and potentially dangerous links (such as javascript:, vbscript:, data:, and file:).

    To allow these elements, use the following:

    • Command line: Use the --unsafe flag.
    • Library API: Use the CMARK_OPT_UNSAFE option.

    Warning: If you enable unsafe mode, it is highly recommended to use a dedicated HTML sanitizer to protect against XSS attacks.

  6. Traverse the AST using an Iterator

    master

    An iterator walks through the node tree, providing CMARK_EVENT_ENTER and CMARK_EVENT_EXIT events for each node. This is ideal for building renderers (e.g., printing an opening tag on ENTER and a closing tag on EXIT) or transforming the AST.

    Important Rules:

    • Iterators do not return EXIT events for leaf nodes (e.g., CMARK_NODE_TEXT, CMARK_NODE_CODE, CMARK_NODE_HTML_BLOCK).
    • Nodes should only be modified after an EXIT event or an ENTER event for leaf nodes.
    void usage_example(cmark_node *root) {
        cmark_event_type ev_type;
        cmark_iter *iter = cmark_iter_new(root);
    
        while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
            cmark_node *cur = cmark_iter_get_node(iter);
            // Do something with `cur` and `ev_type` (e.g., check if ENTER or EXIT)
        }
    
        cmark_iter_free(iter);
    }
  7. Manage HTML and URL security in cmark

    master

    By default, cmark operates in a secure mode to prevent XSS and other vulnerabilities. You can control this behavior with the following flags:

    • --safe (default): Omits raw HTML and potentially dangerous URLs. Raw HTML is replaced by a placeholder comment. Potentially dangerous URLs (those starting with javascript:, vbscript:, file:, or data:—excluding certain image mime types like image/png, image/gif, image/jpeg, or image/webp) are replaced by empty strings.
    • --unsafe: Overrides the default --safe behavior, allowing the rendering of raw HTML and potentially dangerous URLs.
  8. Manage custom memory allocators

    master

    You can provide a custom cmark_mem structure to control how the library allocates and frees memory for the node tree and parser. This is useful for integrating with custom memory management systems.

    • Use cmark_get_default_mem_allocator() to retrieve the default allocator.
    • When creating nodes or parsers, use the _with_mem variants (e.g., cmark_node_new_with_mem) to specify your allocator.
    • Warning: Ensure you use the same allocator for every node in a tree to avoid memory corruption.
    typedef struct cmark_mem {
      void *(*calloc)(size_t, size_t);
      void *(*realloc)(void *, size_t);
      void (*free)(void *);
    } cmark_mem;
  9. Convert CommonMark text to various formats with cmark

    master

    The cmark command-line tool converts Markdown formatted plain text into several output formats following the CommonMark specification. It accepts input from stdin or specified files (which are concatenated) and writes the result to stdout.

    Supported output formats via the --to or -t option:

    • html (default)
    • man (groff man)
    • xml (CommonMark XML)
    • latex
    • commonmark
  10. Configure cmark output formatting and wrapping

    master

    You can control how text is wrapped and how line breaks are handled using the following options:

    • --width WIDTH: Specifies a column width for wrapping. Use 0 (the default) for no wrapping. This affects commonmark, latex, and man renderers.
    • --hardbreaks: Renders soft breaks (newlines inside paragraphs) as hard line breaks in the target format. When used, hard wrapping is disabled for commonmark output regardless of --width.
    • --nobreaks: Renders soft breaks as spaces. When used, hard wrapping is disabled for all output formats regardless of --width.
  11. Use smart punctuation in cmark

    master

    The --smart option enables smart punctuation, which automatically converts standard characters into typographic equivalents:

    • Straight double and single quotes become curly quotes.
    • -- becomes an en-dash.
    • --- becomes an em-dash.
    • ... becomes ellipses.
  12. Convert Markdown to HTML with cmark_markdown_to_html

    master

    Use cmark_markdown_to_html for a simple, one-shot conversion of a UTF-8 encoded Markdown string to an HTML string.

    Note: The caller is responsible for freeing the returned null-terminated, UTF-8-encoded buffer.