Gonzales PE is a CSS parser which plays nicely with preprocessors.
Currently those are supported: SCSS, Sass, LESS.
Try out Gonzales PE online: Gonzales PE Playground.
(1) To install command-line tool globally:
npm install -g git://github.com/tonyganch/gonzales-pe.git#dev
(2) To install parser as a project dependency:
npm install --save git://github.com/tonyganch/gonzales-pe.git#dev
(3) If for some reason you want to build files yourself:
# Clone the repo. git clone git@github.com:tonyganch/gonzales-pe.git # Go to dev branch. git checkout dev # Install project dependencies. npm install # Install git hooks and build files. npm run init
Basically there are a few things you can do:
The different type of tree nodes can be found in docs/node-types.md.
In examples below I assume that gonzales
is a parser module and parseTree
is some parsed css:
let gonzales = require('gonzales-pe'); let parseTree = gonzales.parse(css);
Creates a new node. Useful when you need to add something to a tree.
let css = 'a {color: tomato}'; let parseTree = gonzales.parse(css); let node = gonzales.createNode({ type: 'animal', content: 'panda' }); parseTree.content.push(node);
Parses a css string.
let css = 'a {color: tomato}'; let parseTree = gonzales.parse(css);
let less = 'a {$color: tomato}'; let parseTree = gonzales.parse(less, {syntax: 'less'});
let less = '$color: tomato'; let parseTree = gonzales.parse(less, {syntax: 'less', rule: 'declaration'});
Checks whether there is a child node of given type.
if (parseTree.contains('space')) { doSomething(); }
Calls a function for every child node in tree. If type
parameter is passed, calls a function only for child nodes of a given type. The main difference from parseTree.forEach()
is that this method loops through node list from the end to beginning.
parseTree.eachFor(function(childNode) { doSomething(childNode); });
// Remove all child spaces. parseTree.eachFor('space', function(spaceNode, i) { parseTree.removeChild(i); });
Gets the first child node. If type
parameter is passed, gets the first child node of a given type. If no node has been found, returns null
.
let node = parseTree.first(); node.content = 'panda';
let node = parseTree.first('multilineComment'); node.content = 'panda';
Calls a function for every child node in tree. If type
parameter is passed, calls a function only for child nodes of a given type. The main difference from parseTree.eachFor()
is that this method loops through node list from the beginnig to end.
parseTree.forEach(function(childNode) { doSomething(); });
parseTree.forEach('space', function(spaceNode) { doSomething(); });
Gets nth child of the parseTree
. If no node has been found, returns null
.
var node = parseTree.get(2); doSomething(node);
Inserts a node to a given position in parseTree
.
let node = gonzales.createNode({type: 'animal', content: 'panda'}); parseTree.insert(2, node);
Checks whether the node is of given type.
if (node.is('space')) { node.content = ''; }
Gets the last child node. If type
parameter is passed, gets the last child node of a given type. If no node has been found, returns null
.
let node = parseTree.last(); node.content = 'panda';
let node = parseTree.last('multilineComment'); node.content = 'panda';
Removes a child node at a given position.
// Swap nodes. var node = parseTree.removeChild(1); parseTree.insert(0, node);
Converts parse tree to JSON. Useful for printing.
Converts parse tree back to string according to original syntax.
let css = parseTree.toString();
Calls the function for every node in a tree including parseTree
itself.
parseTree.traverse(function(node, index, parent) { if (node.is('multilineComment')) { parent.removeChild(index); } else if (node.is('space')) { node.content = ' '; } });
This method should be called for a root node, because calling it for a child will be more time consuming.
Calls the function for every node of a given type. This means not just child nodes, but grandchilds and so on.
// Remove all comments. parseTree.traverseByType('multilineComment', function(node, index, parent) { parent.removeChild(index); });
This method should be called for a root node, because calling it for a child will be more time consuming.
Calls the function for every node of given types. This means not just child nodes, but grandchilds and so on.
// Remove all comments and spaces. let types = ['multilineComment', 'space']; parseTree.traverseByTypes(types, function(node, index, parent) { parent.removeChild(index); });
To run tests:
npm test
This command will build library files from sources and run tests on all files in syntax directories.
Every test has 3 files: source stylesheet, expected parse tree and expected string compiled back from parse tree to css.
If some tests fail, you can find information in test logs:
log/test.log
contains all information from stdout;log/expected.txt
contains only expected text;log/result.txt
contains only result text.The last two are made for your convenience: you can use any diff app to see the defference between them.
If you want to test one specific string or get a general idea of how Gonzales works, you can use test/ast.js
file.
Simply change the first two strings (css
and syntax
vars) and run:
node test/single-test.js
If you find a bug or want to add a feature, welcome to Issues.
If you are shy but have a question, feel free to drop me a line.