Skip to main content

oxc_css_parser/
lib.rs

1//! oxc-css-parser is a parser that can parse CSS, SCSS, Sass (indented syntax) and Less.
2//!
3//! ## Basic Usage
4//!
5//! This crate provides a simple API to get started.
6//!
7//! First, create a parser, give it the source code and specify the syntax,
8//! then call the [`parse`](Parser::parse) method:
9//!
10//! ```rust
11//! use oxc_css_parser::{Allocator, Parser, Syntax, ast::Stylesheet};
12//!
13//! let allocator = Allocator::default();
14//! let mut parser = Parser::new(&allocator, "a {}", Syntax::Css); // syntax can also be `Scss`, `Sass` or `Less`
15//! let result = parser.parse::<Stylesheet>();
16//! match result {
17//!     Ok(ast) => {
18//!         // parsed successfully
19//!         println!("{:#?}", ast);
20//!     }
21//!     Err(error) => {
22//!         // it failed, error message and position can be accessed via `error`
23//!         println!("{:#?}", error);
24//!     }
25//! }
26//! ```
27//!
28//! ## Advanced Usage
29//!
30//! ### Creating Parser with Builder
31//!
32//! If you need to control parser with additional features, you can use [`ParserBuilder`].
33//!
34//! For example, to collect comments:
35//!
36//! ```rust
37//! use oxc_css_parser::{Allocator, ParserBuilder, ast::Stylesheet};
38//!
39//! let allocator = Allocator::default();
40//! let builder = ParserBuilder::new(&allocator, "/* comment */ a {}").comments();
41//! let mut parser = builder.build();
42//! parser.parse::<Stylesheet>().unwrap();
43//! let comments = parser.comments();
44//! ```
45//!
46//! By default, syntax is CSS when using parser builder. You can customize it:
47//!
48//! ```rust
49//! use oxc_css_parser::{Allocator, ParserBuilder, Syntax};
50//!
51//! let allocator = Allocator::default();
52//! let builder = ParserBuilder::new(&allocator, "a {}").syntax(Syntax::Scss);
53//! ```
54//!
55//! ### Parser Options
56//!
57//! #### `try_parsing_value_in_custom_property`
58//!
59//! By default, value of custom property whose name starts with `--` will be parsed as tokens.
60//! If you want to parse it as normal declaration value, you can enable this option.
61//! Even though this option is enabled,
62//! parser will fallback to parse as tokens if there're syntax errors.
63//!
64//! ```rust
65//! use oxc_css_parser::{Allocator, ParserBuilder, ParserOptions, ast::*};
66//!
67//! let allocator = Allocator::default();
68//! let options = ParserOptions {
69//!     try_parsing_value_in_custom_property: true,
70//!     ..Default::default()
71//! };
72//! let builder = ParserBuilder::new(&allocator, "--foo: calc(var(--bar) + 1px)").options(options);
73//! let mut parser = builder.build();
74//!
75//! let declaration = parser.parse::<Declaration>().unwrap();
76//! assert!(matches!(declaration.value[0], ComponentValue::Function(..)));
77//! ```
78//!
79//! #### `template_placeholder`
80//!
81//! By default, a backtick is a syntax error outside Less. Setting this option
82//! makes the parser recognize a backtick-delimited token of the shape
83//! `` `<prefix><decimal index>` `` as an atomic
84//! [`Placeholder`](crate::ast::Placeholder) node (in value, selector, and
85//! statement positions) carrying the parsed index. The token terminates at the
86//! closing backtick, so a following identifier re-lexes separately. This is
87//! designed for downstream formatters that substitute template interpolations
88//! (e.g. CSS-in-JS `${expr}`) with such placeholders before parsing. It MUST be
89//! used with [`Syntax::Scss`] (backtick is Less's inline-JS delimiter).
90//!
91//! ```rust
92//! use oxc_css_parser::{Allocator, ParserBuilder, ParserOptions, Syntax, TemplatePlaceholder, ast::*};
93//!
94//! let allocator = Allocator::default();
95//! let options = ParserOptions {
96//!     template_placeholder: Some(TemplatePlaceholder {
97//!         prefix: "PLACEHOLDER-",
98//!     }),
99//!     ..Default::default()
100//! };
101//! let builder = ParserBuilder::new(&allocator, "a { width: `PLACEHOLDER-0`; }")
102//!     .syntax(Syntax::Scss)
103//!     .options(options);
104//! let mut parser = builder.build();
105//!
106//! assert!(parser.parse::<Stylesheet>().is_ok());
107//! ```
108//!
109//! ### Parse Partial Structure
110//!
111//! Sometimes you don't want to parse a full stylesheet.
112//! Say you only need to parse a qualified rule or even a single declaration.
113//! All you need to do is to update the generics of the [`parse`](Parser::parse) method.
114//!
115//! ```rust
116//! use oxc_css_parser::{Allocator, Parser, Syntax, ast::QualifiedRule};
117//!
118//! let allocator = Allocator::default();
119//! let mut parser = Parser::new(&allocator, "a {}", Syntax::Css);
120//! parser.parse::<QualifiedRule>();
121//! ```
122//!
123//! and
124//!
125//! ```rust
126//! use oxc_css_parser::{Allocator, Parser, Syntax, ast::Declaration};
127//!
128//! let allocator = Allocator::default();
129//! let mut parser = Parser::new(&allocator, "color: green", Syntax::Css);
130//! parser.parse::<Declaration>();
131//! ```
132//!
133//! Not all AST nodes support the usage above;
134//! technically, those nodes that implement [`Parse`] trait are supported.
135//!
136//! ### Retrieve Recoverable Errors
137//!
138//! There may be some recoverable errors which doesn't affect on producing AST.
139//! To retrieve those errors, use [`recoverable_errors`](Parser::recoverable_errors).
140//!
141//! ```rust
142//! use oxc_css_parser::{Allocator, Parser, Syntax, ast::Stylesheet};
143//!
144//! let allocator = Allocator::default();
145//! let mut parser = Parser::new(&allocator, "@keyframes kf { invalid {} }", Syntax::Css);
146//! let result = parser.parse::<Stylesheet>();
147//! assert!(result.is_ok());
148//! println!("{:?}", parser.recoverable_errors());
149//! ```
150//!
151//! ## Serialization
152//!
153//! Produced AST can be serialized by Serde, but this feature is disabled by default.
154//! You need to enable feature `serialize` manually:
155//!
156//! ```toml
157//! oxc-css-parser = { version = "*", features = ["serialize"] }
158//! ```
159//!
160//! Then you can pass AST to Serde.
161//!
162//! Note that oxc-css-parser only supports serialization. Deserialization isn't supported.
163
164pub use config::{ParserOptions, Syntax, TemplatePlaceholder};
165pub use oxc_allocator::Allocator;
166pub use parser::{Parse, Parser, ParserBuilder};
167pub use pos::Span;
168pub use tokenizer::token;
169
170pub mod ast;
171mod config;
172pub mod error;
173mod parser;
174pub mod pos;
175mod tokenizer;
176mod util;