Skip to content

Commit 661eae1

Browse files
committed
Initial work on new functionality
1 parent 142ea38 commit 661eae1

File tree

7 files changed

+335
-0
lines changed

7 files changed

+335
-0
lines changed

.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Logs
2+
logs
3+
*.log
4+
*.swp
5+
npm-debug.log*
6+
.DS_Store
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
13+
# Directory for instrumented libs generated by jscoverage/JSCover
14+
lib-cov
15+
16+
# Coverage directory used by tools like istanbul
17+
coverage.lcov
18+
.nyc_output
19+
coverage
20+
21+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22+
.grunt
23+
24+
# node-waf configuration
25+
.lock-wscript
26+
27+
# Compiled binary addons (http://nodejs.org/api/addons.html)
28+
build/Release
29+
30+
# Dependency directory
31+
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
32+
node_modules
33+
34+
# Optional npm cache directory
35+
.npm
36+
37+
# Optional REPL history
38+
.node_repl_history
39+
40+
.idea/

example/example.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const remark = require('remark');
2+
const between = require('..');
3+
4+
const markdown = `
5+
# Example
6+
7+
**List one:**
8+
- 1
9+
- 2
10+
11+
**List two:**
12+
- 3
13+
- 4
14+
- 5
15+
16+
# End
17+
18+
**List three:**
19+
- 6
20+
- 7
21+
`;
22+
23+
// Create a plugin for remark
24+
const plugin = () => (tree) => {
25+
// `start` and `end` nodes to look for, and find between.
26+
const start = {
27+
type: 'heading',
28+
children: [
29+
{
30+
value: 'Example'
31+
}
32+
]
33+
};
34+
35+
const end = {
36+
type: 'heading',
37+
children: [
38+
{
39+
value: 'End'
40+
}
41+
]
42+
};
43+
44+
// Test for list types and paragraph types
45+
const test = (node) => node.type === 'list' || node.type === 'paragraph';
46+
47+
// Get lists between `start` and `end`
48+
const lists = between(tree, start, end, test);
49+
50+
// Store lists and their labels
51+
tree.children = lists;
52+
53+
// Return new tree
54+
return tree;
55+
};
56+
57+
remark()
58+
.use(plugin)
59+
.process(markdown)
60+
.then((result) => console.log(result.toString()), console.error);
61+
62+
/**
63+
* Outputs:
64+
*
65+
* **List one:**
66+
*
67+
* - 1
68+
* - 2
69+
*
70+
* **List two:**
71+
*
72+
* - 3
73+
* - 4
74+
* - 5
75+
*
76+
*/

example/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "unist-util-replace-between-example",
3+
"dependencies": {
4+
"remark": "^11.0.1"
5+
}
6+
}

index.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
const find = require('unist-util-find');
4+
5+
function replaceBetween(parent, start, end, func) {
6+
if (!parent || !parent.type || !parent.children) {
7+
throw new Error('Expected parent node');
8+
}
9+
10+
const {children} = parent;
11+
12+
const index = check(start);
13+
const length = check(end);
14+
15+
const replaced = children.splice(index, length - index + 1);
16+
17+
const changedArray = func(replaced);
18+
19+
children.splice(index, 0, ...changedArray);
20+
21+
return changedArray;
22+
23+
function check(index) {
24+
if (index && index.type) {
25+
const node = find(parent, index);
26+
index = children.indexOf(node);
27+
}
28+
29+
if (isNaN(index) || index < 0 || index === Infinity) {
30+
throw new Error('Expected positive finite index or child node');
31+
}
32+
33+
if (index >= children.length) {
34+
index = children.length - 1;
35+
}
36+
37+
return index;
38+
}
39+
}
40+
41+
module.exports = replaceBetween;

