SkillAgentSearch skills...

Comrak

CommonMark + GFM compatible Markdown parser and renderer

Install / Use

/learn @kivikakk/Comrak
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Comrak

Build status CommonMark: 652/652 GFM: 670/670 crates.io version docs.rs OpenSSF Best Practices

Comrak is a CommonMark and GitHub Flavored Markdown compatible parser and renderer, written in Rust.

Compliant with CommonMark 0.31.2 by default.

Installation

Specify it as a requirement in Cargo.toml:

[dependencies]
comrak = "0.51"

Comrak's library supports Rust <span class="msrv">1.85</span>+.

CLI

  • Anywhere with a Rust toolchain:
  • Many Unix distributions:
    • pacman -S comrak
    • brew install comrak
    • dnf install comrak
    • nix run nixpkgs#comrak

You can also find builds I've published in GitHub Releases, but they're limited to machines I have access to at the time of making them! webinstall.dev offers curl | shell-style installation of the latest of these for your OS, including Windows.

Usage

<details> <summary>Click to expand the CLI <code>--help</code> output.
$ comrak --help
</summary>
A 100% CommonMark-compatible GitHub Flavored Markdown parser and formatter

Usage: comrak [OPTIONS] [FILE]...

Arguments:
  [FILE]...
          CommonMark file(s) to parse; or standard input if none passed

Options:
  -c, --config-file <PATH>
          Path to config file containing command-line arguments, or 'none'
          
          [default: /home/runner/.config/comrak/config]

  -i, --inplace
          Reformat a CommonMark file in-place

      --hardbreaks
          Treat newlines as hard line breaks

      --smart
          Replace punctuation like "this" with smart punctuation like “this”

      --github-pre-lang
          Use GitHub-style "<pre lang>" for code blocks

      --full-info-string
          Include words following the code block info string in a data-meta attribute

      --gfm
          Enable GitHub-flavored markdown extensions: strikethrough, tagfilter, table, autolink, and
          tasklist. Also enables --github-pre-lang and --gfm-quirks

      --gfm-quirks
          Use GFM-style quirks in output HTML, such as not nesting <strong> tags, which otherwise
          breaks CommonMark compatibility

      --relaxed-tasklist-character
          Permit any character inside a tasklist item, not just " ", "x" or "X"

      --relaxed-autolinks
          Relax autolink parsing: allows links to be recognised when in brackets, permits all URL
          schemes, and permits domains without a TLD (like "http://localhost")

      --tasklist-classes
          Include "task-list-item" and "task-list-item-checkbox" classes on

      --default-info-string <INFO>
          Default value for fenced code block's info strings if none is given

      --unsafe
          Allow inline and block HTML (unless --escape is given), and permit

      --gemoji
          Translate gemoji like ":thumbsup:" into Unicode emoji like "👍"

      --escape
          Escape raw HTML, instead of clobbering it; takes precedence over --unsafe

      --escaped-char-spans
          Wrap escaped Markdown characters in "<span data-escaped-char>" in HTML

  -e, --extension <EXTENSION>
          Specify extensions to use
          
          Multiple extensions can be delimited with ",", e.g. '--extension strikethrough,table', or
          you can pass --extension/-e multiple times
          
          [possible values: strikethrough, tagfilter, table, autolink, tasklist, superscript,
          footnotes, inline-footnotes, description-lists, multiline-block-quotes, math-dollars,
          math-code, wikilinks-title-after-pipe, wikilinks-title-before-pipe, underline, subscript,
          spoiler, greentext, alerts, cjk-friendly-emphasis, subtext, highlight, insert,
          phoenix-heex]

  -t, --to <FORMAT>
          Specify output format
          
          [default: html]
          [possible values: html, xml, commonmark]

  -o, --output <FILE>
          Write output to FILE instead of stdout

      --width <WIDTH>
          Specify wrap width for output CommonMark, or '0' to disable wrapping
          
          [default: 0]

      --header-id-prefix <PREFIX>
          Prefix generated header IDs with the given ID prefix

      --header-id-prefix-in-href
          Apply the header ID prefix to the href anchor as well

      --front-matter-delimiter <DELIMITER>
          Detect frontmatter that starts and ends with the given string, and do not include it in
          the resulting document

      --syntax-highlighting <THEME>
          Syntax highlighting for fenced code blocks; 'css' for CSS classes (default), a theme name
          for inline styles, or 'none' to disable
          
          [default: css]

      --list-style <LIST_STYLE>
          Specify bullet character for lists ("-", "+", "*") in CommonMark output
          
          [default: dash]
          [possible values: dash, plus, star]

      --sourcepos
          Include source position attributes in HTML and XML output

      --ignore-setext
          Do not parse setext headers

      --ignore-empty-links
          Do not parse empty links

      --experimental-minimize-commonmark
          Minimise escapes in CommonMark output using a trial-and-error algorithm

      --compact
          Suppress pretty-printing newlines between block-level HTML elements

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

