Home

Awesome

snapdragon-node NPM version NPM monthly downloads NPM total downloads Linux Build Status

Class for creating AST nodes.

Please consider following this project's author, Jon Schlinkert, and consider starring the project to show your :heart: and support.

Install

Install with npm:

$ npm install --save snapdragon-node

Usage

const Node = require('snapdragon-node');
// either pass on object with "type" and (optional) "val"
const node1 = new Node({type: 'star', val: '*'});
// or pass "val" (first) and "type" (second) as string
const node2 = new Node('*', 'star');
// both result in => Node { type: 'star', val: '*' }

Snapdragon usage

With snapdragon v0.9.0 and higher, it's recommended that you use this.node() to create a new Node inside parser handlers (instead of doing new Node()).

Snapdragon ^1.0.0

Example usage inside a snapdragon parser handler function.

const Node = require('snapdragon-node');
const Token = require('snapdragon-token');

// create a new AST node
const node = new Node({ type: 'star', value: '*' });

// convert a Lexer Token into an AST Node
const token = new Token({ type: 'star', value: '*' });
const node = new Node(token);

Node objects

AST Nodes are represented as Node objects that implement the following interface:

interface Node {
  type: string;
  value: string | undefined
  nodes: array | undefined
}

A number of useful methods and non-enumerable properties are also exposed for adding, finding and removing child nodes, etc.

Continue reading the API documentation for more details.

Node API

Node

Create a new AST Node with the given type and value, or an object to initialize with.

Params

Example

console.log(new Node({ type: 'star', value: '*' }));
console.log(new Node('star', '*'));
// both result in => Node { type: 'star', value: '*' }

.clone

Return a clone of the node. Values that are arrays or plain objects are deeply cloned.

Example

const node = new Node({type: 'star', value: '*'});
consle.log(node.clone() !== node);
//=> true

.stringify

Return a string created from node.value and/or recursively visiting over node.nodes.

Example

const node = new Node({type: 'star', value: '*'});
consle.log(node.stringify());
//=> '*'

.push

Push a child node onto the node.nodes array.

Params

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
foo.push(bar);

.unshift

Unshift a child node onto node.nodes, and set node as the parent on child.parent.

Params

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
foo.unshift(bar);

.pop

Pop a node from node.nodes.

Example

const node = new Node({type: 'foo'});
node.push(new Node({type: 'a'}));
node.push(new Node({type: 'b'}));
node.push(new Node({type: 'c'}));
node.push(new Node({type: 'd'}));
console.log(node.nodes.length);
//=> 4
node.pop();
console.log(node.nodes.length);
//=> 3

.shift

Shift a node from node.nodes.

Example

const node = new Node({type: 'foo'});
node.push(new Node({type: 'a'}));
node.push(new Node({type: 'b'}));
node.push(new Node({type: 'c'}));
node.push(new Node({type: 'd'}));
console.log(node.nodes.length);
//=> 4
node.shift();
console.log(node.nodes.length);
//=> 3

.remove

Remove node from node.nodes.

Params

Example

node.remove(childNode);

.find

Get the first child node from node.nodes that matches the given type. If type is a number, the child node at that index is returned.

Params

Example

const child = node.find(1); //<= index of the node to get
const child = node.find('foo'); //<= node.type of a child node
const child = node.find(/^(foo|bar)$/); //<= regex to match node.type
const child = node.find(['foo', 'bar']); //<= array of node.type(s)

.has

Returns true if node.nodes array contains the given node.

Params

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
cosole.log(foo.has(bar)); // false
foo.push(bar);
cosole.log(foo.has(bar)); // true

.hasType

Return true if the node.nodes has the given type.

Params

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
foo.push(bar);

cosole.log(foo.hasType('qux'));          // false
cosole.log(foo.hasType(/^(qux|bar)$/));  // true
cosole.log(foo.hasType(['qux', 'bar'])); // true

.isType

Return true if the node is the given type.

Params

Example

const node = new Node({type: 'bar'});
cosole.log(node.isType('foo'));          // false
cosole.log(node.isType(/^(foo|bar)$/));  // true
cosole.log(node.isType(['foo', 'bar'])); // true

.isEmpty

Returns true if node.value is an empty string, or node.nodes does not contain any non-empty text nodes.

Params

Example

const node = new Node({type: 'text'});
node.isEmpty(); //=> true
node.value = 'foo';
node.isEmpty(); //=> false

.isInside

Returns true if the node has an ancestor node of the given type

Params

Example

const box = new Node({type: 'box'});
const marble = new Node({type: 'marble'});
box.push(marble);
marble.isInside('box'); //=> true

.siblings

Get the siblings array, or null if it doesn't exist.

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
const baz = new Node({type: 'baz'});
foo.push(bar);
foo.push(baz);

console.log(bar.siblings.length) // 2
console.log(baz.siblings.length) // 2

.index

Calculate the node's current index on node.parent.nodes, or -1 if the node does not have a parent, or is not on node.parent.nodes.

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
const baz = new Node({type: 'baz'});
const qux = new Node({type: 'qux'});
foo.push(bar);
foo.push(baz);
foo.unshift(qux);

console.log(bar.index) // 1
console.log(baz.index) // 2
console.log(qux.index) // 0

.prev

Get the previous node from the siblings array or null.

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
const baz = new Node({type: 'baz'});
foo.push(bar);
foo.push(baz);

console.log(baz.prev.type) // 'bar'

.next

Get the next element from the siblings array, or null if a next node does not exist.

Example

const parent = new Node({type: 'root'});
const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
const baz = new Node({type: 'baz'});
parent.push(foo);
parent.push(bar);
parent.push(baz);

console.log(foo.next.type) // 'bar'
console.log(bar.next.type) // 'baz'

.first

Get the first child node from node.nodes.

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
const baz = new Node({type: 'baz'});
const qux = new Node({type: 'qux'});
foo.push(bar);
foo.push(baz);
foo.push(qux);

console.log(foo.first.type) // 'bar'

.last

Get the last child node from node.nodes.

Example

const foo = new Node({type: 'foo'});
const bar = new Node({type: 'bar'});
const baz = new Node({type: 'baz'});
const qux = new Node({type: 'qux'});
foo.push(bar);
foo.push(baz);
foo.push(qux);

console.log(foo.last.type) // 'qux'

.depth

Get the node.depth. The root node has a depth of 0. Add 1 to child nodes for each level of nesting.

Example

const foo = new Node({type: 'foo'});
foo.push(bar);

console.log(foo.depth) // 1
console.log(bar.depth) // 2

Node#isNode

Static method that returns true if the given value is a node.

Params

Example

const Node = require('snapdragon-node');
const node = new Node({type: 'foo'});
console.log(Node.isNode(node)); //=> true
console.log(Node.isNode({})); //=> false

Non-enumerable properties

Release history

See the changelog.

About

<details> <summary><strong>Contributing</strong></summary>

Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.

Please read the contributing guide for advice on opening issues, pull requests, and coding standards.

</details> <details> <summary><strong>Running Tests</strong></summary>

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

$ npm install && npm test
</details> <details> <summary><strong>Building docs</strong></summary>

(This project's readme.md is generated by verb, please don't edit the readme directly. Any changes to the readme must be made in the .verb.md readme template.)

To generate the readme, run the following command:

$ npm install -g verbose/verb#dev verb-generate-readme && verb
</details>

Related projects

You might also be interested in these projects:

Author

Jon Schlinkert

License

Copyright © 2018, Jon Schlinkert. Released under the MIT License.


This file was generated by verb-generate-readme, v0.8.0, on November 24, 2018.