Skip to main content

Crate tabnas_css

Crate tabnas_css 

Source
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

typeFields
stylesheetrules
ruleselectors, declarations
declarationproperty, value (raw, trimmed, comments stripped, quotes kept)
commentcomment (the text between /* and */)
media / supports / document / hosta prelude field of the same name (host has none), plus rules. document also always carries vendor
font-face / pagedeclarations (page also selectors, its prelude split on top-level commas)
keyframesname, an optional vendor, and keyframes of keyframe { values, declarations }
import / charset / namespacea same-named field with the raw params
custom-medianame, 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§

pub use lex::Error;
pub use machine::Options;
pub use value::Node;
pub use value::Value;

Modules§

grammar
The grammar: the embedded css-grammar.jsonic text, and the reader that turns it into the rule table machine runs.
lex
The lexer: the single cssToken matcher, 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 grammar over the tokens lex produces, and the grammar-local actions build the AST as it goes.
value
The AST value model: Node, an insertion-ordered map with a type discriminator, and Value, 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.