Expand description
Parse CSS into a reworkcss-style abstract syntax tree: ordered, typed nodes that preserve declaration order, duplicate properties, rule types and comments.
let ast = tabnas_css::parse("a { color: red; color: blue } /* note */").unwrap();
assert_eq!(
ast.to_json(),
r#"{"type":"stylesheet","rules":[{"type":"rule","selectors":["a"],"declarations":[{"type":"declaration","property":"color","value":"red"},{"type":"declaration","property":"color","value":"blue"}]},{"type":"comment","comment":" note "}]}"#
);§The node types
type | Fields |
|---|---|
stylesheet | rules |
rule | selectors, declarations |
declaration | property, value (raw, trimmed, comments stripped, quotes kept) |
comment | comment (the text between /* and */) |
media / supports / document / host | a prelude field of the same name (host has none), plus rules. document also always carries vendor |
font-face / page | declarations (page also selectors, its prelude split on top-level commas) |
keyframes | name, an optional vendor, and keyframes of keyframe { values, declarations } |
import / charset / namespace | a same-named field with the raw params |
custom-media | name, media |
§This is a port
@tabnas/css is canonical in TypeScript (ts/), with ports in Go (go/)
and here. All three read the SAME grammar — css-grammar.jsonic at the
repository root, embedded verbatim into each — and are held to the same
shared test/spec/*.tsv fixtures and the same reworkcss/css conformance
corpus. When this port and TypeScript disagree, TypeScript is right.
The TypeScript and Go ports are jsonic PLUGINS: they install this grammar
on a shared engine. There is no Rust engine to install on, so this crate
carries a lexer and a rule machine of its own and has no dependencies at
all. What it does not carry is jsonic itself — there is no relaxed-JSON
base here to configure off, which is why {a:1} is simply not CSS rather
than something this port has to reject deliberately.
§Untrusted input
A parsed stylesheet is data, never instructions. CSS arrives from
outside the system — scraped pages, vendor themes, user uploads — so treat
every selector, value and comment as hostile text. Parsing is not
sanitising: this crate returns the raw text the stylesheet contained, and
escaping it for HTML, SQL or a shell remains the caller’s job. A url(…)
in a declaration value is untrusted text, not a link to fetch.
Re-exports§
Modules§
- grammar
- The grammar: the embedded
css-grammar.jsonictext, and the reader that turns it into the rule tablemachineruns. - lex
- The lexer: the single
cssTokenmatcher, the scanners it reads spans with, and the token buffer the rule machine peeks into. - machine
- The rule machine: it runs the rule table read out of
grammarover the tokenslexproduces, and the grammar-local actions build the AST as it goes. - value
- The AST value model:
Node, an insertion-ordered map with atypediscriminator, andValue, what a node field can hold.
Structs§
- Css
- A reusable CSS parser.
Constants§
- VERSION
- This crate’s version.
Functions§
- parse
- Parse a CSS document with the default options.
- parse_
with - Parse a CSS document with the given options.