@tbela99/css-parser
    Preparing search index...

    the ast tree returned by the parser is always a AstStyleSheet node. the other nodes are AstRule, AstAtRule, AstDeclaration, AstComment, AstInvalidRule, AstInvalidAtRule, AstInvalidDeclaration

    Ast rule tokens attribute is an array of Token representing the parsed selector. the sel attribute string that contains the rule's selector. modifying the sel attribute does not affect the tokens attribute, and similarly, changes to the tokens attribute do not update the sel attribute.


    import {AstRule, parseDeclarations, ParserOptions, transform, parseDeclarations} from '@tbela99/css-parser';

    const options: ParserOptions = {

    visitor: {

    async Rule(node: AstRule): AstRule {

    node.sel = '.foo,.bar,.fubar';

    node.chi.push(...await parseDeclarations('width: 3px'));
    return node;
    }
    }
    };

    const css = `

    .foo {

    height: calc(100px * 2/ 15);
    }
    `;

    const result = await transform(css, options);
    console.debug(result.code);

    // .foo,.bar,.fubar{height:calc(40px/3);width:3px}

    Ast at-rule tokens attribute is either null or an array of Token representing the parsed prelude. the val attribute string that contains the at-rule's prelude.

    modifying the val attribute does not affect the tokens attribute, and similarly, changes to the tokens attribute do not update the val attribute.

    import {ParserOptions, transform, AstAtRule} from '@tbela99/css-parser';

    const options: ParserOptions = {

    visitor: {

    AtRule: {

    media: (node: AstAtRule): AstAtRule => {

    node.val = 'all';
    return node
    }
    }
    }
    };

    const css = `

    @media screen {

    .foo {

    height: calc(100px * 2/ 15);
    }
    }
    `;

    const result = await transform(css, options);
    console.debug(result.code);

    // .foo{height:calc(40px/3)}

    Ast declaration nam attribute is the declaration name. the val attribute is an array of Token representing the declaration's value.


    import {AstDeclaration, EnumToken, LengthToken, ParserOptions, transform} from '@tbela99/css-parser';

    const options: ParserOptions = {

    visitor: {

    Declaration: {

    // called only for height declaration
    height: (node: AstDeclaration): AstDeclaration[] => {


    return [
    node,
    {

    typ: EnumToken.DeclarationNodeType,
    nam: 'width',
    val: [
    <LengthToken>{
    typ: EnumToken.LengthTokenType,
    val: 3,
    unit: 'px'
    }
    ]
    }
    ];
    }
    }
    }
    };

    const css = `

    .foo {
    height: calc(100px * 2/ 15);
    }
    .selector {
    color: lch(from peru calc(l * 0.8) calc(c * 0.7) calc(h + 180))
    }
    `;

    const result = await transform(css, options);
    console.debug(result.code);

    // .foo{height:calc(40px/3);width:3px}.selector{color:#0880b0}

    ast traversal is achieved using walk()


    import {walk} from '@tbela99/css-parser';

    const css = `
    body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }

    html,
    body {
    line-height: 1.474;
    }

    .ruler {

    height: 10px;
    }
    `;

    for (const {node, parent, root} of walk(ast)) {

    // do something with node
    }

    ast traversal can be controlled using a filter function. the filter function returns a value of type WalkerOption.


    import {EnumToken, transform, walk, WalkerOptionEnum} from '@tbela99/css-parser';

    const css = `
    body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }

    html,
    body {
    line-height: 1.474;
    }

    .ruler {

    height: 10px;
    }
    `;

    function filter(node) {

    if (node.typ == EnumToken.AstRule && node.sel.includes('html')) {

    // skip the children of the current node
    return WalkerOptionEnum.IgnoreChildren;
    }
    }

    const result = await transform(css);
    for (const {node} of walk(result.ast, filter)) {

    console.error([EnumToken[node.typ]]);
    }

    // [ "StyleSheetNodeType" ]
    // [ "RuleNodeType" ]
    // [ "DeclarationNodeType" ]
    // [ "RuleNodeType" ]
    // [ "DeclarationNodeType" ]
    // [ "RuleNodeType" ]
    // [ "DeclarationNodeType" ]

    the function walkValues() is used to walk the node attribute's tokens.


    import {AstDeclaration, EnumToken, transform, walkValues} from '@tbela99/css-parser';

    const css = `
    body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
    `;

    const result = await transform(css);
    const declaration = result.ast.chi[0].chi[0] as AstDeclaration;

    // walk the node attribute's tokens in reverse order
    for (const {value} of walkValues(declaration.val, null, null,true)) {

    console.error([EnumToken[value.typ], value.val]);
    }

    // [ "Color", "color" ]
    // [ "FunctionTokenType", "calc" ]
    // [ "Number", 0.15 ]
    // [ "Add", undefined ]
    // [ "Iden", "b" ]
    // [ "Whitespace", undefined ]
    // [ "FunctionTokenType", "calc" ]
    // [ "Number", 0.24 ]
    // [ "Add", undefined ]
    // [ "Iden", "g" ]
    // [ "Whitespace", undefined ]
    // [ "Iden", "r" ]
    // [ "Whitespace", undefined ]
    // [ "Iden", "display-p3" ]
    // [ "Whitespace", undefined ]
    // [ "FunctionTokenType", "var" ]
    // [ "DashedIden", "--base-color" ]
    // [ "Whitespace", undefined ]
    // [ "Iden", "from" ]