Skip to content

Latest commit

 

History

History
405 lines (200 loc) · 7.74 KB

css-parser-algorithms.md

File metadata and controls

405 lines (200 loc) · 7.74 KB

Home > @csstools/css-parser-algorithms

css-parser-algorithms package

Parse CSS following the CSS Syntax Level 3 specification.

Remarks

The tokenizing and parsing tools provided by CSS Tools are designed to be low level and generic with strong ties to their respective specifications.

Any analysis or mutation of CSS source code should be done with the least powerful tool that can accomplish the task. For many applications it is sufficient to work with tokens. For others you might need to use @csstools/css-parser-algorithms or a more specific parser.

The implementation of the AST nodes is kept lightweight and simple. Do not expect magic methods, instead assume that arrays and class instances behave like any other JavaScript.

Example 1

Parse a string of CSS into a component value:

import { tokenize } from '@csstools/css-tokenizer';
import { parseComponentValue } from '@csstools/css-parser-algorithms';

const myCSS = `calc(1px * 2)`;

const componentValue = parseComponentValue(tokenize({
	css: myCSS,
}));

console.log(componentValue);

Example 2

Use the right algorithm for the job.

Algorithms that can parse larger structures (comma-separated lists, ...) can also parse smaller structures. However, the opposite is not true.

If your context allows a list of component values, use parseListOfComponentValues():

import { tokenize } from '@csstools/css-tokenizer';
import { parseListOfComponentValues } from '@csstools/css-parser-algorithms';

parseListOfComponentValues(tokenize({ css: `10x 20px` }));

If your context allows a comma-separated list of component values, use parseCommaSeparatedListOfComponentValues():

import { tokenize } from '@csstools/css-tokenizer';
import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';

parseCommaSeparatedListOfComponentValues(tokenize({ css: `20deg, 50%, 30%` }));

Example 3

Use the stateful walkers to keep track of the context of a given component value.

import { tokenize } from '@csstools/css-tokenizer';
import { parseComponentValue, isSimpleBlockNode } from '@csstools/css-parser-algorithms';

const myCSS = `calc(1px * (5 / 2))`;

const componentValue = parseComponentValue(tokenize({ css: myCSS }));

let state = { inSimpleBlock: false };
componentValue.walk((entry) => {
	if (isSimpleBlockNode(entry)) {
		entry.state.inSimpleBlock = true;
		return;
	}

	if (entry.state.inSimpleBlock) {
		console.log(entry.node.toString()); // `5`, ...
	}
}, state);

Classes

Class

Description

CommentNode

FunctionNode

A function node.

SimpleBlockNode

A simple block node.

TokenNode

WhitespaceNode

Abstract Classes

Abstract Class

Description

ContainerNodeBaseClass

Enumerations

Enumeration

Description

ComponentValueType

Functions

Function

Description

forEach(componentValues, cb, state)

Iterates over each item in a list of component values.

gatherNodeAncestry(node)

AST nodes do not have a parent property or method. This makes it harder to traverse the AST upwards. This function builds a Map<Child, Parent> that can be used to lookup ancestors of a node.

isCommentNode(x)

Check if the current object is a CommentNode. This is a type guard.

isFunctionNode(x)

Check if the current object is a FunctionNode. This is a type guard.

isSimpleBlockNode(x)

Check if the current object is a SimpleBlockNode. This is a type guard.

isTokenNode(x)

Check if the current object is a TokenNode. This is a type guard.

isWhitespaceNode(x)

Check if the current object is a WhitespaceNode. This is a type guard.

parseCommaSeparatedListOfComponentValues(tokens, options)

Parse a comma-separated list of component values.

parseComponentValue(tokens, options)

Parse a single component value.

parseListOfComponentValues(tokens, options)

Parse a list of component values.

replaceComponentValues(componentValuesList, replaceWith)

Replace specific component values in a list of component values. A helper for the most common and simplistic cases when mutating an AST.

sourceIndices(x)

Returns the start and end index of a node in the CSS source string.

stringify(componentValueLists)

Concatenate the string representation of a collection of component values. This is not a proper serializer that will handle escaping and whitespace. It only produces valid CSS for token lists that are also valid.

walk(componentValues, cb, state)

Walks each item in a list of component values all of their children.

walkerIndexGenerator(initialList)

Generate a function that finds the next element that should be visited when walking an AST. Rules : 1. the previous iteration is used as a reference, so any checks are relative to the start of the current iteration. 2. the next element always appears after the current index. 3. the next element always exists in the list. 4. replacing an element does not cause the replaced element to be visited. 5. removing an element does not cause elements to be skipped. 6. an element added later in the list will be visited.

Type Aliases

Type Alias

Description

ComponentValue

ContainerNode