Snapdragon utility for creating a new AST node in custom code, such as plugins.
Installations
npm install snapdragon-node
Releases
Unable to fetch releases
Developer
here-be
Developer Guide
Module System
CommonJS
Min. Node Version
>=4
Typescript Support
No
Node Version
11.1.0
NPM Version
6.4.1
Statistics
25 Stars
40 Commits
7 Forks
4 Watching
1 Branches
3 Contributors
Updated on 08 Nov 2024
Languages
JavaScript (100%)
Total Downloads
Cumulative downloads
Total Downloads
4,182,149,420
Last day
-4.6%
2,749,273
Compared to previous day
Last week
6%
16,114,328
Compared to previous week
Last month
38%
57,957,499
Compared to previous month
Last year
-21.7%
593,308,186
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dev Dependencies
5
snapdragon-node
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:
1$ npm install --save snapdragon-node
Usage
1const Node = require('snapdragon-node'); 2// either pass on object with "type" and (optional) "val" 3const node1 = new Node({type: 'star', val: '*'}); 4// or pass "val" (first) and "type" (second) as string 5const node2 = new Node('*', 'star'); 6// 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.
1const Node = require('snapdragon-node'); 2const Token = require('snapdragon-token'); 3 4// create a new AST node 5const node = new Node({ type: 'star', value: '*' }); 6 7// convert a Lexer Token into an AST Node 8const token = new Token({ type: 'star', value: '*' }); 9const node = new Node(token);
Node objects
AST Nodes are represented as Node
objects that implement the following interface:
1interface Node { 2 type: string; 3 value: string | undefined 4 nodes: array | undefined 5}
type
{string} - A string representing the node variant type. This property is often used for classifying the purpose or nature of the node, so that parsers or compilers can determine what to do with it.value
{string|undefined} (optional) - In general, value should only be a string whennode.nodes
is undefined. This is not reinforced, but is considered good practice. Use a different property name to store arbitrary strings on the node whennode.nodes
is an array.nodes
{array|undefined} (optional) - array of child nodes
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
type
{object|string}: Either an object to initialize with, or a string to be used as thenode.type
.value
{string|boolean}: If the first argument is a string, the second argument may be a string value to set onnode.value
.clone
{boolean}: When an object is passed as the first argument, pass true as the last argument to deep clone values before assigning them to the new node.returns
{Object}: node instance
Example
1console.log(new Node({ type: 'star', value: '*' })); 2console.log(new Node('star', '*')); 3// both result in => Node { type: 'star', value: '*' }
.clone
Return a clone of the node. Values that are arrays or plain objects are deeply cloned.
returns
{Object}: returns a clone of the node
Example
1const node = new Node({type: 'star', value: '*'}); 2consle.log(node.clone() !== node); 3//=> true
.stringify
Return a string created from node.value
and/or recursively visiting over node.nodes
.
returns
{String}
Example
1const node = new Node({type: 'star', value: '*'}); 2consle.log(node.stringify()); 3//=> '*'
.push
Push a child node onto the node.nodes
array.
Params
node
{Object}returns
{Number}: Returns the length ofnode.nodes
, likeArray.push
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3foo.push(bar);
.unshift
Unshift a child node onto node.nodes
, and set node
as the parent on child.parent
.
Params
node
{Object}returns
{Number}: Returns the length ofnode.nodes
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3foo.unshift(bar);
.pop
Pop a node from node.nodes
.
returns
{Number}: Returns the poppednode
Example
1const node = new Node({type: 'foo'});
2node.push(new Node({type: 'a'}));
3node.push(new Node({type: 'b'}));
4node.push(new Node({type: 'c'}));
5node.push(new Node({type: 'd'}));
6console.log(node.nodes.length);
7//=> 4
8node.pop();
9console.log(node.nodes.length);
10//=> 3
.shift
Shift a node from node.nodes
.
returns
{Object}: Returns the shiftednode
Example
1const node = new Node({type: 'foo'});
2node.push(new Node({type: 'a'}));
3node.push(new Node({type: 'b'}));
4node.push(new Node({type: 'c'}));
5node.push(new Node({type: 'd'}));
6console.log(node.nodes.length);
7//=> 4
8node.shift();
9console.log(node.nodes.length);
10//=> 3
.remove
Remove node
from node.nodes
.
Params
node
{Object}returns
{Object}: Returns the removed node.
Example
1node.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
type
{String}returns
{Object}: Returns a child node or undefined.
Example
1const child = node.find(1); //<= index of the node to get 2const child = node.find('foo'); //<= node.type of a child node 3const child = node.find(/^(foo|bar)$/); //<= regex to match node.type 4const child = node.find(['foo', 'bar']); //<= array of node.type(s)
.has
Returns true if node.nodes
array contains the given node
.
Params
type
{String}returns
{Boolean}
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3cosole.log(foo.has(bar)); // false 4foo.push(bar); 5cosole.log(foo.has(bar)); // true
.hasType
Return true if the node.nodes
has the given type
.
Params
type
{String}returns
{Boolean}
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3foo.push(bar); 4 5cosole.log(foo.hasType('qux')); // false 6cosole.log(foo.hasType(/^(qux|bar)$/)); // true 7cosole.log(foo.hasType(['qux', 'bar'])); // true
.isType
Return true if the node is the given type
.
Params
type
{String}returns
{Boolean}
Example
1const node = new Node({type: 'bar'}); 2cosole.log(node.isType('foo')); // false 3cosole.log(node.isType(/^(foo|bar)$/)); // true 4cosole.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
fn
{Function}: (optional) Filter function that is called onnode
and/or child nodes.isEmpty
will return false immediately when the filter function returns false on any nodes.returns
{Boolean}
Example
1const node = new Node({type: 'text'}); 2node.isEmpty(); //=> true 3node.value = 'foo'; 4node.isEmpty(); //=> false
.isInside
Returns true if the node has an ancestor node of the given type
Params
type
{String}returns
{Boolean}
Example
1const box = new Node({type: 'box'});
2const marble = new Node({type: 'marble'});
3box.push(marble);
4marble.isInside('box'); //=> true
.siblings
Get the siblings array, or null
if it doesn't exist.
returns
{Array}
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3const baz = new Node({type: 'baz'}); 4foo.push(bar); 5foo.push(baz); 6 7console.log(bar.siblings.length) // 2 8console.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
.
returns
{Number}
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3const baz = new Node({type: 'baz'}); 4const qux = new Node({type: 'qux'}); 5foo.push(bar); 6foo.push(baz); 7foo.unshift(qux); 8 9console.log(bar.index) // 1 10console.log(baz.index) // 2 11console.log(qux.index) // 0
.prev
Get the previous node from the siblings array or null
.
returns
{Object}
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3const baz = new Node({type: 'baz'}); 4foo.push(bar); 5foo.push(baz); 6 7console.log(baz.prev.type) // 'bar'
.next
Get the next element from the siblings array, or null
if a next node does not exist.
returns
{Object}
Example
1const parent = new Node({type: 'root'}); 2const foo = new Node({type: 'foo'}); 3const bar = new Node({type: 'bar'}); 4const baz = new Node({type: 'baz'}); 5parent.push(foo); 6parent.push(bar); 7parent.push(baz); 8 9console.log(foo.next.type) // 'bar' 10console.log(bar.next.type) // 'baz'
.first
Get the first child node from node.nodes
.
returns
{Object}: The first node, or undefiend
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3const baz = new Node({type: 'baz'}); 4const qux = new Node({type: 'qux'}); 5foo.push(bar); 6foo.push(baz); 7foo.push(qux); 8 9console.log(foo.first.type) // 'bar'
.last
Get the last child node from node.nodes
.
returns
{Object}: The last node, or undefiend
Example
1const foo = new Node({type: 'foo'}); 2const bar = new Node({type: 'bar'}); 3const baz = new Node({type: 'baz'}); 4const qux = new Node({type: 'qux'}); 5foo.push(bar); 6foo.push(baz); 7foo.push(qux); 8 9console.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.
returns
{Object}: The last node, or undefiend
Example
1const foo = new Node({type: 'foo'}); 2foo.push(bar); 3 4console.log(foo.depth) // 1 5console.log(bar.depth) // 2
Node#isNode
Static method that returns true if the given value is a node.
Params
node
{Object}returns
{Boolean}
Example
1const Node = require('snapdragon-node'); 2const node = new Node({type: 'foo'}); 3console.log(Node.isNode(node)); //=> true 4console.log(Node.isNode({})); //=> false
Non-enumerable properties
node.isNode
{boolean} - this value is set totrue
when a node is created. This can be useful in situationas as a fast alternative to usinginstanceof Node
if you need to determine if a value is anode
object.node.size
{number} - the number of child nodes that have been pushed or unshifted ontonode.nodes
using the node's API. This is useful for determining if nodes were added tonode.nodes
without usingnode.push()
ornode.unshift()
(for example:if (node.nodes && node.size !== node.nodes.length)
)node.parent
{object} (instance of Node)
Release history
See the changelog.
About
Contributing
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.
Running Tests
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:
1$ npm install && npm test
Building docs
(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:
1$ npm install -g verbose/verb#dev verb-generate-readme && verb
Related projects
You might also be interested in these projects:
- breakdance: Breakdance is a node.js library for converting HTML to markdown. Highly pluggable, flexible and easy… more | homepage
- snapdragon-capture: Snapdragon plugin that adds a capture method to the parser instance. | homepage
- snapdragon-cheerio: Snapdragon plugin for converting a cheerio AST to a snapdragon AST. | homepage
- snapdragon-util: Utilities for the snapdragon parser/compiler. | homepage
- snapdragon: Easy-to-use plugin system for creating powerful, fast and versatile parsers and compilers, with built-in source-map… more | homepage
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.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no SAST tool detected
Details
- Warn: no pull requests merged into dev branch
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Score
3
/10
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to snapdragon-node
snapdragon
Easy-to-use plugin system for creating powerful, fast and versatile parsers and compilers, with built-in source-map support.
snapdragon-util
Utilities for the snapdragon parser/compiler.
snapdragon-capture
Snapdragon plugin that adds a capture method to the parser instance.
snapdragon-lexer
Converts a string into an array of tokens, with useful methods for looking ahead and behind, capturing, matching, et cetera.