Repository navigation
Home
Parsec is an HTML parser written in Rust. It reads a page the way a browser does, following the WHATWG HTML Standard, gives you a tree you can walk and change, finds what you're after with CSS selectors from Selectors Level 4, and writes the tree back out as HTML.
It's being built for the people who use Lexbor today, directly or through selectolax, PHP's Dom\HTMLDocument, nokolexbor or lazy_html. Lexbor is fast and follows the spec. What Parsec adds, or plans to, is the list Lexbor's users keep asking for: positions on nodes, a worst case that doesn't blow up, documents you can share across threads, XPath, selectors that match everything a static page can decide, and memory safety.
This wiki is Parsec's only documentation. There's no website and no rustdoc site yet, so the reference pages here list every public item, taken from the source on main.
Note
Parsec isn't released. There's nothing on crates.io yet, and the API can still change before 0.1.0.
You depend on it from git:
[dependencies]
parsec-html = { git = "https://github.com/parsec-html/parsec" }The package is parsec-html; the crate you use is parsec. You need Rust 1.88 or newer.
use parsec::css::SelectorList;
let doc = parsec::parse("<ul><li class=hit>one<li>two</ul>", false);
let hits = SelectorList::parse("li.hit").unwrap().select(&doc, doc.root());
assert_eq!(doc.text(hits[0]), "one");Everything marked ✅ ships on main, and cargo test checks it. The rest has an issue and a milestone, and Roadmap has the order.
| Area | Where it stands | |
|---|---|---|
| ✅ | Whole documents | The HTML Standard's tokenizer and tree builder, scripting on or off. Passes the html5lib tokenizer suite and every web-platform-tests tree-construction case that doesn't need JavaScript; Conformance has the counts. |
| ✅ | Fragments | Parsed in the context of any element as innerHTML does, SVG and MathML included. See Parsing. |
| ✅ | A tree you can walk | Nodes in one arena, addressed by NodeId, with parent, child and sibling links. See The document tree. |
| ✅ | Editing | Create, insert, move and remove nodes; set, add, rename and remove attributes; rename elements. See Editing. |
| ✅ | Serialization |
innerHTML, outerHTML, a start tag alone, or text. See Serialization. |
| ✅ | CSS selectors from Level 4 |
:has(), :is(), :where(), :not() with lists, :nth-child(An+B of S), :scope, attribute case flags and the form states. See Selectors. |
| ✅ | The tokenizer on its own | Feeding a Sink you write. See Tokenizer. |
| ✅ | Limits you choose | A time budget per parse, and a fixed cap on input size. See Limits and hostile input. |
| 📋 | Bytes in, encoding sniffed | #5, with the decoders in #25 |
| 📋 | Chunked input | #6 |
| 📋 | Parse errors | #7 |
| 📋 | Source positions | #8 |
| 📋 | A C API | #20 |
| 📋 | Python and WebAssembly packages | #23, #24 |
| 📋 | XPath | #31 |
| 📋 | A CSS parser | #28 |
| 📋 | URL parsing | #26 |
The marks mean the same on every page of this wiki:
- ✅ shipped, and
cargo testchecks it; - 🚧 in progress;
- 📋 planned, with an issue.
Parsec has one dependency (memchr) and one unsafe block. That's a fact about the code rather than something a test checks, so it gets no mark; Thread safety and memory safety explains both. Comparison with Lexbor lays the whole picture out module by module.
Start here
- Getting started: add Parsec, parse, select, read, edit, write out.
- FAQ
- Glossary: the HTML Standard's terms, and Parsec's own, in a sentence or two each.
Reference
-
Parsing:
parse,parse_with,Options,ParseError,MAX_INPUT,parse_fragment, quirks, scripting, input. -
The document tree:
Document,NodeId,Kind,Ns,AttrNs,Quirks, navigation, attributes, templates, the name helpers. -
Editing: every edit function,
EditError, and the rules edits keep. -
Serialization:
inner_html,outer_html,html_alone,text. - Selectors: what parses, what matches, what's refused, and where Lexbor differs.
-
Tokenizer:
Tokenizer,Sink,TextMode,Tag,Attrs,Doctype,preprocess.
How it works
- Architecture: the arena, spans into the source, the tokenizer and tree builder, the adoption agency, foreign content.
- Limits and hostile input: the budget, the size cap, and which inputs stay linear.
- Thread safety and memory safety
- Conformance: the suites, the counts, what's skipped and why.
- Benchmarks: what's been measured so far, and what hasn't.
Coming from Lexbor
- Comparison with Lexbor
- Moving from Lexbor: Lexbor's C calls next to Parsec's Rust ones.
The project
- Contributing: the Netweir sync, building, testing, fuzzing, the CLA.
- Roadmap
- Changelog: what's on main, and every release once there is one.
- Getting started, to go from an empty project to a parsed page.
- Glossary, for the HTML Standard's vocabulary.
- Changelog, for what has landed so far.
Parsec is Apache-2.0 and not yet released; these pages describe main. Found something wrong here? Open an issue or ask in Discussions.
Repository · Issues · Discussions · Roadmap · Security policy · Licence