Search
Search documentation
Getting started
Updated Nov 1, 2026
Install
cargo add textlaneThe crate needs Rust 1.88 or later. Each domain is a feature, all on by default: md,
html, highlight (html.highlight and its grammars), katex (html.katex and KaTeX's
font metrics), mdx and nl. Leave out what you do not use to build faster:
cargo add textlane --no-default-features --features md,htmlA first pipeline
A pipeline parses text into a tree, runs plugins over it and serializes the result. Each
plugin is a struct in its domain's module, textlane::md, textlane::html,
textlane::mdx and textlane::nl, and its options are the struct's fields.
use textlane::{Processor, html, md};
let processor = Processor::new()
.with(md::Parse::default())
.with(md::ToHtml::default())
.with(html::Stringify::default())
.freeze()?;
let output = processor.process("# Hello *world*")?;
output.value
// <h1>Hello <em>world</em></h1>md::Parse reads Markdown into mdast, md::ToHtml turns it into hast and
html::Stringify writes HTML. freeze checks that each stage takes the tree the one before
returns, and the frozen processor then handles any number of documents.
Adding syntax
Syntax extensions sit beside the parser. Add md::Gfm for tables, task lists, strikethrough
and autolinks, md::CjkFriendly for emphasis next to Chinese, Japanese and Korean text, and
md::Frontmatter to read a YAML block at the top:
use textlane::{Processor, html, md};
let output = Processor::new()
.with(md::Parse::default())
.with(md::Gfm::default())
.with(md::Frontmatter::default())
.with(md::ToHtml::default())
.with(html::Stringify::default())
.freeze()?
.process("---\ntitle: Notes\n---\n\n~~draft~~ done")?;
output.value
// <p><del>draft</del> done</p>Reading the result
process returns an Output: the text as value and the file, which holds the
messages plugins reported. Checks such as nl::RepeatedWords leave the text alone and
report a message:
use textlane::{Processor, md, nl};
let output = Processor::new()
.with(md::Parse::default())
.with(md::ToNaturalLanguage::default())
.with(nl::RepeatedWords)
.with(nl::Stringify)
.freeze()?
.process("It is the the best.")?;
output.file.messages[0].reason
// Unexpected repeated `the`, remove one occurrenceNext, the processor covers every method, and the plugin pages list each plugin with its options.
Created with ❤ and Livemark