-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
67 lines (63 loc) · 2.38 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
const { convertV1ToV2, convertV2ToV1 } = require('idyll-ast').converters;
const AST = require('idyll-ast/v1');
const formatId = function(text) {
return text.replace(/['"]+/g, '').replace(/[\W_]+/g,"-");
}
const getText = function (node) {
const texts = [];
AST.walkNodes(AST.getChildren(node), (n) => {
if (typeof n === 'string') {
texts.push(n);
}
})
return texts.join('');
}
module.exports = (ast) => {
ast = convertV2ToV1(convertV2ToV1);
var timeBegin = process.hrtime();
console.log('Generating table of contents...');
let headings = AST.findNodes(ast, (node) => {
let type = node[0].toLowerCase();
return type === 'h1' || type == 'h2';
});
let tags = [];
let h = 'h1';
tags['h1'] = [];
tags['h2'] = [];
headings.forEach((node) => {
let text = getText(node);
let href = '#' + formatId(text);
let type = node[0].toLowerCase();
let element = AST.createNode('a', { href }, [text]);
//console.log(node, text, href, type, element)
if (h !== type && type === 'h1') {
tags[type].push(AST.createNode('ul', { id: 'list' }, tags['h2']));
tags['h2'] = [];
}
tags[type].push(AST.createNode('li', {}, [element]));
h = type;
});
if (h === 'h2' && tags['h2'] !== []) {
tags['h1'].push(AST.createNode('ul', { id: 'list' }, tags['h2']));
tags['h2'] = [];
}
let list = AST.createNode('ul', { id: 'list' }, tags['h1'])
let ASTwithID = ast;
ASTwithID = AST.modifyNodesByName(ASTwithID, 'h1', (node) => {
node = AST.setProperty(node, 'id', formatId(getText(node)))
return node;
});
ASTwithID = AST.modifyNodesByName(ASTwithID, 'h2', (node) => {
node = AST.setProperty(node, 'id', formatId(getText(node)))
return node;
});
let tocTitle = AST.createNode('h1', { id: 'tableofcontents' }, ['Table Of Contents']);
let textContainer = AST.createNode('div', { id: 'tocContainer' }, [tocTitle, list])
ASTwithID = AST.modifyNodesByName(ASTwithID, 'TableOfContents', (node) => {
return textContainer;
});
var timeEnd = process.hrtime(timeBegin);
var timeTaken = parseFloat(timeEnd[0]) + parseFloat(timeEnd[1]) / Math.pow(10, 9);
console.log('Generating table of contents done in %f seconds', timeTaken);
return convertV1ToV2(ASTwithID);
};