test.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
'use strict';
2+
3+
const {test} = require('tap');
4+
const findAllBetween = require('.');
5+
6+
test('unist-util-find-all-between', (test) => {
7+
test.throws(() => {
8+
findAllBetween();
9+
}, 'Should fail without parent node');
10+
11+
test.throws(() => {
12+
findAllBetween({type: 'foo'});
13+
}, 'Should fail without parent node');
14+
15+
test.doesNotThrow(() => {
16+
test.throws(() => {
17+
findAllBetween({type: 'foo', children: []});
18+
}, 'Expected positive finite index or child node');
19+
20+
test.throws(() => {
21+
findAllBetween({type: 'foo', children: []}, -1);
22+
}, 'Expected positive finite index or child node');
23+
24+
test.throws(() => {
25+
findAllBetween({type: 'foo', children: []}, {type: 'bar'});
26+
}, 'Expected positive finite index or child node');
27+
28+
test.throws(() => {
29+
findAllBetween({type: 'foo', children: []}, 1, {type: 'bar'});
30+
}, 'Expected positive finite index or child node');
31+
}, 'Should fail without index');
32+
33+
test.doesNotThrow(() => {
34+
test.ok(
35+
findAllBetween(
36+
{
37+
type: 'foo',
38+
children: [
39+
{
40+
type: 'foo'
41+
},
42+
{
43+
type: 'bar'
44+
}
45+
]
46+
},
47+
0,
48+
1,
49+
(v) => v
50+
)
51+
);
52+
}, 'Should not throw with `unist-util-is` >= 4.0.0');
53+
54+
test.doesNotThrow(() => {
55+
test.deepEqual(
56+
findAllBetween(
57+
{
58+
type: 'foo',
59+
children: [
60+
{
61+
type: 'foo'
62+
},
63+
{
64+
type: 'bar'
65+
},
66+
{
67+
type: 'baz'
68+
}
69+
]
70+
},
71+
0,
72+
2,
73+
(v) => v
74+
),
75+
[
76+
{
77+
type: 'foo'
78+
},
79+
{
80+
type: 'bar'
81+
},
82+
{
83+
type: 'baz'
84+
}
85+
]
86+
);
87+
}, 'Expects identity function to return the same');
88+
89+
test.doesNotThrow(() => {
90+
test.deepEqual(
91+
findAllBetween(
92+
{
93+
type: 'foo',
94+
children: [
95+
{
96+
type: 'foo'
97+
},
98+
{
99+
type: 'bar'
100+
},
101+
{
102+
type: 'baz'
103+
}
104+
]
105+
},
106+
0,
107+
2,
108+
(v) => [{type: 'test', data: v.length}]
109+
),
110+
[
111+
{
112+
type: 'test',
113+
data: 3
114+
}
115+
]
116+
);
117+
}, 'Replaces range with new output');
118+
119+
test.end();
120+
});

types/index.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// TypeScript Version: 3.5
2+
3+
import {Node, Parent} from 'unist';
4+
5+
export = findAllBetween;
6+
7+
/**
8+
* A unist utility to get all children of a parent between two nodes or indices.
9+
*
10+
* @param parent Parent node to search in
11+
* @param start A node or index to start search with
12+
* @param end A node or index to end search with
13+
* @param func The function ran to change the nodes
14+
*/
15+
declare function findAllBetween<T extends Node>(
16+
parent: Parent,
17+
start: Node | number,
18+
end: Node | number,
19+
func: (val: Node[]) => Node[]
20+
): Node[];

types/index.test-d.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {Node, Parent} from 'unist';
2+
import {expectError} from 'tsd';
3+
import between = require('.');
4+
5+
const n1: Node = {type: 'a', value: 'a'};
6+
const n2: Node = {type: 'b', value: 'b'};
7+
const parent: Parent = {type: 'root', children: [n1, n2]};
8+
9+
/**
10+
* Incorrect number of arguments
11+
*/
12+
expectError(between());
13+
expectError(between(parent));
14+
expectError(between(parent, n1));
15+
expectError(between(parent, n1, n2));
16+
17+
/**
18+
* Incorrect types of arguments
19+
*/
20+
expectError(between((v: Node[]) => v));
21+
expectError(between(parent, (v: Node[]) => v));
22+
expectError(between(parent, n1, (v: Node[]) => v));
23+
24+
/**
25+
* Incorrect test type
26+
*/
27+
expectError(between(parent, n1, n2, true));
28+
29+
/**
30+
* Correct test type
31+
*/
32+
between(parent, n1, n2, (v) => v);

0 commit comments

Comments
 (0)