Skip to content

Commit c0cb8a8

Browse files
gibson042wooorm
authored andcommitted
Add support for visiting nodes of multiple types
Closes GH-10.
1 parent cd4e091 commit c0cb8a8

File tree

4 files changed

+74
-12
lines changed

4 files changed

+74
-12
lines changed

index.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
/* Expose. */
44
module.exports = visit;
55

6+
var is = require('unist-util-is');
7+
68
/* Visit. */
7-
function visit(tree, type, visitor, reverse) {
8-
if (typeof type === 'function') {
9+
function visit(tree, test, visitor, reverse) {
10+
if (typeof test === 'function' && typeof visitor !== 'function') {
911
reverse = visitor;
10-
visitor = type;
11-
type = null;
12+
visitor = test;
13+
test = null;
1214
}
1315

1416
one(tree);
@@ -19,7 +21,7 @@ function visit(tree, type, visitor, reverse) {
1921

2022
index = index || (parent ? 0 : null);
2123

22-
if (!type || node.type === type) {
24+
if (!test || node.type === test || is(test, node, index, parent || null)) {
2325
result = visitor(node, index, parent || null);
2426
}
2527

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
"files": [
2626
"index.js"
2727
],
28+
"dependencies": {
29+
"unist-util-is": "^2.1.1"
30+
},
2831
"devDependencies": {
2932
"browserify": "^14.0.0",
3033
"esmangle": "^1.0.0",

readme.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ Yields:
3939

4040
## API
4141

42-
### `visit(node[, type], visitor[, reverse])`
42+
### `visit(node[, test], visitor[, reverse])`
4343

44-
Visit nodes. Optionally by node type. Optionally in reverse.
44+
Visit nodes. Optionally filtering nodes. Optionally in reverse.
4545

4646
###### Parameters
4747

4848
* `node` ([`Node`][node])
4949
— Node to search
50-
* `type` (`string`, optional)
51-
— Node type
50+
* `test` ([`Test`][is], optional)
51+
— Node type or other [`is`][is]-compatible test
5252
* `visitor` ([Function][visitor])
5353
— Visitor invoked when a node is found
5454
* `reverse` (`boolean`, default: `false`)
@@ -59,7 +59,7 @@ Visit nodes. Optionally by node type. Optionally in reverse.
5959

6060
#### `stop? = visitor(node, index, parent)`
6161

62-
Invoked when a node (when `type` is given, matching `type`) is found.
62+
Invoked when a node (matching `test`, if given) is found.
6363

6464
###### Parameters
6565

@@ -114,4 +114,6 @@ Invoked when a node (when `type` is given, matching `type`) is found.
114114

115115
[node]: https://github.com/syntax-tree/unist#node
116116

117+
[is]: https://github.com/syntax-tree/unist-util-is#istest-node-index-parent-context
118+
117119
[visitor]: #stop--visitornode-index-parent

test.js

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ var tree = remark().parse('Some _emphasis_, **importance**, and `code`.');
99
var STOP = 5;
1010

1111
var textNodes = 6;
12+
var codeNodes = 1;
1213

1314
var types = [
1415
'root',
@@ -78,15 +79,69 @@ test('unist-util-visit', function (t) {
7879
st.end();
7980
});
8081

81-
t.test('should only visit given `types`', function (st) {
82+
t.test('should only visit a given `type`', function (st) {
8283
var n = 0;
8384

8485
visit(tree, 'text', function (node) {
8586
n++;
8687
st.equal(node.type, 'text');
8788
});
8889

89-
st.equal(n, textNodes, 'should visit all nodes');
90+
st.equal(n, textNodes, 'should visit all matching nodes');
91+
92+
st.end();
93+
});
94+
95+
t.test('should only visit given `type`s', function (st) {
96+
var n = 0;
97+
var types = ['text', 'inlineCode'];
98+
99+
visit(tree, types, function (node) {
100+
n++;
101+
st.ok(types.indexOf(node.type) !== -1, 'should be a requested type: ' + node.type);
102+
});
103+
104+
st.equal(n, textNodes + codeNodes, 'should visit all matching nodes');
105+
106+
st.end();
107+
});
108+
109+
t.test('should accept any `is`-compatible test', function (st) {
110+
var n = 0;
111+
var test = function (node, index) {
112+
return index > 3;
113+
};
114+
115+
visit(tree, test, function (node, index, parent) {
116+
n++;
117+
var parentType = parent && parent.type;
118+
st.ok(index > 3, 'should be a requested node: ' + parentType + '/[' + index + ']');
119+
});
120+
121+
st.equal(n, 3, 'should visit all matching nodes');
122+
123+
st.end();
124+
});
125+
126+
t.test('should accept an array of `is`-compatible tests', function (st) {
127+
var n = 0;
128+
var tests = [
129+
function (node) {
130+
return node.type === 'root';
131+
},
132+
'paragraph',
133+
{value: '.'},
134+
['emphasis', 'strong']
135+
];
136+
var expectedTypes = ['root', 'paragraph', 'emphasis', 'strong'];
137+
138+
visit(tree, tests, function (node) {
139+
n++;
140+
st.ok(expectedTypes.indexOf(node.type) !== -1 || node.value === '.',
141+
'should be a requested type: ' + node.type);
142+
});
143+
144+
st.equal(n, 5, 'should visit all matching nodes');
90145

91146
st.end();
92147
});

0 commit comments

Comments
 (0)