-
Notifications
You must be signed in to change notification settings - Fork 2
/
mdMenu.js
101 lines (82 loc) · 2.93 KB
/
mdMenu.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
var fs = require('fs');
var args = process.argv.slice(2);
var options = {};
// Parse options if it exist (e.g. --source='custom.md')
args.length && args.forEach(function(option) {
var optionArr = option.split('=');
options[optionArr[0].replace('--', '')] = optionArr[1];
});
Object.prototype.merge = function(obj) {
if (typeof obj !== 'object') return;
for (var prop in obj) {
if (this.hasOwnProperty(prop) &&
obj.hasOwnProperty(prop)) {
this[prop] = obj[prop];
}
}
return this;
};
var config = {
source: 'README.md',
destination: 'README.md',
cascade: 'true',
firstLevel: 2,
menuTitle: '## Table of Contents',
placeholder: '<!--mdMenu-->'
};
config.merge(options);
fs.readFile(config.source, function(err, data) {
if (err) throw err;
// Matches to all headers in document (by default: /#{2,6}\s.+/g)
var headerRegexp = new RegExp('#{' + config.firstLevel + ',6}\\s.+', 'g');
// todo: check this regexp if more than 1 menu are on a page
// Matches to placeholders with/without menu (by default: /<!--mdMenu-->[\s\S]*<!--mdMenu-->/)
var menuRegexp = new RegExp(config.placeholder + '[\\s\\S]*' + config.placeholder);
var content = data.toString();
var headersArr = content.match(headerRegexp);
var br = '\r\n';
var menu;
var res;
if (headersArr === null || !headersArr.length) {
console.log('No headers were found.');
return;
}
menu = headersArr
// Remove title of menu from menu (config.menuTitle)
.filter(function (header) {
return header !== config.menuTitle;
})
// Getting md links
.map(function(header) {
var tabs = '';
var link;
if (config.cascade === 'true') {
// Detect level of header
var level = (header.match(/#/g) || []).length;
// Save tabs if needed
tabs = new Array(level - config.firstLevel + 1).join('\t') + '* ';
}
// Normalize header
header = header.replace(/#{1,6}\s/g, '').trim();
// Create links like md parser does
link = '#' + header.replace(/[&\/]/g, '').replace(/\s/g, '-').toLowerCase();
return tabs + '[' + header + '](' + link + ')';
})
// Concat
.join('\r\n');
if (config.menuTitle) {
menu = config.placeholder + br + config.menuTitle + br + menu + br + config.placeholder;
} else {
menu = config.placeholder + br + menu + br + config.placeholder;
}
// If no placeholders - paste in the beginning of document
if (content.indexOf(config.placeholder) !== -1) {
res = content.replace(menuRegexp, menu);
} else {
res = menu + br + br + content;
}
fs.writeFile(config.destination, res, function (err) {
if (err) throw err;
console.log('Menu was built.');
});
});