unist-util-visit-siblings-first
Breadth-first traversal for unist ASTs — visits siblings before descending into children.
Installation
deno add npm:unist-util-visit-siblings-first
bun add unist-util-visit-siblings-first
pnpm add unist-util-visit-siblings-first
yarn add unist-util-visit-siblings-first
npm install unist-util-visit-siblings-first
What it does
visit walks a unist tree in breadth-first order. It visits all siblings at a level first, then moves down to the next level.
Usage
import type {Parent} from "unist-util-visit-siblings-first";
import {visit} from "unist-util-visit-siblings-first";
const tree: Parent = {
type: "root",
children: [
{type: "1", children: [{type: "1.1"}, {type: "1.2"}]},
{type: "2", children: [{type: "2.1"}, {type: "2.2"}]},
],
};
visit(tree, (node, i, ancestors) => {
const ancestorTypes = ancestors.map((el) => el.type).join(", ");
console.log(`type: ${node.type}, index: ${i}, ancestors: [${ancestorTypes}]`);
return "CONTINUE";
});
Output:
type: root, index: undefined, ancestors: []
type: 1, index: 0, ancestors: [root]
type: 2, index: 1, ancestors: [root]
type: 1.1, index: 0, ancestors: [root, 1]
type: 1.2, index: 1, ancestors: [root, 1]
type: 2.1, index: 0, ancestors: [root, 2]
type: 2.2, index: 1, ancestors: [root, 2]
Traversal order for the example above:
root.
1, 2 (siblings at same level).
1.1, 1.2, 2.1, 2.2 (children level).
Example: skip subtree and exit
visit(tree, (node) => {
if (node.type === "1") return "SKIP";
if (node.type === "1.1") return "EXIT";
return "CONTINUE";
});
Example: remove node
visit(tree, (node, index, ancestors) => {
if (node.type === "2.1") {
const parent = ancestors.at(-1);
if (!parent || typeof index !== "number") return "CONTINUE";
parent.children.splice(index, 1);
return index;
}
return "CONTINUE";
});
Example: replace previous sibling and current node
visit(tree, (node, index, ancestors) => {
if (node.type === '2.2') {
const parent = ancestors.at(-1);
if (!parent || typeof index !== "number") return "CONTINUE";
const newNode = { type: "new-node", value: "Hello, world!"};
parent.children.splice(index - 1, 2, newNode);
return index - 1;
}
return "CONTINUE";
});
API
visit(tree, visitor, options)
Traverses a unist AST in breadth-first order.
Visits siblings before descending to children.
Parameters
tree — the root node of a compatible unist AST.
visitor — callback invoked for each node.
options — optional configs.
Returns
Nothing.
visitor(node, index, ancestors)
Callback invoked for each node.
The visitor receives the node, its index in
the parent's children, and the array of ancestor nodes from root to parent.
NOTE:
When a visitor modifies a sibling, it must return
the index of the changed sibling.
Otherwise you may encounter unexpected behavior.
If you only modify the current node or its children, returning an index is not required.
Parameters
node — a compatible unist AST node.
index — number index of node in parent's children, or undefined for root.
ancestors — array of ancestor Parent nodes from root to parent.
Returns
It must return one of:
"EXIT" to stop traversal,
"SKIP" to skip subtree (children),
"CONTINUE" to continue, or
- an index number to resume traversal at that index.
Options
Options for the visit function.
test
Optional test to filter nodes before visiting.
Uses the Test from unist-util-is to check if a node should be visited.
If provided, only nodes passing the test will invoke the visitor.
Example:
visit(
tree,
(node) => {
console.log('node type is "text"');
return "CONTINUE";
},
{ test: "text" }
);
Related
Contributing
Please see CONTRIBUTING.md for contribution guidelines.
License
MIT