# API Documentation *Please use only this documented API when working with the parser. Methods not documented here are subject to change at any point.* - [`parser` function](#parser-function) * [`parser.atword([props])`](#parseratwordprops) * [`parser.colon([props])`](#parsercolonprops) * [`parser.comma([props])`](#parsercommaprops) * [`parser.comment([props])`](#parsercommentprops) * [`parser.func([props])`](#parserfuncprops) * [`parser.number([props])`](#parsernumberprops) * [`parser.operator([props])`](#parseroperatorprops) * [`parser.paren([props])`](#parserparenprops) * [`parser.string([props])`](#parserstringprops) * [`parser.value([props])`](#parservalueprops) * [`parser.word([props])`](#parserwordprops) * [`parser.unicodeRange([props])`](#parserunicoderangeprops) - [Node types](#node-types) * [`node.type`](#nodetype) * [`node.parent`](#nodeparent) * [`node.toString()`, `String(node)`, or `'' + node`](#nodetostring-stringnode-or---node) * [`node.next()` & `node.prev()`](#nodenext--nodeprev) * [`node.replaceWith(node)`](#nodereplacewithnode) * [`node.remove()`](#noderemove) * [`node.clone()`](#nodeclone) * [`node.raws`](#noderaws) * [`node.source`](#nodesource) * [`node.sourceIndex`](#nodesourceindex) - [Container types](#container-types) * [`container.nodes`](#containernodes) * [`container.first` & `container.last`](#containerfirst--containerlast) * [`container.at(index)`](#containeratindex) * [`container.index(node)`](#containerindexnode) * [`container.length`](#containerlength) * [`container.each(callback)`](#containereachcallback) * [`container.walk(callback)`](#containerwalkcallback) * [`container.walk` proxies](#containerwalk-proxies) * [`container.prepend(node)` & `container.append(node)`](#containerprependnode--containerappendnode) * [`container.insertBefore(old, new)` & `container.insertAfter(old, new)`](#containerinsertbeforeold-new--containerinsertafterold-new) * [`container.removeChild(node)`](#containerremovechildnode) * [`container.removeAll()` or `container.empty()`](#containerremoveall-or-containerempty) - [Root nodes`](#root-nodes) - [Value nodes](#value-nodes) ## `parser` function This is the module's main entry point, and returns a `new Parser`. ```js let parser = require('postcss-values-parser'); let ast = parser(source) // tokenizes the source string .parse(); // parses the tokens and returns an AST ``` ### `parser.atword([props])` Creates a new AtWord value. ```js parser.atword({ value: '@foo' }); // → @foo ``` Arguments: * `props (object)`: The new node's properties. ### `parser.colon([props])` Creates a new colon Node. ```js parser.colon({ value: ':' }); // → : ``` Arguments: * `props (object)`: The new node's properties. If no properties are specified, the default value of `:` will be used. It's not recommended to deviate from this. ### `parser.comma([props])` Creates a new comma Node. ```js parser.comma({ value: ',' }); // → , ``` Arguments: * `props (object)`: The new node's properties. If no properties are specified, the default value of `,` will be used. It's not recommended to deviate from this. ### `parser.comment([props])` Creates a new comment. ```js parser.comment({ value: 'Affirmative, Dave. I read you.' }); // → /* Affirmative, Dave. I read you. */ ``` ```js parser.comment({ value: 'Affirmative, Dave. I read you.', inline: true }); // → // Affirmative, Dave. I read you. ``` Arguments: * `props (object)`: The new node's properties. ### `parser.func([props])` Creates a new function value Container node. ```js let func = parser.func({ value: 'calc' }); func.append(parser.paren()); func.append(parser.paren({ value: ')' })); func.toString(); // → calc() ``` Arguments: * `props (object)`: The new node's properties. ### `parser.number([props])` Creates a new number Node. ```js parser.number({ value: 10, unit: 'px' }); // → 10px ``` Arguments: * `props (object)`: The new node's properties. ### `parser.operator([props])` Creates a new operator Node. ```js parser.operator({ value: '+' }); // → + ``` Arguments: * `props (object)`: The new node's properties. ### `parser.paren([props])` Creates a new parenthesis Node. ```js parser.paren(); // → ( parser.paren({ value: ')' }); // → ) ``` Arguments: * `props (object)`: The new node's properties. If no value is specified, the default value of `(` will be used. ### `parser.string([props])` Creates a new string node. ```js parser.string(); // → (empty) parser.string({ value: 'hello', quote: '"' }); // → "hello" ``` Arguments: * `props (object)`: The new node's properties. Note: If no `quote` property is specified, the default value of `'` will be used. ### `parser.value([props])` Creates a new value Node. This node acts as the container for all values within the Root node, but can be created for convenience. ### `parser.word([props])` Creates a new word Node. A `Word` is anything that doesn't fall into one of the other node types. ```js let word = parser.word({ value: '#fff' }); // → #fff word.isHex; // → true word.isColor; // → true ``` Arguments: * `props (object)`: The new node's properties. ### `parser.unicodeRange([props])` Creates a new unicode range Node. ```js parser.unicodeRange({ value: 'U+26' }); // → U+26 ``` Arguments: * `props (object)`: The new node's properties. ## Node types ### `node.type` A string representation of the node type. It can be one of the following; `atword`, `colon`, `comma`, `comment`, `func`, `number`, `operator`, `paren`, `string`, `unicoderange`, `value`, `word`. ```js parser.word({ value: '#fff' }).type; // → 'word' ``` ### `node.parent` Returns the parent node. ```js root.nodes[0].parent === root; ``` ### `node.toString()`, `String(node)`, or `'' + node` Returns a string representation of the node. ```js let color = parser.word({ value: '#fff' }); console.log(String(color)); // → #fff ``` ### `node.next()` & `node.prev()` Returns the next/previous child of the parent node. ```js let next = func.next(); if (next && next.type !== 'paren') { throw new Error('Unclosed function parenthesis!'); } ``` ### `node.replaceWith(node)` Replace a node with another. ```js let ast = parser('#fff').parse(); let word = ast.first.first; let atword = parser.atword({ value: '@purple' }); word.replaceWith(atword); ``` Arguments: * `node`: The node to substitute the original with. ### `node.remove()` Removes the node from its parent node. ```js if (node.type === 'word') { node.remove(); } ``` ### `node.clone()` Returns a copy of a node, detached from any parent containers that the original might have had. ```js let word = parser.word({ value: '#fff' }); let cloned = word.clone(); cloned.value = '#fff'; String(cloned); // → #000 String(word); // → #fff ``` ### `node.raws` Extra whitespaces around the node will be assigned to `node.raws.before` and `node.raws.after`. Spaces in this context have no semantic meaning, but may be useful for inspection: ```css 1px solid black ``` Any space following a node/segement is assigned to the next node's `raws.before` property, unless the node with the trailing space is the only node in the set. ```js let source = 'calc(something about mary)'; let ast = parser(source).parse(); let func = ast.first.first; let something = func.first.next(); let about = something.next(); something.raws.after; // → (empty) about.raws.before; // → ' ' ``` Additionally, any space remaining after the last node in a set will be assigned to the last non-symbol child's `raws.after` property. For example: ```js let source = 'calc(something )'; let ast = parser(source).parse(); let func = ast.first.first; let something = func.first.next(); something.raws.after; // → ' ' ``` ### `node.source` An object describing the node's start/end, line/column source position. Within the following CSS, the `.bar` class node ... ```css .foo, .bar {} ``` ... will contain the following `source` object. ```js source: { start: { line: 2, column: 3 }, end: { line: 2, column: 6 } } ``` ### `node.sourceIndex` The zero-based index of the node within the original source string. Within the following CSS, the `.baz` class node will have a `sourceIndex` of `12`. ```css .foo, .bar, .baz {} ``` ## Container types The `root`, `node`, and `pseudo` nodes have some helper methods for working with their children. ### `container.nodes` An array of the container's children. ```js // Input: h1 h2 nodes.at(0).nodes.length // → 3 nodes.at(0).nodes[0].value // → 'h1' nodes.at(0).nodes[1].value // → ' ' ``` ### `container.first` & `container.last` The first/last child of the container. ```js node.first === node.nodes[0]; node.last === node.nodes[node.nodes.length - 1]; ``` ### `container.at(index)` Returns the node at position `index`. ```js node.at(0) === node.first; node.at(0) === node.nodes[0]; ``` Arguments: * `index`: The index of the node to return. ### `container.index(node)` Return the index of the node within its container. ```js node.index(node.nodes[2]) // → 2 ``` Arguments: * `node`: A node within the current container. ### `container.length` Proxy to the length of the container's nodes. ```js container.length === container.nodes.length ``` ### `container.each(callback)` Iterate the container's immediate children, calling `callback` for each child. You may return `false` within the callback to break the iteration. ```js let className; nodes.each(function (node, index) { if (node.type === 'class') { className = node.value; return false; } }); ``` Note that unlike `Array#forEach()`, this iterator is safe to use whilst adding or removing nodes from the container. Arguments: * `callback (function)`: A function to call for each node, which receives `node` and `index` arguments. ### `container.walk(callback)` Like `container#each`, but will also iterate child nodes as long as they are `container` types. ```js nodes.walk(function (node, index) { // all nodes }); ``` Arguments: * `callback (function)`: A function to call for each node, which receives `node` and `index` arguments. This iterator is safe to use whilst mutating `container.nodes`, like `container#each`. ### `container.walk` proxies The container class provides proxy methods for iterating over types of nodes, so that it is easier to write modules that target specific nodes. Those methods are: * `container.walkAtWords` * `container.walkColons` * `container.walkCommas` * `container.walkComments` * `container.walkFunctionNodes` * `container.walkNumberNodes` * `container.walkOperators` * `container.walkParenthesis` * `container.walkStringNodes` * `container.walkUnicodeRanges` * `container.walkWords` ### `container.prepend(node)` & `container.append(node)` Add a node to the start/end of the container. Note that doing so will set the parent property of the node to this container. ```js let color = parser.word({ value: '#fff' }); node.append(color); ``` Arguments: * `node`: The node to add. ### `container.insertBefore(old, new)` & `container.insertAfter(old, new)` Add a node before or after an existing node in a container: ```js nodes.walk(function (node) { if (node.type !== 'word') { let colon = parser.colon(); node.parent.insertAfter(node, colon); } }); ``` Arguments: * `old`: The existing node in the container. * `new`: The new node to add before/after the existing node. ### `container.removeChild(node)` Remove the node from the container. Note that you can also use `node.remove()` if you would like to remove just a single node. ```js node.length // → 2 node.remove(word) node.length // → 1; word.parent // undefined ``` Arguments: * `node`: The node to remove. ### `container.removeAll()` or `container.empty()` Remove all children from the container. ```js node.removeAll(); node.length // → 0 ``` ## Root nodes` A root node represents the top-level Container for Value nodes. Indeed, all a root's `toString()` method does is join its node children with a ','. Other than this, it has no special functionality and acts like a container. ## Value nodes A Value node represents a single compound node. For example, this node string `1px solid black`, is represented as three distinct nodes. It has no special functionality of its own.