3 [![NPM version][npm-img]][npm]
4 [![Build Status][travis-img]][travis]
5 [![AppVeyor Build Status][appveyor-img]][appveyor]
7 [npm-img]: https://img.shields.io/npm/v/gonzales-pe.svg
8 [npm]: https://www.npmjs.com/package/gonzales-pe
9 [travis-img]: https://travis-ci.org/tonyganch/gonzales-pe.svg
10 [travis]: https://travis-ci.org/tonyganch/gonzales-pe
11 [appveyor-img]: https://ci.appveyor.com/api/projects/status/m29jphtrqt398v2o/branch/dev?svg=true
12 [appveyor]: https://ci.appveyor.com/project/tonyganch/gonzales-pe/branch/dev
14 Gonzales PE is a CSS parser which plays nicely with preprocessors.
15 Currently those are supported: SCSS, Sass, LESS.
16 Try out Gonzales PE online: [Gonzales PE Playground](https://tonyganch.io/gonzales-pe/).
20 (1) To install command-line tool globally:
23 npm install -g git://github.com/tonyganch/gonzales-pe.git#dev
26 (2) To install parser as a project dependency:
29 npm install --save git://github.com/tonyganch/gonzales-pe.git#dev
32 (3) If for some reason you want to build files yourself:
36 git clone git@github.com:tonyganch/gonzales-pe.git
39 # Install project dependencies.
41 # Install git hooks and build files.
47 Basically there are a few things you can do:
49 1. parse css string and get a parse tree in return;
52 4. add new nodes to the tree;
53 5. convert modified tree back to a string.
55 The different type of tree nodes can be found in [docs/node-types.md](https://github.com/tonyganch/gonzales-pe/blob/dev/docs/node-types.md).
57 In examples below I assume that `gonzales` is a parser module and `parseTree`
61 let gonzales = require('gonzales-pe');
62 let parseTree = gonzales.parse(css);
65 ### gonzales.createNode(options)
69 Creates a new node. Useful when you need to add something to a tree.
75 <td><i>{Object}</i></td>
77 <td>Options to pass to a `Node` constructor.</td>
86 <td><i>{Object}</i></td>
94 let css = 'a {color: tomato}';
95 let parseTree = gonzales.parse(css);
96 let node = gonzales.createNode({ type: 'animal', content: 'panda' });
97 parseTree.content.push(node);
101 ### gonzales.parse(css[, options])
111 <td><i>{string}</i></td>
113 <td>A string to parse.</td>
116 <td><i>{Object=}</i></td>
118 <td>Optional. Additional options:
121 <code>{string} syntax</code> — any of the following: <code>css</code>,
122 <code>less</code>, <code>sass</code>, <code>scss</code>.
123 Default one is <code>css</code>.
126 <code>{string} context</code> — root node's type. For a list of available
127 values see <a href="docs/node-types.md">"Node types"</a>. Default
128 one is <code>stylesheet</code>.
131 <code>{number} tabSize</code> — size of a tab character in spaces.
143 <td><i>{Object}</i></td>
151 let css = 'a {color: tomato}';
152 let parseTree = gonzales.parse(css);
156 let less = 'a {$color: tomato}';
157 let parseTree = gonzales.parse(less, {syntax: 'less'});
161 let less = '$color: tomato';
162 let parseTree = gonzales.parse(less, {syntax: 'less', rule: 'declaration'});
165 ### parseTree.contains(type)
169 Checks whether there is a child node of given type.
175 <td><i>{string}</i></td>
178 Node type we're looking for. For a list of available values see
179 <a href="docs/node-types.md">"Node types"</a>.
188 <td><i>{boolean}</i></td>
190 <code>true</code> if a tree contains a child node of a given type,
191 <code>false</code> otherwise.
199 if (parseTree.contains('space')) {
204 ### parseTree.content
210 <td><i>{string|Array}</i></td>
211 <td>Node's content (child nodes or a string).</td>
215 ### parseTree.eachFor([type, ]callback)
219 Calls a function for every child node in tree. If `type` parameter is passed,
220 calls a function only for child nodes of a given type. The main difference from
221 `parseTree.forEach()` is that this method loops through node list from the end
228 <td><i>{string=}</i></td>
231 Optional. A node type by which to filter child nodes before applying
232 a callback function. For a list of available values see
233 <a href="docs/node-types.md">"Node types"</a>.
237 <td><i>{Function}</i></td>
240 Function to call for every child node. Accepts following parameters:
242 <li><code>{Object}</code> — a child node;</li>
243 <li><code>{number}</code> — index of the child node in node list;</li>
245 <code>{Object}</code> — parent node (equals to <code>parseTree</code>).
255 parseTree.eachFor(function(childNode) {
256 doSomething(childNode);
261 // Remove all child spaces.
262 parseTree.eachFor('space', function(spaceNode, i) {
263 parseTree.removeChild(i);
273 <td><i>{Object}</i></td>
275 End position of the node. Contains following info:
278 <code>{number} line</code> — last symbol's line number
282 <code>{number} column</code> — last symbol's column number
290 ### parseTree.first([type])
294 Gets the first child node. If `type` parameter is passed, gets the first child
295 node of a given type. If no node has been found, returns `null`.
301 <td><i>{string=}</i></td>
304 Optional. Node type to look for. For a list of available values see
305 <a href="docs/node-types.md">"Node types"</a>.
314 <td><i>{?Object}</i></td>
322 let node = parseTree.first();
323 node.content = 'panda';
327 let node = parseTree.first('multilineComment');
328 node.content = 'panda';
331 ### parseTree.forEach([type, ]callback)
335 Calls a function for every child node in tree. If `type` parameter is passed,
336 calls a function only for child nodes of a given type. The main difference from
337 `parseTree.eachFor()` is that this method loops through node list from the
344 <td><i>{string=}</i></td>
347 Optional. A node type by which to filter child nodes before applying
348 a callback function. For a list of available values see
349 <a href="docs/node-types.md">"Node types"</a>.
353 <td><i>{Function}</i></td>
356 Function to call for every child node. Accepts following parameters:
358 <li><code>{Object}</code> — a child node;</li>
359 <li><code>{number}</code> — index of the child node in node list;</li>
361 <code>{Object}</code> — parent node (equals to <code>parseTree</code>).
371 parseTree.forEach(function(childNode) {
377 parseTree.forEach('space', function(spaceNode) {
382 ### parseTree.get(index)
386 Gets *nth* child of the `parseTree`. If no node has been found, returns `null`.
392 <td><i>{number}</i></td>
394 <td>Index number of node which we're looking for.</td>
402 <td><i>{?Object}</i></td>
410 var node = parseTree.get(2);
414 ### parseTree.insert(index, node)
418 Inserts a node to a given position in `parseTree`.
424 <td><i>{number}</i></td>
426 <td>Index of position where to insert the node.</td>
429 <td><i>{Object}</i></td>
431 <td>A node to insert.</td>
438 let node = gonzales.createNode({type: 'animal', content: 'panda'});
439 parseTree.insert(2, node);
442 ### parseTree.is(type)
446 Checks whether the node is of given type.
452 <td><i>{string}</i></td>
455 A node type against which to check type of <code>parseTree</code>.
456 For a list of available values see
457 <a href="docs/node-types.md">"Node types"</a>.
466 <td><i>{boolean}</i></td>
468 <code>true</code> if types are equal, <code>false</code> otherwise.
476 if (node.is('space')) {
481 ### parseTree.last(type)
483 Gets the last child node. If `type` parameter is passed, gets the last child
484 node of a given type. If no node has been found, returns `null`.
490 <td><i>{string=}</i></td>
493 Optional. Node type to look for. For a list of available values see
494 <a href="docs/node-types.md">"Node types"</a>.
503 <td><i>{?Object}</i></td>
511 let node = parseTree.last();
512 node.content = 'panda';
516 let node = parseTree.last('multilineComment');
517 node.content = 'panda';
526 <td><i>{number}</i></td>
527 <td>Number of child nodes.</td>
531 ### parseTree.removeChild(index)
535 Removes a child node at a given position.
541 <td><i>{number}</i></td>
543 <td>Index of a child node we need to remove.</td>
551 <td><i>{Object}</i></td>
552 <td>Removed node.</td>
559 var node = parseTree.removeChild(1);
560 parseTree.insert(0, node);
569 <td><i>{Object}</i></td>
571 Start position of the node. Contains following info:
574 <code>{number} line</code> — first symbol's line number
578 <code>{number} column</code> — first symbol's column number
593 <td><i>{string}</i></td>
594 <td>Syntax of original parsed string.</td>
598 ### parseTree.toJson()
602 Converts parse tree to JSON. Useful for printing.
608 <td><i>{Object}</i></td>
609 <td>Parse tree in JSON</td>
613 ### parseTree.toString()
617 Converts parse tree back to string according to original syntax.
623 <td><i>{string}</i></td>
624 <td>A compiled string.</td>
631 let css = parseTree.toString();
634 ### parseTree.traverse(callback)
638 Calls the function for every node in a tree including `parseTree` itself.
644 <td><i>{Function}</i></td>
647 Function to apply to every node. Accepts following parameters:
649 <li><code>{Object}</code> — a node to which we apply callback;</li>
650 <li><code>{number}</code> — node's index number inside its parent;</li>
651 <li><code>{Object}</code> — a node's parent;</li>
653 <code>{number}</code> — node's nesting level relative to its parent.
663 parseTree.traverse(function(node, index, parent) {
664 if (node.is('multilineComment')) {
665 parent.removeChild(index);
666 } else if (node.is('space')) {
672 ### parseTree.traverseByType(type, callback)
676 This method should be called for a root node, because calling it for a child
677 will be more time consuming.
678 Calls the function for every node of a given type. This means not just child
679 nodes, but grandchilds and so on.
685 <td><i>{string}</i></td>
688 Node type. For a list of available values please see
689 <a href="docs/node-types.md">"Node types"</a>.
693 <td><i>{Function}</i></td>
696 Function to apply to every node of a given type.
697 Accepts following parameters:
699 <li><code>{Object}</code> — a node to which we apply callback;</li>
700 <li><code>{number}</code> — node's index number inside its parent;</li>
701 <li><code>{Object}</code> — a node's parent.</li>
710 // Remove all comments.
711 parseTree.traverseByType('multilineComment', function(node, index, parent) {
712 parent.removeChild(index);
716 ### parseTree.traverseByTypes(types, callback)
720 This method should be called for a root node, because calling it for a child
721 will be more time consuming.
722 Calls the function for every node of given types. This means not just child
723 nodes, but grandchilds and so on.
729 <td><i>{Array.string}</i></td>
732 List of node types. For a list of available values please see
733 <a href="docs/node-types.md">"Node types"</a>.
737 <td><i>{Function}</i></td>
740 Function to apply to every node of given types.
741 Accepts following parameters:
743 <li><code>{Object}</code> — a node to which we apply callback;</li>
744 <li><code>{number}</code> — node's index number inside its parent;</li>
745 <li><code>{Object}</code> — a node's parent.</li>
754 // Remove all comments and spaces.
755 let types = ['multilineComment', 'space'];
756 parseTree.traverseByTypes(types, function(node, index, parent) {
757 parent.removeChild(index);
767 <td><i>{string}</i></td>
769 Node type. For a list of available values see
770 <a href="docs/node-types.md">"Node types"</a>.
782 This command will build library files from sources and run tests on all files
783 in syntax directories.
785 Every test has 3 files: source stylesheet, expected parse tree and expected
786 string compiled back from parse tree to css.
788 If some tests fail, you can find information in test logs:
790 - `log/test.log` contains all information from stdout;
791 - `log/expected.txt` contains only expected text;
792 - `log/result.txt` contains only result text.
794 The last two are made for your convenience: you can use any diff app to see
795 the defference between them.
797 If you want to test one specific string or get a general idea of how Gonzales
798 works, you can use `test/ast.js` file.
799 Simply change the first two strings (`css` and `syntax` vars) and run:
801 node test/single-test.js
805 If you find a bug or want to add a feature, welcome to [Issues](https://github.com/tonyganch/gonzales-pe/issues).
807 If you are shy but have a question, feel free to [drop me a
808 line](mailto:tonyganch+gonzales@gmail.com).