- Rust 95.1%
- JavaScript 2.4%
- Python 2.1%
- Kotlin 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks are pending
Dependency audit / Audit release workspace dependencies (push) Waiting to run
minimal-dep-check-ignore-this / test (nightly) (push) Waiting to run
JS compatibility / Linkify crate compatibility (push) Waiting to run
JS compatibility / Differential (config 0) (push) Waiting to run
JS compatibility / Differential (config 1) (push) Waiting to run
JS compatibility / Differential (config 2) (push) Waiting to run
JS compatibility / Differential (config 3) (push) Waiting to run
JS compatibility / Differential (config 4) (push) Waiting to run
JS compatibility / Differential (config 5) (push) Waiting to run
Build Kotlin Binding / Build Native (android) (push) Waiting to run
Build Kotlin Binding / Build Native (aarch64-apple-darwin) (push) Waiting to run
Build Kotlin Binding / Build Native (x86_64-apple-darwin) (push) Waiting to run
Build Kotlin Binding / Build Native (x86_64-unknown-linux-gnu) (push) Waiting to run
Build Kotlin Binding / Build Native (aarch64-unknown-linux-gnu) (push) Waiting to run
Build Kotlin Binding / Build Native (x86_64-pc-windows-msvc) (push) Waiting to run
Build Kotlin Binding / Test and package JVM JAR (push) Blocked by required conditions
gh-pages / build (stable) (push) Waiting to run
gh-pages / deploy (push) Blocked by required conditions
Build Python Wheels / linux (aarch64) (push) Waiting to run
Build Python Wheels / linux (x86_64) (push) Waiting to run
Build Python Wheels / windows (3.10, x64) (push) Waiting to run
Build Python Wheels / windows (3.11, x64) (push) Waiting to run
Build Python Wheels / windows (3.12, x64) (push) Waiting to run
Build Python Wheels / windows (3.13, x64) (push) Waiting to run
Build Python Wheels / windows (3.14, x64) (push) Waiting to run
Build Python Wheels / windows (3.14t, x64) (push) Waiting to run
Build Python Wheels / windows (3.15, x64) (push) Waiting to run
Build Python Wheels / windows (3.15t, x64) (push) Waiting to run
Build Python Wheels / windows (pypy3.11-nightly, x64) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.10) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.11) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.12) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.13) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.14) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.14t) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.15) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], 3.15t) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-15-intel target:x86_64], pypy3.11-nightly) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.10) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.11) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.12) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.13) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.14) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.14t) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.15) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], 3.15t) (push) Waiting to run
Build Python Wheels / macos (map[runner:macos-latest target:aarch64], pypy3.11-nightly) (push) Waiting to run
Build Python Wheels / sdist (push) Waiting to run
tests / Format and Clippy (push) Waiting to run
tests / Test (default features) (push) Waiting to run
tests / Test (all features) (push) Waiting to run
tests / Test (no default features) (push) Waiting to run
|
||
| .github/workflows | ||
| benchmarks | ||
| bindings | ||
| crates | ||
| demo | ||
| examples | ||
| src | ||
| tests | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| LICENSE | ||
| README.md | ||
| rustfmt.toml | ||
| THIRD_PARTY_LICENSES | ||
markdown-it-rs
Note
This is a personally maintained fork of markdown-it-rust/markdown-it.
Warning
Status: unpublished
1.0.0— contains many breaking changes compared to the latest published version (0.7.0); the API is not stable yet.
A Rust-native, AST-first Markdown parser with markdown-it.js-compatible rendering.
You can check a demo in your browser.
Features
- 100% CommonMark compatible & 100% markdown-it.js-compatible HTML rendering
- Mutable, typed AST
- Everything is a plugin
- Source maps for parsed nodes
- Extensible core, block, and inline rule chains
- Optional CJK-friendly emphasis handling
- Optional Python and WebAssembly bindings
Quick start
The MarkdownItDefault preset corresponds to markdown-it.js's default syntax:
use markdown_it::{MarkdownIt, Preset};
fn main() {
let md = MarkdownIt::with_preset(Preset::MarkdownItDefault);
let html = md.render("Hello **world**!");
assert_eq!(html, "<p>Hello <strong>world</strong>!</p>\n");
}
Assembling your own Rust Markdown dialect:
use markdown_it::MarkdownIt;
use markdown_it::plugins::{cmark, extra};
fn main() {
let mut md = MarkdownIt::empty();
cmark::add(&mut md);
extra::tables::add(&mut md);
extra::tasklist::add(&mut md);
extra::footnote::add(&mut md);
// ...
}
Planned plugin API
Important
This section is a design target for the next major version, not an API that is available in the current release yet.
The planned high-level API uses typed, composable builders for common plugins, while keeping the lower-level rule and AST interfaces available for advanced parsers. An emoji shortcode plugin with custom HTML rendering should look roughly like this:
use markdown_it::{MarkdownIt, PluginSpec};
const EMOJIS: &[(&str, &str, &str)] = &[
(":rocket:", "🚀", "rocket"),
(":warning:", "⚠️", "warning"),
];
#[derive(Debug)]
struct Emoji {
glyph: &'static str,
label: &'static str,
}
fn emoji() -> PluginSpec {
PluginSpec::new("emoji")
.inline_leaf::<Emoji>("shortcode")
.marker(':')
.parse(|cx| {
let &(shortcode, glyph, label) = EMOJIS
.iter()
.find(|(code, _, _)| cx.starts_with(code))?;
cx.consume(shortcode);
Some(Emoji { glyph, label })
})
.render_html(|emoji, html| {
html.element("span")
.class("emoji")
.attr("role", "img")
.attr("aria-label", emoji.label)
.text(emoji.glyph);
})
.finish()
}
let md = MarkdownIt::builder().plugin(emoji()).build()?;
let html = md.render("Ready :rocket:");
//assert_eq!(html, r#"<p>Ready <span class="emoji" role="img" aria-label="rocket">🚀</span></p>"#)
The goal is to keep simple plugins around 20 lines, with automatic rollback and HTML escaping, while retaining lower-level APIs for advanced plugins.
Until then, see the examples/ferris folder for a detailed guide to the current
low-level plugin API.
CJK-friendly delimiters
The optional cjk_friendly plugin implements the delimiter amendments from
markdown-cjk-friendly, so
emphasis next to Chinese, Japanese, or Korean punctuation works without spaces:
use markdown_it::{MarkdownIt, Preset};
let mut md = MarkdownIt::with_preset(Preset::MarkdownItDefault);
markdown_it::plugins::cjk_friendly::add(&mut md);
assert_eq!(
md.render("**这是重要内容。**后面可以继续写~~,被删除的内容~~"),
"<p><strong>这是重要内容。</strong>后面可以继续写<s>,被删除的内容</s></p>\n"
);
Security
This lib does not sanitize or filter any HTML output. You should add a sanitizer before rendering untrusted content.
There are two plugins you should be careful with:
-
html- enable raw inline/block HTML. By defaultplugins::cmarkdoes not enable raw HTML. Addmarkdown_it::plugins::html::add(parser)to enable it. -
directives- allows custom directives like:name{key=value}that are rendered by user provided content. The default renderers simply emit<span>/<div>wrappers. But it might be used like:name{onclick=...}.