easy-gonz
v0.0.3
Published
Parse CSS, Less, SCSS and indented Sass into one editable syntax tree that prints back byte for byte.
Maintainers
Readme
easy-gonz
English · 简体中文
Parse CSS, Less, SCSS and indented Sass into one editable syntax tree that prints back byte for byte.
easy-gonz is for tools that read or rewrite stylesheets: formatters, linters, codemods and dependency scanners.
It is a maintained fork of gonzales-pe 4.3.0 with the same API, node types and gonzales command, and it parses syntax that 4.3.0 rejects, such as Sass modules, CSS nesting and Less guards.
Unlike postcss, easy-gonz covers all four syntaxes with one parser and returns selectors and values as nodes, not strings.
Rename a variable and keep everything else
This script renames $w to $width in an SCSS file that uses Sass modules:
const gonzales = require('easy-gonz');
const ast = gonzales.parse(`@use 'sass:math';
.card {
width: math.div($w, 2); // half width
@include theme.shadow;
}`, { syntax: 'scss' });
// Rename $w to $width everywhere.
ast.traverseByType('variable', (node) => {
const name = node.first('ident');
if (name.content === 'w') name.content = 'width';
});
console.log(ast.toString());It prints:
@use 'sass:math';
.card {
width: math.div($width, 2); // half width
@include theme.shadow;
}Only the renamed variable changes: the comment, spacing and layout come back exactly as written.
gonzales-pe 4.3.0 throws on the same input (Please check validity of the block starting from line #4).
Get started
Install the package:
npm install easy-gonzPrint the tree of a rule as an outline; the first line is
-> stylesheet:printf 'a { color: red }' | npx gonzales -s css --simple -Check the round trip in code; it prints
true:node -e "const g = require('easy-gonz'); const src = '.a { &:hover { color: red } }'; console.log(g.parse(src).toString() === src)"
Coming from gonzales-pe, change one line, then read Migrate from gonzales-pe if your code matches on node types:
- const gonzales = require('gonzales-pe');
+ const gonzales = require('easy-gonz');Build on one tree that keeps every byte
- Rewrite without side effects:
parse(src).toString() === srcholds for every valid case of the official test suites below, comments, whitespace and indented Sass line endings (;,\r\n,\r,\f) included. - Write one tree walker for four syntaxes, down to selectors and values:
syntax: 'css' | 'less' | 'scss' | 'sass'all produce the same node types, and selectors, values, function arguments and interpolation are nodes too. - Parse today's stylesheets: Sass modules, CSS nesting,
:has(> a),:nth-child(… of S), media range syntax, Less guards, mixins,@{}/${}interpolation and$prop, and the indented Sass syntax improvements. - Keep going on broken CSS and Less: invalid statements become
rawnodes instead of errors, as in postcss. - Switch from gonzales-pe in one line: same
parse/createNode/NodeAPI andgonzalesoptions, no runtime dependencies, Node.js 6+.
Each valid case must parse, print back byte for byte, and match the structure of the reference parser (the postcss stack; indented Sass has none).
The check is gonz.mjs, run by npm run test:official against the suite versions pinned in suites.json; setup steps are in Run the official test suites.
| Suite | Syntax | Valid cases | easy-gonz | postcss stack |
| --- | --- | --: | --: | --: |
| WPT parsing tests | CSS | 4,414 | 100% | 99.9% |
| WPT <style> blocks | CSS | 715 | 100% | 98.0% |
| css-parsing-tests | CSS | 1,243 | 100% | 98.1% |
| sass-spec | SCSS | 11,456 | 100% | 99.5% |
| sass-spec | indented Sass | 348 | 100% | not supported |
| less.js test-data | Less | 285 | 100% | 87.4% |
The postcss stack is postcss, postcss-scss and postcss-less, with selectors and values re-parsed by postcss-selector-parser and postcss-value-parser. Every case it passes, easy-gonz passes too.
Know when another parser fits better
Use postcss with postcss-scss or postcss-less if you need its plugin ecosystem and do not need indented Sass. Use @csstools/css-parser-algorithms if you parse only CSS and want component values exactly as the CSS Syntax spec defines them. easy-gonz still throws on most invalid SCSS and indented Sass, so it is not an error-tolerant parser for those two syntaxes.
| Parser | Syntaxes | Selectors and values | Runtime deps | Node.js | | --- | --- | --- | --- | --- | | easy-gonz | CSS, Less, SCSS, Sass | Nodes | none | >=6 | | gonzales-pe 4.3.0 | CSS, Less, SCSS, Sass | Nodes | minimist | >=0.6 (declared) | | postcss 8 + postcss-scss / postcss-less | CSS, SCSS, Less | Strings; extra parsers needed | 3 | >=12 | | postcss-sass 0.5.0 | Sass, converted from a gonzales-pe 4.3.0 tree | Strings (postcss AST) | gonzales-pe 4.3.0, postcss | ^10, ^12, >=14 | | sugarss 5 | SugarSS, a different indented syntax | Strings (postcss AST) | postcss (peer) | >=18 | | sass-parser 0.4 (Sass team) | CSS, SCSS, Sass | Not assessed here | postcss, sass | >=18 | | @csstools/css-parser-algorithms 4 | CSS only | Generic component values | @csstools/css-tokenizer (peer) | >=20.19 |
Of these, only easy-gonz and gonzales-pe 4.3.0 read all four syntaxes with one API and give selectors and values their own nodes.
Read more
- Documentation index: every guide by task.
- API reference:
parseoptions, node methods, parsing errors and thegonzalescommand. - Node types: what each syntax produces and how nodes nest.
- Migrate from gonzales-pe: what stays the same and which trees change.
- Develop and test easy-gonz: corpus format,
npm testand the official suites. - CHANGELOG: changes in each version.
- easy-comb, the maintained CSScomb fork, is built on easy-gonz.
- Report bugs and ideas in issues.
License
MIT; forked from Gonzales PE by Tony Ganch, whose playground runs the original parser.
