Comrak
CommonMark + GFM compatible Markdown parser and renderer
Install / Use
/learn @kivikakk/ComrakREADME
Comrak
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:
cargo install comrak- <code>cargo binstall comrak</code>
- Many Unix distributions:
pacman -S comrakbrew install comrakdnf install comraknix 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
himalaya
343.1kCLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
node-connect
343.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
90.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
coding-agent
343.1kDelegate coding tasks to Codex, Claude Code, or Pi agents via background process
