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