By default, Comrak will attempt to read command-line options from a config file specified by
--config-file. This behaviour can be disabled by passing --config-file none. It is not an error if
the file does not exist.
</details>

And there's a Rust interface. You can use comrak::markdown_to_html directly:

use comrak::{markdown_to_html, Options};
assert_eq!(
    markdown_to_html("¡Olá, **世界**!", &Options::default()),
    "<p>¡Olá, <strong>世界</strong>!</p>\n"
);

Or you can parse the input into an AST yourself, manipulate it, and then use your desired formatter:

use comrak::nodes::NodeValue;
use comrak::{format_html, parse_document, Arena, Options};

fn replace_text(document: &str, orig_string: &str, replacement: &str) -> String {
    // The returned nodes are created in the supplied Arena, and are bound by its lifetime.
    let arena = Arena::new();

    // Parse the document into a root `AstNode`
    let root = parse_document(&arena, document, &Options::default());

    // Iterate over all the descendants of root.
    for node in root.descendants() {
        if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
            // If the node is a text node, perform the string replacement.
            *text = text.to_mut().replace(orig_string, replacement).into()
        }
    }

    let mut html = String::new();
    format_html(root, &Options::default(), &mut html).unwrap();

    html
}

fn main() {
    let doc = "Hello, pretty world!\n\n1. Do you like [pretty](#) paintings?\n2. Or *pretty* music?\n";
    let orig = "pretty";
    let repl = "beautiful";
    let html = replace_text(doc, orig, repl);

    println!("{}", html);
    // Output:
    //
    // <p>Hello, beautiful world!</p>
    // <ol>
    // <li>Do you like <a href="#">beautiful</a> paintings?</li>
    // <li>Or <em>beautiful</em> music?</li>
    // </ol>
}

For a slightly more real-world example, see how I generate my GitHub user README from a base document with embedded YAML, which itself has embedded Markdown, or check out some of Comrak's dependents on crates.io or on GitHub.

Security

As with cmark and cmark-gfm, Comrak will scrub raw HTML and potentially dangerous links. This change was introduced in Comrak 0.4.0 in support of a safe-by-default posture, and later adopted by our contemporaries. :)

To allow these, use the r#unsafe option (or --unsafe with the command line program). If doing so, we recommend the use of a sanitisation library like ammonia configured specific to your needs.

Extensions

Comrak supports the five extensions to CommonMark defined in the GitHub Flavored Markdown Spec:

Comrak additionally supports its own extensions, which are yet to be specced out (PRs welcome!):

  • Superscript
  • Header IDs
  • Footnotes
  • Inline footnotes
  • Description lists
  • Front matter
  • Multi-line blockquote

Related Skills

View on GitHub
GitHub Stars1.6k
CategoryDevelopment
Updated7h ago
Forks177

Languages

Rust

Security Score

85/100

Audited on Mar 31, 2026

No findings