-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
127 lines (98 loc) · 3.81 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
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
'use strict';
var defaultOptions = {
tocRegexp: /@\[toc\]/im,
tocTitle: 'Table of Contents',
tocId: 'toc',
tocWrapperClass: 'toc',
tocLevelWrapperClass: 'toc-level',
anchorIdPrefix: 'h-',
reverseLink: false
};
module.exports = function (md, options) {
// Set default options
var options = Object.assign({}, defaultOptions, options);
// Global variables
var headingInfos = [];
md.inline.ruler.after('emphasis', 'toc', function (state, silent) {
if (silent) {
return false;
}
var match = options.tocRegexp.exec(state.src);
match = !match ? [] : match.filter(function (m) {
return m;
});
if (match.length < 1) {
return false;
}
var token;
token = state.push("toc_open", "toc", 1);
token.markup = match[0];
token = state.push("toc_body", "", 0);
token = state.push("toc_close", "toc", -1);
// to continue pasing, Update pos
state.pos = state.pos + match[0].length;
return true;
});
md.core.ruler.push('init_toc', function (state) {
// For each rendering, initialize heading count
var headingCounts = [null, 0, 0, 0, 0, 0, 0];
var tokens = state.tokens;
// Parses all heading information to render the TOC
for (var i = 0; i < tokens.length; i++)
if (tokens[i].type === 'heading_open') {
var tagLevel = parseInt(tokens[i].tag[1]);
var numbering = [];
headingCounts[tagLevel] += 1;
for (var j = 1; j < headingCounts.length; j++) {
if (j <= tagLevel) {
numbering.push(headingCounts[j]);
} else {
headingCounts[j] = 0;
}
}
var hInfo = {
numbering: numbering,
content: tokens[i + 1].content
};
headingInfos.push(hInfo);
}
});
md.renderer.rules.toc_open = function (tokens, index) {
return '<div id="' + options.tocId + '" class="' + options.tocWrapperClass + '"><h3>' + options.tocTitle + '</h3>';
}
md.renderer.rules.toc_close = function (token, index) {
return '</div>';
}
md.renderer.rules.toc_body = function (tokens, index) {
var results = [];
var previousLevel = 0;
for (var i = 0; i < headingInfos.length; i++) {
var hInfo = headingInfos[i];
var levelDiff = hInfo.numbering.length - previousLevel;
if (levelDiff > 0) {
for (var _ = 0; _ < levelDiff; _++) {
results.push('<ul class="' + options.tocLevelWrapperClass + '">');
}
} else if (levelDiff < 0) {
for (var _ = 0; _ > levelDiff; _--) {
results.push('</ul>');
}
}
var numberingStr = hInfo.numbering.join('.');
var anchor = options.anchorIdPrefix + numberingStr;
results.push('<li><a href="#' + anchor + '">' + numberingStr + '.</a> ' + hInfo.content + '</li>');
previousLevel = headingInfos[i].numbering.length;
}
// Add the remaining </ul> tags at end of TOC.
for (var i = 0; i < previousLevel; i++) {
results.push('</ul>');
}
return results.join('');
}
md.renderer.rules.heading_open = function (tokens, index) {
var hInfo = headingInfos.shift();
var numberingStr = hInfo.numbering.join('.');
var anchor = options.anchorIdPrefix + numberingStr;
return '<' + tokens[index].tag + '><a href="#' + (options.reverseLink ? options.tocId : anchor) + '" id="' + anchor + '">' + numberingStr + '.</a> ';
}
}