120 lines
3.2 KiB
Markdown
120 lines
3.2 KiB
Markdown
# CSS Parser Algorithms
|
|
|
|
[<img alt="npm version" src="https://img.shields.io/npm/v/@csstools/css-parser-algorithms.svg" height="20">][npm-url]
|
|
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/workflows/test/badge.svg" height="20">][cli-url]
|
|
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
|
|
|
|
Implemented from : https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/
|
|
|
|
## API
|
|
|
|
[Read the API docs](./docs/css-parser-algorithms.md)
|
|
|
|
## Usage
|
|
|
|
Add [CSS Parser Algorithms] to your project:
|
|
|
|
```bash
|
|
npm install @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev
|
|
```
|
|
|
|
[CSS Parser Algorithms] only accepts tokenized CSS.
|
|
It must be used together with `@csstools/css-tokenizer`.
|
|
|
|
|
|
```js
|
|
import { tokenizer, TokenType } from '@csstools/css-tokenizer';
|
|
import { parseComponentValue } from '@csstools/css-parser-algorithms';
|
|
|
|
const myCSS = `@media only screen and (min-width: 768rem) {
|
|
.foo {
|
|
content: 'Some content!' !important;
|
|
}
|
|
}
|
|
`;
|
|
|
|
const t = tokenizer({
|
|
css: myCSS,
|
|
});
|
|
|
|
const tokens = [];
|
|
|
|
{
|
|
while (!t.endOfFile()) {
|
|
tokens.push(t.nextToken());
|
|
}
|
|
|
|
tokens.push(t.nextToken()); // EOF-token
|
|
}
|
|
|
|
const options = {
|
|
onParseError: ((err) => {
|
|
throw err;
|
|
}),
|
|
};
|
|
|
|
const result = parseComponentValue(tokens, options);
|
|
|
|
console.log(result);
|
|
```
|
|
|
|
### Available functions
|
|
|
|
- [`parseComponentValue`](https://www.w3.org/TR/css-syntax-3/#parse-component-value)
|
|
- [`parseListOfComponentValues`](https://www.w3.org/TR/css-syntax-3/#parse-list-of-component-values)
|
|
- [`parseCommaSeparatedListOfComponentValues`](https://www.w3.org/TR/css-syntax-3/#parse-comma-separated-list-of-component-values)
|
|
|
|
### Utilities
|
|
|
|
#### `gatherNodeAncestry`
|
|
|
|
The AST does not expose the entire ancestry of each node.
|
|
The walker methods do provide access to the current parent, but also not the entire ancestry.
|
|
|
|
To gather the entire ancestry for a a given sub tree of the AST you can use `gatherNodeAncestry`.
|
|
The result is a `Map` with the child nodes as keys and the parents as values.
|
|
This allows you to lookup any ancestor of any node.
|
|
|
|
```js
|
|
import { parseComponentValue } from '@csstools/css-parser-algorithms';
|
|
|
|
const result = parseComponentValue(tokens, options);
|
|
const ancestry = gatherNodeAncestry(result);
|
|
```
|
|
|
|
### Options
|
|
|
|
```ts
|
|
{
|
|
onParseError?: (error: ParseError) => void
|
|
}
|
|
```
|
|
|
|
#### `onParseError`
|
|
|
|
The parser algorithms are forgiving and won't stop when a parse error is encountered.
|
|
Parse errors also aren't tokens.
|
|
|
|
To receive parsing error information you can set a callback.
|
|
|
|
Parser errors will try to inform you about the point in the parsing logic the error happened.
|
|
This tells you the kind of error.
|
|
|
|
## Goals and non-goals
|
|
|
|
Things this package aims to be:
|
|
- specification compliant CSS parser
|
|
- a reliable low level package to be used in CSS sub-grammars
|
|
|
|
What it is not:
|
|
- opinionated
|
|
- fast
|
|
- small
|
|
- a replacement for PostCSS (PostCSS is fast and also an ecosystem)
|
|
|
|
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
|
|
[discord]: https://discord.gg/bUadyRwkJS
|
|
[npm-url]: https://www.npmjs.com/package/@csstools/css-parser-algorithms
|
|
|
|
[CSS Parser Algorithms]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms
|