@subiz/widget-v4 4.1.37 → 4.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiled_src/chatbox/Typing.js +2 -2
- package/compiled_src/chatbox/Widget.js +6 -0
- package/compiled_src/lib.js +24 -5
- package/compiled_src/popup/popup.js +20 -2
- package/compiled_src/store/store.js +8 -0
- package/compiled_src/util/campaign.js +6 -2
- package/compiled_src/util/common.js +9 -5
- package/compiled_src/util/order.js +4 -2
- package/compiled_src/util/pubsub.js +6 -3
- package/dist/132.js +524 -524
- package/dist/18a02a9c54e.132.js +1 -0
- package/dist/18a02a9c54e.213.js +1 -0
- package/dist/18a02a9c54e.335.js +1 -0
- package/dist/18a02a9c54e.441.js +1 -0
- package/dist/18a02a9c54e.605.js +1 -0
- package/dist/18a02a9c54e.app.js +1 -0
- package/dist/{189cbc6136e.index.html → 18a02a9c54e.index.html} +1 -1
- package/dist/{189cbc6136e.library.html → 18a02a9c54e.library.html} +1 -1
- package/dist/18a02a9c54e.library.js +1 -0
- package/dist/{189cbc6136e.preview.html → 18a02a9c54e.preview.html} +1 -1
- package/dist/18a02a9c54e.preview.js +1 -0
- package/dist/18a02a9c54e.screenshoot.js +1 -0
- package/dist/18a02a9c54e.webview.js +1 -0
- package/dist/213.js +98 -98
- package/dist/335.js +25 -25
- package/dist/441.js +1484 -886
- package/dist/605.js +50 -50
- package/dist/HASH +1 -1
- package/dist/screenshoot.html +1 -1
- package/dist/screenshoot.js +437 -394
- package/index.html +3 -3
- package/package.json +9 -9
- package/src/chatbox/Typing.js +2 -3
- package/src/chatbox/Widget.js +9 -0
- package/src/lib.js +15 -1
- package/src/popup/popup.js +23 -3
- package/src/store/store.js +10 -1
- package/src/util/common.js +9 -3
- package/dist/189cbc6136e.132.js +0 -1
- package/dist/189cbc6136e.213.js +0 -1
- package/dist/189cbc6136e.335.js +0 -1
- package/dist/189cbc6136e.441.js +0 -1
- package/dist/189cbc6136e.605.js +0 -1
- package/dist/189cbc6136e.app.js +0 -1
- package/dist/189cbc6136e.library.js +0 -1
- package/dist/189cbc6136e.preview.js +0 -1
- package/dist/189cbc6136e.screenshoot.js +0 -1
- package/dist/189cbc6136e.webview.js +0 -1
- /package/dist/{189cbc6136e.178.js → 18a02a9c54e.178.js} +0 -0
- /package/dist/{189cbc6136e.362.js → 18a02a9c54e.362.js} +0 -0
- /package/dist/{189cbc6136e.678.js → 18a02a9c54e.678.js} +0 -0
- /package/dist/{189cbc6136e.782.js → 18a02a9c54e.782.js} +0 -0
package/dist/441.js
CHANGED
|
@@ -6,28 +6,26 @@
|
|
|
6
6
|
|
|
7
7
|
__webpack_require__.r(__webpack_exports__);
|
|
8
8
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9
|
-
/* harmony export */
|
|
10
|
-
/* harmony export */
|
|
11
|
-
/* harmony export */
|
|
12
|
-
/* harmony export */
|
|
13
|
-
/* harmony export */
|
|
14
|
-
/* harmony export */
|
|
15
|
-
/* harmony export */
|
|
16
|
-
/* harmony export */
|
|
17
|
-
/* harmony export */
|
|
18
|
-
/* harmony export */
|
|
19
|
-
/* harmony export */
|
|
20
|
-
/* harmony export */
|
|
21
|
-
/* harmony export */
|
|
22
|
-
/* harmony export */
|
|
23
|
-
/* harmony export */
|
|
24
|
-
/* harmony export */
|
|
25
|
-
/* harmony export */
|
|
26
|
-
/* harmony export */ use: () => (/* binding */ use),
|
|
27
|
-
/* harmony export */ walkTokens: () => (/* binding */ walkTokens)
|
|
9
|
+
/* harmony export */ "Lexer": () => (/* binding */ Lexer),
|
|
10
|
+
/* harmony export */ "Parser": () => (/* binding */ Parser),
|
|
11
|
+
/* harmony export */ "Renderer": () => (/* binding */ Renderer),
|
|
12
|
+
/* harmony export */ "Slugger": () => (/* binding */ Slugger),
|
|
13
|
+
/* harmony export */ "TextRenderer": () => (/* binding */ TextRenderer),
|
|
14
|
+
/* harmony export */ "Tokenizer": () => (/* binding */ Tokenizer),
|
|
15
|
+
/* harmony export */ "defaults": () => (/* binding */ defaults),
|
|
16
|
+
/* harmony export */ "getDefaults": () => (/* binding */ getDefaults),
|
|
17
|
+
/* harmony export */ "lexer": () => (/* binding */ lexer),
|
|
18
|
+
/* harmony export */ "marked": () => (/* binding */ marked),
|
|
19
|
+
/* harmony export */ "options": () => (/* binding */ options),
|
|
20
|
+
/* harmony export */ "parse": () => (/* binding */ parse),
|
|
21
|
+
/* harmony export */ "parseInline": () => (/* binding */ parseInline),
|
|
22
|
+
/* harmony export */ "parser": () => (/* binding */ parser),
|
|
23
|
+
/* harmony export */ "setOptions": () => (/* binding */ setOptions),
|
|
24
|
+
/* harmony export */ "use": () => (/* binding */ use),
|
|
25
|
+
/* harmony export */ "walkTokens": () => (/* binding */ walkTokens)
|
|
28
26
|
/* harmony export */ });
|
|
29
27
|
/**
|
|
30
|
-
* marked
|
|
28
|
+
* marked v4.2.12 - a markdown parser
|
|
31
29
|
* Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
|
|
32
30
|
* https://github.com/markedjs/marked
|
|
33
31
|
*/
|
|
@@ -37,22 +35,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
37
35
|
* The code in this file is generated from files in ./src/
|
|
38
36
|
*/
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
if (!member.has(obj))
|
|
42
|
-
throw TypeError("Cannot " + msg);
|
|
43
|
-
};
|
|
44
|
-
var __privateAdd = (obj, member, value) => {
|
|
45
|
-
if (member.has(obj))
|
|
46
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
47
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
48
|
-
};
|
|
49
|
-
var __privateMethod = (obj, member, method) => {
|
|
50
|
-
__accessCheck(obj, member, "access private method");
|
|
51
|
-
return method;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// src/defaults.ts
|
|
55
|
-
function _getDefaults() {
|
|
38
|
+
function getDefaults() {
|
|
56
39
|
return {
|
|
57
40
|
async: false,
|
|
58
41
|
baseUrl: null,
|
|
@@ -60,10 +43,9 @@ function _getDefaults() {
|
|
|
60
43
|
extensions: null,
|
|
61
44
|
gfm: true,
|
|
62
45
|
headerIds: true,
|
|
63
|
-
headerPrefix:
|
|
46
|
+
headerPrefix: '',
|
|
64
47
|
highlight: null,
|
|
65
|
-
|
|
66
|
-
langPrefix: "language-",
|
|
48
|
+
langPrefix: 'language-',
|
|
67
49
|
mangle: true,
|
|
68
50
|
pedantic: false,
|
|
69
51
|
renderer: null,
|
|
@@ -76,24 +58,28 @@ function _getDefaults() {
|
|
|
76
58
|
xhtml: false
|
|
77
59
|
};
|
|
78
60
|
}
|
|
79
|
-
|
|
61
|
+
|
|
62
|
+
let defaults = getDefaults();
|
|
63
|
+
|
|
80
64
|
function changeDefaults(newDefaults) {
|
|
81
|
-
|
|
65
|
+
defaults = newDefaults;
|
|
82
66
|
}
|
|
83
67
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'
|
|
94
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Helpers
|
|
70
|
+
*/
|
|
71
|
+
const escapeTest = /[&<>"']/;
|
|
72
|
+
const escapeReplace = new RegExp(escapeTest.source, 'g');
|
|
73
|
+
const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
|
|
74
|
+
const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
|
|
75
|
+
const escapeReplacements = {
|
|
76
|
+
'&': '&',
|
|
77
|
+
'<': '<',
|
|
78
|
+
'>': '>',
|
|
79
|
+
'"': '"',
|
|
80
|
+
"'": '''
|
|
95
81
|
};
|
|
96
|
-
|
|
82
|
+
const getEscapeReplacement = (ch) => escapeReplacements[ch];
|
|
97
83
|
function escape(html, encode) {
|
|
98
84
|
if (encode) {
|
|
99
85
|
if (escapeTest.test(html)) {
|
|
@@ -104,28 +90,42 @@ function escape(html, encode) {
|
|
|
104
90
|
return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
|
|
105
91
|
}
|
|
106
92
|
}
|
|
93
|
+
|
|
107
94
|
return html;
|
|
108
95
|
}
|
|
109
|
-
|
|
96
|
+
|
|
97
|
+
const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} html
|
|
101
|
+
*/
|
|
110
102
|
function unescape(html) {
|
|
103
|
+
// explicitly match decimal, hex, and named HTML entities
|
|
111
104
|
return html.replace(unescapeTest, (_, n) => {
|
|
112
105
|
n = n.toLowerCase();
|
|
113
|
-
if (n ===
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
if (n === 'colon') return ':';
|
|
107
|
+
if (n.charAt(0) === '#') {
|
|
108
|
+
return n.charAt(1) === 'x'
|
|
109
|
+
? String.fromCharCode(parseInt(n.substring(2), 16))
|
|
110
|
+
: String.fromCharCode(+n.substring(1));
|
|
117
111
|
}
|
|
118
|
-
return
|
|
112
|
+
return '';
|
|
119
113
|
});
|
|
120
114
|
}
|
|
121
|
-
|
|
115
|
+
|
|
116
|
+
const caret = /(^|[^\[])\^/g;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {string | RegExp} regex
|
|
120
|
+
* @param {string} opt
|
|
121
|
+
*/
|
|
122
122
|
function edit(regex, opt) {
|
|
123
|
-
regex = typeof regex ===
|
|
124
|
-
opt = opt ||
|
|
123
|
+
regex = typeof regex === 'string' ? regex : regex.source;
|
|
124
|
+
opt = opt || '';
|
|
125
125
|
const obj = {
|
|
126
126
|
replace: (name, val) => {
|
|
127
|
-
val =
|
|
128
|
-
val = val.replace(caret,
|
|
127
|
+
val = val.source || val;
|
|
128
|
+
val = val.replace(caret, '$1');
|
|
129
129
|
regex = regex.replace(name, val);
|
|
130
130
|
return obj;
|
|
131
131
|
},
|
|
@@ -135,17 +135,26 @@ function edit(regex, opt) {
|
|
|
135
135
|
};
|
|
136
136
|
return obj;
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
|
|
139
|
+
const nonWordAndColonTest = /[^\w:]/g;
|
|
140
|
+
const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param {boolean} sanitize
|
|
144
|
+
* @param {string} base
|
|
145
|
+
* @param {string} href
|
|
146
|
+
*/
|
|
140
147
|
function cleanUrl(sanitize, base, href) {
|
|
141
148
|
if (sanitize) {
|
|
142
149
|
let prot;
|
|
143
150
|
try {
|
|
144
|
-
prot = decodeURIComponent(unescape(href))
|
|
151
|
+
prot = decodeURIComponent(unescape(href))
|
|
152
|
+
.replace(nonWordAndColonTest, '')
|
|
153
|
+
.toLowerCase();
|
|
145
154
|
} catch (e) {
|
|
146
155
|
return null;
|
|
147
156
|
}
|
|
148
|
-
if (prot.indexOf(
|
|
157
|
+
if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
|
|
149
158
|
return null;
|
|
150
159
|
}
|
|
151
160
|
}
|
|
@@ -153,76 +162,124 @@ function cleanUrl(sanitize, base, href) {
|
|
|
153
162
|
href = resolveUrl(base, href);
|
|
154
163
|
}
|
|
155
164
|
try {
|
|
156
|
-
href = encodeURI(href).replace(/%25/g,
|
|
165
|
+
href = encodeURI(href).replace(/%25/g, '%');
|
|
157
166
|
} catch (e) {
|
|
158
167
|
return null;
|
|
159
168
|
}
|
|
160
169
|
return href;
|
|
161
170
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
|
|
172
|
+
const baseUrls = {};
|
|
173
|
+
const justDomain = /^[^:]+:\/*[^/]*$/;
|
|
174
|
+
const protocol = /^([^:]+:)[\s\S]*$/;
|
|
175
|
+
const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @param {string} base
|
|
179
|
+
* @param {string} href
|
|
180
|
+
*/
|
|
166
181
|
function resolveUrl(base, href) {
|
|
167
|
-
if (!baseUrls[
|
|
182
|
+
if (!baseUrls[' ' + base]) {
|
|
183
|
+
// we can ignore everything in base after the last slash of its path component,
|
|
184
|
+
// but we might need to add _that_
|
|
185
|
+
// https://tools.ietf.org/html/rfc3986#section-3
|
|
168
186
|
if (justDomain.test(base)) {
|
|
169
|
-
baseUrls[
|
|
187
|
+
baseUrls[' ' + base] = base + '/';
|
|
170
188
|
} else {
|
|
171
|
-
baseUrls[
|
|
189
|
+
baseUrls[' ' + base] = rtrim(base, '/', true);
|
|
172
190
|
}
|
|
173
191
|
}
|
|
174
|
-
base = baseUrls[
|
|
175
|
-
const relativeBase = base.indexOf(
|
|
176
|
-
|
|
192
|
+
base = baseUrls[' ' + base];
|
|
193
|
+
const relativeBase = base.indexOf(':') === -1;
|
|
194
|
+
|
|
195
|
+
if (href.substring(0, 2) === '//') {
|
|
177
196
|
if (relativeBase) {
|
|
178
197
|
return href;
|
|
179
198
|
}
|
|
180
|
-
return base.replace(protocol,
|
|
181
|
-
} else if (href.charAt(0) ===
|
|
199
|
+
return base.replace(protocol, '$1') + href;
|
|
200
|
+
} else if (href.charAt(0) === '/') {
|
|
182
201
|
if (relativeBase) {
|
|
183
202
|
return href;
|
|
184
203
|
}
|
|
185
|
-
return base.replace(domain,
|
|
204
|
+
return base.replace(domain, '$1') + href;
|
|
186
205
|
} else {
|
|
187
206
|
return base + href;
|
|
188
207
|
}
|
|
189
208
|
}
|
|
190
|
-
|
|
209
|
+
|
|
210
|
+
const noopTest = { exec: function noopTest() {} };
|
|
211
|
+
|
|
212
|
+
function merge(obj) {
|
|
213
|
+
let i = 1,
|
|
214
|
+
target,
|
|
215
|
+
key;
|
|
216
|
+
|
|
217
|
+
for (; i < arguments.length; i++) {
|
|
218
|
+
target = arguments[i];
|
|
219
|
+
for (key in target) {
|
|
220
|
+
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
|
221
|
+
obj[key] = target[key];
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return obj;
|
|
227
|
+
}
|
|
228
|
+
|
|
191
229
|
function splitCells(tableRow, count) {
|
|
230
|
+
// ensure that every cell-delimiting pipe has a space
|
|
231
|
+
// before it to distinguish it from an escaped pipe
|
|
192
232
|
const row = tableRow.replace(/\|/g, (match, offset, str) => {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
escaped = !escaped;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
233
|
+
let escaped = false,
|
|
234
|
+
curr = offset;
|
|
235
|
+
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;
|
|
236
|
+
if (escaped) {
|
|
237
|
+
// odd number of slashes means | is escaped
|
|
238
|
+
// so we leave it alone
|
|
239
|
+
return '|';
|
|
240
|
+
} else {
|
|
241
|
+
// add space before unescaped |
|
|
242
|
+
return ' |';
|
|
243
|
+
}
|
|
244
|
+
}),
|
|
245
|
+
cells = row.split(/ \|/);
|
|
202
246
|
let i = 0;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
if (cells.length > 0 && !cells[cells.length - 1].trim()) {
|
|
207
|
-
|
|
208
|
-
}
|
|
247
|
+
|
|
248
|
+
// First/last cell in a row cannot be empty if it has no leading/trailing pipe
|
|
249
|
+
if (!cells[0].trim()) { cells.shift(); }
|
|
250
|
+
if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); }
|
|
251
|
+
|
|
209
252
|
if (cells.length > count) {
|
|
210
253
|
cells.splice(count);
|
|
211
254
|
} else {
|
|
212
|
-
while (cells.length < count)
|
|
213
|
-
cells.push("");
|
|
255
|
+
while (cells.length < count) cells.push('');
|
|
214
256
|
}
|
|
257
|
+
|
|
215
258
|
for (; i < cells.length; i++) {
|
|
216
|
-
|
|
259
|
+
// leading or trailing whitespace is ignored per the gfm spec
|
|
260
|
+
cells[i] = cells[i].trim().replace(/\\\|/g, '|');
|
|
217
261
|
}
|
|
218
262
|
return cells;
|
|
219
263
|
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
|
|
267
|
+
* /c*$/ is vulnerable to REDOS.
|
|
268
|
+
*
|
|
269
|
+
* @param {string} str
|
|
270
|
+
* @param {string} c
|
|
271
|
+
* @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
|
|
272
|
+
*/
|
|
220
273
|
function rtrim(str, c, invert) {
|
|
221
274
|
const l = str.length;
|
|
222
275
|
if (l === 0) {
|
|
223
|
-
return
|
|
276
|
+
return '';
|
|
224
277
|
}
|
|
278
|
+
|
|
279
|
+
// Length of suffix matching the invert condition.
|
|
225
280
|
let suffLen = 0;
|
|
281
|
+
|
|
282
|
+
// Step left until we fail to match the invert condition.
|
|
226
283
|
while (suffLen < l) {
|
|
227
284
|
const currChar = str.charAt(l - suffLen - 1);
|
|
228
285
|
if (currChar === c && !invert) {
|
|
@@ -233,16 +290,19 @@ function rtrim(str, c, invert) {
|
|
|
233
290
|
break;
|
|
234
291
|
}
|
|
235
292
|
}
|
|
293
|
+
|
|
236
294
|
return str.slice(0, l - suffLen);
|
|
237
295
|
}
|
|
296
|
+
|
|
238
297
|
function findClosingBracket(str, b) {
|
|
239
298
|
if (str.indexOf(b[1]) === -1) {
|
|
240
299
|
return -1;
|
|
241
300
|
}
|
|
242
301
|
const l = str.length;
|
|
243
|
-
let level = 0,
|
|
302
|
+
let level = 0,
|
|
303
|
+
i = 0;
|
|
244
304
|
for (; i < l; i++) {
|
|
245
|
-
if (str[i] ===
|
|
305
|
+
if (str[i] === '\\') {
|
|
246
306
|
i++;
|
|
247
307
|
} else if (str[i] === b[0]) {
|
|
248
308
|
level++;
|
|
@@ -255,132 +315,154 @@ function findClosingBracket(str, b) {
|
|
|
255
315
|
}
|
|
256
316
|
return -1;
|
|
257
317
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (callback) {
|
|
263
|
-
console.warn("marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async");
|
|
264
|
-
}
|
|
265
|
-
if (opt.sanitize || opt.sanitizer) {
|
|
266
|
-
console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options");
|
|
267
|
-
}
|
|
268
|
-
if (opt.highlight || opt.langPrefix !== "language-") {
|
|
269
|
-
console.warn("marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.");
|
|
270
|
-
}
|
|
271
|
-
if (opt.mangle) {
|
|
272
|
-
console.warn("marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.");
|
|
273
|
-
}
|
|
274
|
-
if (opt.baseUrl) {
|
|
275
|
-
console.warn("marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.");
|
|
276
|
-
}
|
|
277
|
-
if (opt.smartypants) {
|
|
278
|
-
console.warn("marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.");
|
|
318
|
+
|
|
319
|
+
function checkSanitizeDeprecation(opt) {
|
|
320
|
+
if (opt && opt.sanitize && !opt.silent) {
|
|
321
|
+
console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
|
|
279
322
|
}
|
|
280
|
-
|
|
281
|
-
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// copied from https://stackoverflow.com/a/5450113/806777
|
|
326
|
+
/**
|
|
327
|
+
* @param {string} pattern
|
|
328
|
+
* @param {number} count
|
|
329
|
+
*/
|
|
330
|
+
function repeatString(pattern, count) {
|
|
331
|
+
if (count < 1) {
|
|
332
|
+
return '';
|
|
282
333
|
}
|
|
283
|
-
|
|
284
|
-
|
|
334
|
+
let result = '';
|
|
335
|
+
while (count > 1) {
|
|
336
|
+
if (count & 1) {
|
|
337
|
+
result += pattern;
|
|
338
|
+
}
|
|
339
|
+
count >>= 1;
|
|
340
|
+
pattern += pattern;
|
|
285
341
|
}
|
|
342
|
+
return result + pattern;
|
|
286
343
|
}
|
|
287
344
|
|
|
288
|
-
|
|
289
|
-
function outputLink(cap, link, raw, lexer2) {
|
|
345
|
+
function outputLink(cap, link, raw, lexer) {
|
|
290
346
|
const href = link.href;
|
|
291
347
|
const title = link.title ? escape(link.title) : null;
|
|
292
|
-
const text = cap[1].replace(/\\([\[\]])/g,
|
|
293
|
-
|
|
294
|
-
|
|
348
|
+
const text = cap[1].replace(/\\([\[\]])/g, '$1');
|
|
349
|
+
|
|
350
|
+
if (cap[0].charAt(0) !== '!') {
|
|
351
|
+
lexer.state.inLink = true;
|
|
295
352
|
const token = {
|
|
296
|
-
type:
|
|
353
|
+
type: 'link',
|
|
297
354
|
raw,
|
|
298
355
|
href,
|
|
299
356
|
title,
|
|
300
357
|
text,
|
|
301
|
-
tokens:
|
|
358
|
+
tokens: lexer.inlineTokens(text)
|
|
302
359
|
};
|
|
303
|
-
|
|
360
|
+
lexer.state.inLink = false;
|
|
304
361
|
return token;
|
|
305
362
|
}
|
|
306
363
|
return {
|
|
307
|
-
type:
|
|
364
|
+
type: 'image',
|
|
308
365
|
raw,
|
|
309
366
|
href,
|
|
310
367
|
title,
|
|
311
368
|
text: escape(text)
|
|
312
369
|
};
|
|
313
370
|
}
|
|
371
|
+
|
|
314
372
|
function indentCodeCompensation(raw, text) {
|
|
315
373
|
const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
|
|
374
|
+
|
|
316
375
|
if (matchIndentToCode === null) {
|
|
317
376
|
return text;
|
|
318
377
|
}
|
|
378
|
+
|
|
319
379
|
const indentToCode = matchIndentToCode[1];
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
380
|
+
|
|
381
|
+
return text
|
|
382
|
+
.split('\n')
|
|
383
|
+
.map(node => {
|
|
384
|
+
const matchIndentInNode = node.match(/^\s+/);
|
|
385
|
+
if (matchIndentInNode === null) {
|
|
386
|
+
return node;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const [indentInNode] = matchIndentInNode;
|
|
390
|
+
|
|
391
|
+
if (indentInNode.length >= indentToCode.length) {
|
|
392
|
+
return node.slice(indentToCode.length);
|
|
393
|
+
}
|
|
394
|
+
|
|
323
395
|
return node;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (indentInNode.length >= indentToCode.length) {
|
|
327
|
-
return node.slice(indentToCode.length);
|
|
328
|
-
}
|
|
329
|
-
return node;
|
|
330
|
-
}).join("\n");
|
|
396
|
+
})
|
|
397
|
+
.join('\n');
|
|
331
398
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Tokenizer
|
|
402
|
+
*/
|
|
403
|
+
class Tokenizer {
|
|
404
|
+
constructor(options) {
|
|
405
|
+
this.options = options || defaults;
|
|
335
406
|
}
|
|
407
|
+
|
|
336
408
|
space(src) {
|
|
337
409
|
const cap = this.rules.block.newline.exec(src);
|
|
338
410
|
if (cap && cap[0].length > 0) {
|
|
339
411
|
return {
|
|
340
|
-
type:
|
|
412
|
+
type: 'space',
|
|
341
413
|
raw: cap[0]
|
|
342
414
|
};
|
|
343
415
|
}
|
|
344
416
|
}
|
|
417
|
+
|
|
345
418
|
code(src) {
|
|
346
419
|
const cap = this.rules.block.code.exec(src);
|
|
347
420
|
if (cap) {
|
|
348
|
-
const text = cap[0].replace(/^ {1,4}/gm,
|
|
421
|
+
const text = cap[0].replace(/^ {1,4}/gm, '');
|
|
349
422
|
return {
|
|
350
|
-
type:
|
|
423
|
+
type: 'code',
|
|
351
424
|
raw: cap[0],
|
|
352
|
-
codeBlockStyle:
|
|
353
|
-
text: !this.options.pedantic
|
|
425
|
+
codeBlockStyle: 'indented',
|
|
426
|
+
text: !this.options.pedantic
|
|
427
|
+
? rtrim(text, '\n')
|
|
428
|
+
: text
|
|
354
429
|
};
|
|
355
430
|
}
|
|
356
431
|
}
|
|
432
|
+
|
|
357
433
|
fences(src) {
|
|
358
434
|
const cap = this.rules.block.fences.exec(src);
|
|
359
435
|
if (cap) {
|
|
360
436
|
const raw = cap[0];
|
|
361
|
-
const text = indentCodeCompensation(raw, cap[3] ||
|
|
437
|
+
const text = indentCodeCompensation(raw, cap[3] || '');
|
|
438
|
+
|
|
362
439
|
return {
|
|
363
|
-
type:
|
|
440
|
+
type: 'code',
|
|
364
441
|
raw,
|
|
365
|
-
lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes,
|
|
442
|
+
lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
|
|
366
443
|
text
|
|
367
444
|
};
|
|
368
445
|
}
|
|
369
446
|
}
|
|
447
|
+
|
|
370
448
|
heading(src) {
|
|
371
449
|
const cap = this.rules.block.heading.exec(src);
|
|
372
450
|
if (cap) {
|
|
373
451
|
let text = cap[2].trim();
|
|
452
|
+
|
|
453
|
+
// remove trailing #s
|
|
374
454
|
if (/#$/.test(text)) {
|
|
375
|
-
const trimmed = rtrim(text,
|
|
455
|
+
const trimmed = rtrim(text, '#');
|
|
376
456
|
if (this.options.pedantic) {
|
|
377
457
|
text = trimmed.trim();
|
|
378
458
|
} else if (!trimmed || / $/.test(trimmed)) {
|
|
459
|
+
// CommonMark requires space before trailing #s
|
|
379
460
|
text = trimmed.trim();
|
|
380
461
|
}
|
|
381
462
|
}
|
|
463
|
+
|
|
382
464
|
return {
|
|
383
|
-
type:
|
|
465
|
+
type: 'heading',
|
|
384
466
|
raw: cap[0],
|
|
385
467
|
depth: cap[1].length,
|
|
386
468
|
text,
|
|
@@ -388,107 +470,142 @@ var _Tokenizer = class {
|
|
|
388
470
|
};
|
|
389
471
|
}
|
|
390
472
|
}
|
|
473
|
+
|
|
391
474
|
hr(src) {
|
|
392
475
|
const cap = this.rules.block.hr.exec(src);
|
|
393
476
|
if (cap) {
|
|
394
477
|
return {
|
|
395
|
-
type:
|
|
478
|
+
type: 'hr',
|
|
396
479
|
raw: cap[0]
|
|
397
480
|
};
|
|
398
481
|
}
|
|
399
482
|
}
|
|
483
|
+
|
|
400
484
|
blockquote(src) {
|
|
401
485
|
const cap = this.rules.block.blockquote.exec(src);
|
|
402
486
|
if (cap) {
|
|
403
|
-
const text = cap[0].replace(/^ *>[ \t]?/gm,
|
|
487
|
+
const text = cap[0].replace(/^ *>[ \t]?/gm, '');
|
|
404
488
|
const top = this.lexer.state.top;
|
|
405
489
|
this.lexer.state.top = true;
|
|
406
490
|
const tokens = this.lexer.blockTokens(text);
|
|
407
491
|
this.lexer.state.top = top;
|
|
408
492
|
return {
|
|
409
|
-
type:
|
|
493
|
+
type: 'blockquote',
|
|
410
494
|
raw: cap[0],
|
|
411
495
|
tokens,
|
|
412
496
|
text
|
|
413
497
|
};
|
|
414
498
|
}
|
|
415
499
|
}
|
|
500
|
+
|
|
416
501
|
list(src) {
|
|
417
502
|
let cap = this.rules.block.list.exec(src);
|
|
418
503
|
if (cap) {
|
|
419
|
-
let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine,
|
|
504
|
+
let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine,
|
|
505
|
+
line, nextLine, rawLine, itemContents, endEarly;
|
|
506
|
+
|
|
420
507
|
let bull = cap[1].trim();
|
|
421
508
|
const isordered = bull.length > 1;
|
|
509
|
+
|
|
422
510
|
const list = {
|
|
423
|
-
type:
|
|
424
|
-
raw:
|
|
511
|
+
type: 'list',
|
|
512
|
+
raw: '',
|
|
425
513
|
ordered: isordered,
|
|
426
|
-
start: isordered ? +bull.slice(0, -1) :
|
|
514
|
+
start: isordered ? +bull.slice(0, -1) : '',
|
|
427
515
|
loose: false,
|
|
428
516
|
items: []
|
|
429
517
|
};
|
|
518
|
+
|
|
430
519
|
bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
|
|
520
|
+
|
|
431
521
|
if (this.options.pedantic) {
|
|
432
|
-
bull = isordered ? bull :
|
|
522
|
+
bull = isordered ? bull : '[*+-]';
|
|
433
523
|
}
|
|
434
|
-
|
|
524
|
+
|
|
525
|
+
// Get next list item
|
|
526
|
+
const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
|
|
527
|
+
|
|
528
|
+
// Check if current bullet point can start a new List Item
|
|
435
529
|
while (src) {
|
|
436
530
|
endEarly = false;
|
|
437
531
|
if (!(cap = itemRegex.exec(src))) {
|
|
438
532
|
break;
|
|
439
533
|
}
|
|
440
|
-
|
|
534
|
+
|
|
535
|
+
if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
|
|
441
536
|
break;
|
|
442
537
|
}
|
|
538
|
+
|
|
443
539
|
raw = cap[0];
|
|
444
540
|
src = src.substring(raw.length);
|
|
445
|
-
|
|
446
|
-
|
|
541
|
+
|
|
542
|
+
line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
|
|
543
|
+
nextLine = src.split('\n', 1)[0];
|
|
544
|
+
|
|
447
545
|
if (this.options.pedantic) {
|
|
448
546
|
indent = 2;
|
|
449
547
|
itemContents = line.trimLeft();
|
|
450
548
|
} else {
|
|
451
|
-
indent = cap[2].search(/[^ ]/);
|
|
452
|
-
indent = indent > 4 ? 1 : indent;
|
|
549
|
+
indent = cap[2].search(/[^ ]/); // Find first non-space char
|
|
550
|
+
indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
|
|
453
551
|
itemContents = line.slice(indent);
|
|
454
552
|
indent += cap[1].length;
|
|
455
553
|
}
|
|
554
|
+
|
|
456
555
|
blankLine = false;
|
|
457
|
-
|
|
458
|
-
|
|
556
|
+
|
|
557
|
+
if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
|
|
558
|
+
raw += nextLine + '\n';
|
|
459
559
|
src = src.substring(nextLine.length + 1);
|
|
460
560
|
endEarly = true;
|
|
461
561
|
}
|
|
562
|
+
|
|
462
563
|
if (!endEarly) {
|
|
463
|
-
const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[
|
|
564
|
+
const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
|
|
464
565
|
const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
|
|
465
566
|
const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
|
|
466
567
|
const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
|
|
568
|
+
|
|
569
|
+
// Check if following lines should be included in List Item
|
|
467
570
|
while (src) {
|
|
468
|
-
rawLine = src.split(
|
|
571
|
+
rawLine = src.split('\n', 1)[0];
|
|
469
572
|
nextLine = rawLine;
|
|
573
|
+
|
|
574
|
+
// Re-align to follow commonmark nesting rules
|
|
470
575
|
if (this.options.pedantic) {
|
|
471
|
-
nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g,
|
|
576
|
+
nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');
|
|
472
577
|
}
|
|
578
|
+
|
|
579
|
+
// End list item if found code fences
|
|
473
580
|
if (fencesBeginRegex.test(nextLine)) {
|
|
474
581
|
break;
|
|
475
582
|
}
|
|
583
|
+
|
|
584
|
+
// End list item if found start of new heading
|
|
476
585
|
if (headingBeginRegex.test(nextLine)) {
|
|
477
586
|
break;
|
|
478
587
|
}
|
|
588
|
+
|
|
589
|
+
// End list item if found start of new bullet
|
|
479
590
|
if (nextBulletRegex.test(nextLine)) {
|
|
480
591
|
break;
|
|
481
592
|
}
|
|
593
|
+
|
|
594
|
+
// Horizontal rule found
|
|
482
595
|
if (hrRegex.test(src)) {
|
|
483
596
|
break;
|
|
484
597
|
}
|
|
485
|
-
|
|
486
|
-
|
|
598
|
+
|
|
599
|
+
if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
|
|
600
|
+
itemContents += '\n' + nextLine.slice(indent);
|
|
487
601
|
} else {
|
|
602
|
+
// not enough indentation
|
|
488
603
|
if (blankLine) {
|
|
489
604
|
break;
|
|
490
605
|
}
|
|
491
|
-
|
|
606
|
+
|
|
607
|
+
// paragraph continuation unless last line was a different block level element
|
|
608
|
+
if (line.search(/[^ ]/) >= 4) { // indented code block
|
|
492
609
|
break;
|
|
493
610
|
}
|
|
494
611
|
if (fencesBeginRegex.test(line)) {
|
|
@@ -500,89 +617,110 @@ var _Tokenizer = class {
|
|
|
500
617
|
if (hrRegex.test(line)) {
|
|
501
618
|
break;
|
|
502
619
|
}
|
|
503
|
-
|
|
620
|
+
|
|
621
|
+
itemContents += '\n' + nextLine;
|
|
504
622
|
}
|
|
505
|
-
|
|
623
|
+
|
|
624
|
+
if (!blankLine && !nextLine.trim()) { // Check if current line is blank
|
|
506
625
|
blankLine = true;
|
|
507
626
|
}
|
|
508
|
-
|
|
627
|
+
|
|
628
|
+
raw += rawLine + '\n';
|
|
509
629
|
src = src.substring(rawLine.length + 1);
|
|
510
630
|
line = nextLine.slice(indent);
|
|
511
631
|
}
|
|
512
632
|
}
|
|
633
|
+
|
|
513
634
|
if (!list.loose) {
|
|
635
|
+
// If the previous item ended with a blank line, the list is loose
|
|
514
636
|
if (endsWithBlankLine) {
|
|
515
637
|
list.loose = true;
|
|
516
638
|
} else if (/\n *\n *$/.test(raw)) {
|
|
517
639
|
endsWithBlankLine = true;
|
|
518
640
|
}
|
|
519
641
|
}
|
|
642
|
+
|
|
643
|
+
// Check for task list items
|
|
520
644
|
if (this.options.gfm) {
|
|
521
645
|
istask = /^\[[ xX]\] /.exec(itemContents);
|
|
522
646
|
if (istask) {
|
|
523
|
-
ischecked = istask[0] !==
|
|
524
|
-
itemContents = itemContents.replace(/^\[[ xX]\] +/,
|
|
647
|
+
ischecked = istask[0] !== '[ ] ';
|
|
648
|
+
itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
|
|
525
649
|
}
|
|
526
650
|
}
|
|
651
|
+
|
|
527
652
|
list.items.push({
|
|
528
|
-
type:
|
|
653
|
+
type: 'list_item',
|
|
529
654
|
raw,
|
|
530
655
|
task: !!istask,
|
|
531
656
|
checked: ischecked,
|
|
532
657
|
loose: false,
|
|
533
658
|
text: itemContents
|
|
534
659
|
});
|
|
660
|
+
|
|
535
661
|
list.raw += raw;
|
|
536
662
|
}
|
|
663
|
+
|
|
664
|
+
// Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
|
|
537
665
|
list.items[list.items.length - 1].raw = raw.trimRight();
|
|
538
666
|
list.items[list.items.length - 1].text = itemContents.trimRight();
|
|
539
667
|
list.raw = list.raw.trimRight();
|
|
668
|
+
|
|
540
669
|
const l = list.items.length;
|
|
670
|
+
|
|
671
|
+
// Item child tokens handled here at end because we needed to have the final item to trim it first
|
|
541
672
|
for (i = 0; i < l; i++) {
|
|
542
673
|
this.lexer.state.top = false;
|
|
543
674
|
list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
|
|
675
|
+
|
|
544
676
|
if (!list.loose) {
|
|
545
|
-
|
|
546
|
-
const
|
|
677
|
+
// Check if list should be loose
|
|
678
|
+
const spacers = list.items[i].tokens.filter(t => t.type === 'space');
|
|
679
|
+
const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw));
|
|
680
|
+
|
|
547
681
|
list.loose = hasMultipleLineBreaks;
|
|
548
682
|
}
|
|
549
683
|
}
|
|
684
|
+
|
|
685
|
+
// Set all items to loose if list is loose
|
|
550
686
|
if (list.loose) {
|
|
551
687
|
for (i = 0; i < l; i++) {
|
|
552
688
|
list.items[i].loose = true;
|
|
553
689
|
}
|
|
554
690
|
}
|
|
691
|
+
|
|
555
692
|
return list;
|
|
556
693
|
}
|
|
557
694
|
}
|
|
695
|
+
|
|
558
696
|
html(src) {
|
|
559
697
|
const cap = this.rules.block.html.exec(src);
|
|
560
698
|
if (cap) {
|
|
561
699
|
const token = {
|
|
562
|
-
type:
|
|
563
|
-
block: true,
|
|
700
|
+
type: 'html',
|
|
564
701
|
raw: cap[0],
|
|
565
|
-
pre: !this.options.sanitizer
|
|
702
|
+
pre: !this.options.sanitizer
|
|
703
|
+
&& (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
|
|
566
704
|
text: cap[0]
|
|
567
705
|
};
|
|
568
706
|
if (this.options.sanitize) {
|
|
569
707
|
const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
paragraph.tokens = this.lexer.inline(text);
|
|
708
|
+
token.type = 'paragraph';
|
|
709
|
+
token.text = text;
|
|
710
|
+
token.tokens = this.lexer.inline(text);
|
|
574
711
|
}
|
|
575
712
|
return token;
|
|
576
713
|
}
|
|
577
714
|
}
|
|
715
|
+
|
|
578
716
|
def(src) {
|
|
579
717
|
const cap = this.rules.block.def.exec(src);
|
|
580
718
|
if (cap) {
|
|
581
|
-
const tag = cap[1].toLowerCase().replace(/\s+/g,
|
|
582
|
-
const href = cap[2] ? cap[2].replace(/^<(.*)>$/,
|
|
583
|
-
const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes,
|
|
719
|
+
const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
|
|
720
|
+
const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
|
|
721
|
+
const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
|
|
584
722
|
return {
|
|
585
|
-
type:
|
|
723
|
+
type: 'def',
|
|
586
724
|
tag,
|
|
587
725
|
raw: cap[0],
|
|
588
726
|
href,
|
|
@@ -590,44 +728,48 @@ var _Tokenizer = class {
|
|
|
590
728
|
};
|
|
591
729
|
}
|
|
592
730
|
}
|
|
731
|
+
|
|
593
732
|
table(src) {
|
|
594
733
|
const cap = this.rules.block.table.exec(src);
|
|
595
734
|
if (cap) {
|
|
596
735
|
const item = {
|
|
597
|
-
type:
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
return { text: c };
|
|
602
|
-
}),
|
|
603
|
-
align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
|
|
604
|
-
rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : []
|
|
736
|
+
type: 'table',
|
|
737
|
+
header: splitCells(cap[1]).map(c => { return { text: c }; }),
|
|
738
|
+
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
|
739
|
+
rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
|
|
605
740
|
};
|
|
741
|
+
|
|
606
742
|
if (item.header.length === item.align.length) {
|
|
607
743
|
item.raw = cap[0];
|
|
744
|
+
|
|
608
745
|
let l = item.align.length;
|
|
609
746
|
let i, j, k, row;
|
|
610
747
|
for (i = 0; i < l; i++) {
|
|
611
748
|
if (/^ *-+: *$/.test(item.align[i])) {
|
|
612
|
-
item.align[i] =
|
|
749
|
+
item.align[i] = 'right';
|
|
613
750
|
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
|
614
|
-
item.align[i] =
|
|
751
|
+
item.align[i] = 'center';
|
|
615
752
|
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
|
616
|
-
item.align[i] =
|
|
753
|
+
item.align[i] = 'left';
|
|
617
754
|
} else {
|
|
618
755
|
item.align[i] = null;
|
|
619
756
|
}
|
|
620
757
|
}
|
|
758
|
+
|
|
621
759
|
l = item.rows.length;
|
|
622
760
|
for (i = 0; i < l; i++) {
|
|
623
|
-
item.rows[i] = splitCells(item.rows[i], item.header.length).map(
|
|
624
|
-
return { text: c };
|
|
625
|
-
});
|
|
761
|
+
item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; });
|
|
626
762
|
}
|
|
763
|
+
|
|
764
|
+
// parse child tokens inside headers and cells
|
|
765
|
+
|
|
766
|
+
// header child tokens
|
|
627
767
|
l = item.header.length;
|
|
628
768
|
for (j = 0; j < l; j++) {
|
|
629
769
|
item.header[j].tokens = this.lexer.inline(item.header[j].text);
|
|
630
770
|
}
|
|
771
|
+
|
|
772
|
+
// cell child tokens
|
|
631
773
|
l = item.rows.length;
|
|
632
774
|
for (j = 0; j < l; j++) {
|
|
633
775
|
row = item.rows[j];
|
|
@@ -635,55 +777,63 @@ var _Tokenizer = class {
|
|
|
635
777
|
row[k].tokens = this.lexer.inline(row[k].text);
|
|
636
778
|
}
|
|
637
779
|
}
|
|
780
|
+
|
|
638
781
|
return item;
|
|
639
782
|
}
|
|
640
783
|
}
|
|
641
784
|
}
|
|
785
|
+
|
|
642
786
|
lheading(src) {
|
|
643
787
|
const cap = this.rules.block.lheading.exec(src);
|
|
644
788
|
if (cap) {
|
|
645
789
|
return {
|
|
646
|
-
type:
|
|
790
|
+
type: 'heading',
|
|
647
791
|
raw: cap[0],
|
|
648
|
-
depth: cap[2].charAt(0) ===
|
|
792
|
+
depth: cap[2].charAt(0) === '=' ? 1 : 2,
|
|
649
793
|
text: cap[1],
|
|
650
794
|
tokens: this.lexer.inline(cap[1])
|
|
651
795
|
};
|
|
652
796
|
}
|
|
653
797
|
}
|
|
798
|
+
|
|
654
799
|
paragraph(src) {
|
|
655
800
|
const cap = this.rules.block.paragraph.exec(src);
|
|
656
801
|
if (cap) {
|
|
657
|
-
const text = cap[1].charAt(cap[1].length - 1) ===
|
|
802
|
+
const text = cap[1].charAt(cap[1].length - 1) === '\n'
|
|
803
|
+
? cap[1].slice(0, -1)
|
|
804
|
+
: cap[1];
|
|
658
805
|
return {
|
|
659
|
-
type:
|
|
806
|
+
type: 'paragraph',
|
|
660
807
|
raw: cap[0],
|
|
661
808
|
text,
|
|
662
809
|
tokens: this.lexer.inline(text)
|
|
663
810
|
};
|
|
664
811
|
}
|
|
665
812
|
}
|
|
813
|
+
|
|
666
814
|
text(src) {
|
|
667
815
|
const cap = this.rules.block.text.exec(src);
|
|
668
816
|
if (cap) {
|
|
669
817
|
return {
|
|
670
|
-
type:
|
|
818
|
+
type: 'text',
|
|
671
819
|
raw: cap[0],
|
|
672
820
|
text: cap[0],
|
|
673
821
|
tokens: this.lexer.inline(cap[0])
|
|
674
822
|
};
|
|
675
823
|
}
|
|
676
824
|
}
|
|
825
|
+
|
|
677
826
|
escape(src) {
|
|
678
827
|
const cap = this.rules.inline.escape.exec(src);
|
|
679
828
|
if (cap) {
|
|
680
829
|
return {
|
|
681
|
-
type:
|
|
830
|
+
type: 'escape',
|
|
682
831
|
raw: cap[0],
|
|
683
832
|
text: escape(cap[1])
|
|
684
833
|
};
|
|
685
834
|
}
|
|
686
835
|
}
|
|
836
|
+
|
|
687
837
|
tag(src) {
|
|
688
838
|
const cap = this.rules.inline.tag.exec(src);
|
|
689
839
|
if (cap) {
|
|
@@ -697,72 +847,89 @@ var _Tokenizer = class {
|
|
|
697
847
|
} else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
|
|
698
848
|
this.lexer.state.inRawBlock = false;
|
|
699
849
|
}
|
|
850
|
+
|
|
700
851
|
return {
|
|
701
|
-
type: this.options.sanitize
|
|
852
|
+
type: this.options.sanitize
|
|
853
|
+
? 'text'
|
|
854
|
+
: 'html',
|
|
702
855
|
raw: cap[0],
|
|
703
856
|
inLink: this.lexer.state.inLink,
|
|
704
857
|
inRawBlock: this.lexer.state.inRawBlock,
|
|
705
|
-
|
|
706
|
-
|
|
858
|
+
text: this.options.sanitize
|
|
859
|
+
? (this.options.sanitizer
|
|
860
|
+
? this.options.sanitizer(cap[0])
|
|
861
|
+
: escape(cap[0]))
|
|
862
|
+
: cap[0]
|
|
707
863
|
};
|
|
708
864
|
}
|
|
709
865
|
}
|
|
866
|
+
|
|
710
867
|
link(src) {
|
|
711
868
|
const cap = this.rules.inline.link.exec(src);
|
|
712
869
|
if (cap) {
|
|
713
870
|
const trimmedUrl = cap[2].trim();
|
|
714
871
|
if (!this.options.pedantic && /^</.test(trimmedUrl)) {
|
|
715
|
-
|
|
872
|
+
// commonmark requires matching angle brackets
|
|
873
|
+
if (!(/>$/.test(trimmedUrl))) {
|
|
716
874
|
return;
|
|
717
875
|
}
|
|
718
|
-
|
|
876
|
+
|
|
877
|
+
// ending angle bracket cannot be escaped
|
|
878
|
+
const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
|
|
719
879
|
if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
|
|
720
880
|
return;
|
|
721
881
|
}
|
|
722
882
|
} else {
|
|
723
|
-
|
|
883
|
+
// find closing parenthesis
|
|
884
|
+
const lastParenIndex = findClosingBracket(cap[2], '()');
|
|
724
885
|
if (lastParenIndex > -1) {
|
|
725
|
-
const start = cap[0].indexOf(
|
|
886
|
+
const start = cap[0].indexOf('!') === 0 ? 5 : 4;
|
|
726
887
|
const linkLen = start + cap[1].length + lastParenIndex;
|
|
727
888
|
cap[2] = cap[2].substring(0, lastParenIndex);
|
|
728
889
|
cap[0] = cap[0].substring(0, linkLen).trim();
|
|
729
|
-
cap[3] =
|
|
890
|
+
cap[3] = '';
|
|
730
891
|
}
|
|
731
892
|
}
|
|
732
893
|
let href = cap[2];
|
|
733
|
-
let title =
|
|
894
|
+
let title = '';
|
|
734
895
|
if (this.options.pedantic) {
|
|
896
|
+
// split pedantic href and title
|
|
735
897
|
const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
|
|
898
|
+
|
|
736
899
|
if (link) {
|
|
737
900
|
href = link[1];
|
|
738
901
|
title = link[3];
|
|
739
902
|
}
|
|
740
903
|
} else {
|
|
741
|
-
title = cap[3] ? cap[3].slice(1, -1) :
|
|
904
|
+
title = cap[3] ? cap[3].slice(1, -1) : '';
|
|
742
905
|
}
|
|
906
|
+
|
|
743
907
|
href = href.trim();
|
|
744
908
|
if (/^</.test(href)) {
|
|
745
|
-
if (this.options.pedantic &&
|
|
909
|
+
if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
|
|
910
|
+
// pedantic allows starting angle bracket without ending angle bracket
|
|
746
911
|
href = href.slice(1);
|
|
747
912
|
} else {
|
|
748
913
|
href = href.slice(1, -1);
|
|
749
914
|
}
|
|
750
915
|
}
|
|
751
916
|
return outputLink(cap, {
|
|
752
|
-
href: href ? href.replace(this.rules.inline._escapes,
|
|
753
|
-
title: title ? title.replace(this.rules.inline._escapes,
|
|
917
|
+
href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
|
|
918
|
+
title: title ? title.replace(this.rules.inline._escapes, '$1') : title
|
|
754
919
|
}, cap[0], this.lexer);
|
|
755
920
|
}
|
|
756
921
|
}
|
|
922
|
+
|
|
757
923
|
reflink(src, links) {
|
|
758
924
|
let cap;
|
|
759
|
-
if ((cap = this.rules.inline.reflink.exec(src))
|
|
760
|
-
|
|
925
|
+
if ((cap = this.rules.inline.reflink.exec(src))
|
|
926
|
+
|| (cap = this.rules.inline.nolink.exec(src))) {
|
|
927
|
+
let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
|
|
761
928
|
link = links[link.toLowerCase()];
|
|
762
929
|
if (!link) {
|
|
763
930
|
const text = cap[0].charAt(0);
|
|
764
931
|
return {
|
|
765
|
-
type:
|
|
932
|
+
type: 'text',
|
|
766
933
|
raw: text,
|
|
767
934
|
text
|
|
768
935
|
};
|
|
@@ -770,50 +937,67 @@ var _Tokenizer = class {
|
|
|
770
937
|
return outputLink(cap, link, cap[0], this.lexer);
|
|
771
938
|
}
|
|
772
939
|
}
|
|
773
|
-
|
|
940
|
+
|
|
941
|
+
emStrong(src, maskedSrc, prevChar = '') {
|
|
774
942
|
let match = this.rules.inline.emStrong.lDelim.exec(src);
|
|
775
|
-
if (!match)
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
943
|
+
if (!match) return;
|
|
944
|
+
|
|
945
|
+
// _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
|
|
946
|
+
if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return;
|
|
947
|
+
|
|
948
|
+
const nextChar = match[1] || match[2] || '';
|
|
949
|
+
|
|
950
|
+
if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
|
|
781
951
|
const lLength = match[0].length - 1;
|
|
782
952
|
let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
|
|
783
|
-
|
|
953
|
+
|
|
954
|
+
const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
|
|
784
955
|
endReg.lastIndex = 0;
|
|
956
|
+
|
|
957
|
+
// Clip maskedSrc to same section of string as src (move to lexer?)
|
|
785
958
|
maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
|
|
959
|
+
|
|
786
960
|
while ((match = endReg.exec(maskedSrc)) != null) {
|
|
787
961
|
rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
|
|
788
|
-
|
|
789
|
-
|
|
962
|
+
|
|
963
|
+
if (!rDelim) continue; // skip single * in __abc*abc__
|
|
964
|
+
|
|
790
965
|
rLength = rDelim.length;
|
|
791
|
-
|
|
966
|
+
|
|
967
|
+
if (match[3] || match[4]) { // found another Left Delim
|
|
792
968
|
delimTotal += rLength;
|
|
793
969
|
continue;
|
|
794
|
-
} else if (match[5] || match[6]) {
|
|
970
|
+
} else if (match[5] || match[6]) { // either Left or Right Delim
|
|
795
971
|
if (lLength % 3 && !((lLength + rLength) % 3)) {
|
|
796
972
|
midDelimTotal += rLength;
|
|
797
|
-
continue;
|
|
973
|
+
continue; // CommonMark Emphasis Rules 9-10
|
|
798
974
|
}
|
|
799
975
|
}
|
|
976
|
+
|
|
800
977
|
delimTotal -= rLength;
|
|
801
|
-
|
|
802
|
-
|
|
978
|
+
|
|
979
|
+
if (delimTotal > 0) continue; // Haven't found enough closing delimiters
|
|
980
|
+
|
|
981
|
+
// Remove extra characters. *a*** -> *a*
|
|
803
982
|
rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
|
|
804
|
-
|
|
983
|
+
|
|
984
|
+
const raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength);
|
|
985
|
+
|
|
986
|
+
// Create `em` if smallest delimiter has odd char count. *a***
|
|
805
987
|
if (Math.min(lLength, rLength) % 2) {
|
|
806
|
-
const
|
|
988
|
+
const text = raw.slice(1, -1);
|
|
807
989
|
return {
|
|
808
|
-
type:
|
|
990
|
+
type: 'em',
|
|
809
991
|
raw,
|
|
810
|
-
text
|
|
811
|
-
tokens: this.lexer.inlineTokens(
|
|
992
|
+
text,
|
|
993
|
+
tokens: this.lexer.inlineTokens(text)
|
|
812
994
|
};
|
|
813
995
|
}
|
|
996
|
+
|
|
997
|
+
// Create 'strong' if smallest delimiter has even char count. **a***
|
|
814
998
|
const text = raw.slice(2, -2);
|
|
815
999
|
return {
|
|
816
|
-
type:
|
|
1000
|
+
type: 'strong',
|
|
817
1001
|
raw,
|
|
818
1002
|
text,
|
|
819
1003
|
tokens: this.lexer.inlineTokens(text)
|
|
@@ -821,10 +1005,11 @@ var _Tokenizer = class {
|
|
|
821
1005
|
}
|
|
822
1006
|
}
|
|
823
1007
|
}
|
|
1008
|
+
|
|
824
1009
|
codespan(src) {
|
|
825
1010
|
const cap = this.rules.inline.code.exec(src);
|
|
826
1011
|
if (cap) {
|
|
827
|
-
let text = cap[2].replace(/\n/g,
|
|
1012
|
+
let text = cap[2].replace(/\n/g, ' ');
|
|
828
1013
|
const hasNonSpaceChars = /[^ ]/.test(text);
|
|
829
1014
|
const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
|
|
830
1015
|
if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
|
|
@@ -832,51 +1017,55 @@ var _Tokenizer = class {
|
|
|
832
1017
|
}
|
|
833
1018
|
text = escape(text, true);
|
|
834
1019
|
return {
|
|
835
|
-
type:
|
|
1020
|
+
type: 'codespan',
|
|
836
1021
|
raw: cap[0],
|
|
837
1022
|
text
|
|
838
1023
|
};
|
|
839
1024
|
}
|
|
840
1025
|
}
|
|
1026
|
+
|
|
841
1027
|
br(src) {
|
|
842
1028
|
const cap = this.rules.inline.br.exec(src);
|
|
843
1029
|
if (cap) {
|
|
844
1030
|
return {
|
|
845
|
-
type:
|
|
1031
|
+
type: 'br',
|
|
846
1032
|
raw: cap[0]
|
|
847
1033
|
};
|
|
848
1034
|
}
|
|
849
1035
|
}
|
|
1036
|
+
|
|
850
1037
|
del(src) {
|
|
851
1038
|
const cap = this.rules.inline.del.exec(src);
|
|
852
1039
|
if (cap) {
|
|
853
1040
|
return {
|
|
854
|
-
type:
|
|
1041
|
+
type: 'del',
|
|
855
1042
|
raw: cap[0],
|
|
856
1043
|
text: cap[2],
|
|
857
1044
|
tokens: this.lexer.inlineTokens(cap[2])
|
|
858
1045
|
};
|
|
859
1046
|
}
|
|
860
1047
|
}
|
|
861
|
-
|
|
1048
|
+
|
|
1049
|
+
autolink(src, mangle) {
|
|
862
1050
|
const cap = this.rules.inline.autolink.exec(src);
|
|
863
1051
|
if (cap) {
|
|
864
1052
|
let text, href;
|
|
865
|
-
if (cap[2] ===
|
|
866
|
-
text = escape(this.options.mangle ?
|
|
867
|
-
href =
|
|
1053
|
+
if (cap[2] === '@') {
|
|
1054
|
+
text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
|
|
1055
|
+
href = 'mailto:' + text;
|
|
868
1056
|
} else {
|
|
869
1057
|
text = escape(cap[1]);
|
|
870
1058
|
href = text;
|
|
871
1059
|
}
|
|
1060
|
+
|
|
872
1061
|
return {
|
|
873
|
-
type:
|
|
1062
|
+
type: 'link',
|
|
874
1063
|
raw: cap[0],
|
|
875
1064
|
text,
|
|
876
1065
|
href,
|
|
877
1066
|
tokens: [
|
|
878
1067
|
{
|
|
879
|
-
type:
|
|
1068
|
+
type: 'text',
|
|
880
1069
|
raw: text,
|
|
881
1070
|
text
|
|
882
1071
|
}
|
|
@@ -884,34 +1073,36 @@ var _Tokenizer = class {
|
|
|
884
1073
|
};
|
|
885
1074
|
}
|
|
886
1075
|
}
|
|
887
|
-
|
|
1076
|
+
|
|
1077
|
+
url(src, mangle) {
|
|
888
1078
|
let cap;
|
|
889
1079
|
if (cap = this.rules.inline.url.exec(src)) {
|
|
890
1080
|
let text, href;
|
|
891
|
-
if (cap[2] ===
|
|
892
|
-
text = escape(this.options.mangle ?
|
|
893
|
-
href =
|
|
1081
|
+
if (cap[2] === '@') {
|
|
1082
|
+
text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
|
|
1083
|
+
href = 'mailto:' + text;
|
|
894
1084
|
} else {
|
|
1085
|
+
// do extended autolink path validation
|
|
895
1086
|
let prevCapZero;
|
|
896
1087
|
do {
|
|
897
1088
|
prevCapZero = cap[0];
|
|
898
1089
|
cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
|
|
899
1090
|
} while (prevCapZero !== cap[0]);
|
|
900
1091
|
text = escape(cap[0]);
|
|
901
|
-
if (cap[1] ===
|
|
902
|
-
href =
|
|
1092
|
+
if (cap[1] === 'www.') {
|
|
1093
|
+
href = 'http://' + cap[0];
|
|
903
1094
|
} else {
|
|
904
1095
|
href = cap[0];
|
|
905
1096
|
}
|
|
906
1097
|
}
|
|
907
1098
|
return {
|
|
908
|
-
type:
|
|
1099
|
+
type: 'link',
|
|
909
1100
|
raw: cap[0],
|
|
910
1101
|
text,
|
|
911
1102
|
href,
|
|
912
1103
|
tokens: [
|
|
913
1104
|
{
|
|
914
|
-
type:
|
|
1105
|
+
type: 'text',
|
|
915
1106
|
raw: text,
|
|
916
1107
|
text
|
|
917
1108
|
}
|
|
@@ -919,124 +1110,277 @@ var _Tokenizer = class {
|
|
|
919
1110
|
};
|
|
920
1111
|
}
|
|
921
1112
|
}
|
|
922
|
-
|
|
1113
|
+
|
|
1114
|
+
inlineText(src, smartypants) {
|
|
923
1115
|
const cap = this.rules.inline.text.exec(src);
|
|
924
1116
|
if (cap) {
|
|
925
1117
|
let text;
|
|
926
1118
|
if (this.lexer.state.inRawBlock) {
|
|
927
|
-
text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
|
|
1119
|
+
text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];
|
|
928
1120
|
} else {
|
|
929
|
-
text = escape(this.options.smartypants ?
|
|
1121
|
+
text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
|
|
930
1122
|
}
|
|
931
1123
|
return {
|
|
932
|
-
type:
|
|
1124
|
+
type: 'text',
|
|
933
1125
|
raw: cap[0],
|
|
934
1126
|
text
|
|
935
1127
|
};
|
|
936
1128
|
}
|
|
937
1129
|
}
|
|
938
|
-
}
|
|
1130
|
+
}
|
|
939
1131
|
|
|
940
|
-
|
|
941
|
-
|
|
1132
|
+
/**
|
|
1133
|
+
* Block-Level Grammar
|
|
1134
|
+
*/
|
|
1135
|
+
const block = {
|
|
942
1136
|
newline: /^(?: *(?:\n|$))+/,
|
|
943
1137
|
code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
|
|
944
|
-
fences: /^ {0,3}(`{3,}(?=[^`\n]
|
|
1138
|
+
fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
|
|
945
1139
|
hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
|
|
946
1140
|
heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
|
|
947
1141
|
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
|
|
948
1142
|
list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
|
|
949
|
-
html:
|
|
1143
|
+
html: '^ {0,3}(?:' // optional indentation
|
|
1144
|
+
+ '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
1145
|
+
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
1146
|
+
+ '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
|
|
1147
|
+
+ '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
|
|
1148
|
+
+ '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
|
|
1149
|
+
+ '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
|
|
1150
|
+
+ '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
|
|
1151
|
+
+ '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
|
|
1152
|
+
+ ')',
|
|
950
1153
|
def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
|
|
951
1154
|
table: noopTest,
|
|
952
|
-
lheading: /^((
|
|
1155
|
+
lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
953
1156
|
// regex template, placeholders will be replaced according to different paragraph
|
|
954
1157
|
// interruption rules of commonmark and the original markdown spec:
|
|
955
1158
|
_paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
|
|
956
1159
|
text: /^[^\n]+/
|
|
957
1160
|
};
|
|
1161
|
+
|
|
958
1162
|
block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
|
|
959
1163
|
block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
|
|
960
|
-
block.def = edit(block.def)
|
|
1164
|
+
block.def = edit(block.def)
|
|
1165
|
+
.replace('label', block._label)
|
|
1166
|
+
.replace('title', block._title)
|
|
1167
|
+
.getRegex();
|
|
1168
|
+
|
|
961
1169
|
block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
|
|
962
|
-
block.listItemStart = edit(/^( *)(bull) */)
|
|
963
|
-
|
|
964
|
-
|
|
1170
|
+
block.listItemStart = edit(/^( *)(bull) */)
|
|
1171
|
+
.replace('bull', block.bullet)
|
|
1172
|
+
.getRegex();
|
|
1173
|
+
|
|
1174
|
+
block.list = edit(block.list)
|
|
1175
|
+
.replace(/bull/g, block.bullet)
|
|
1176
|
+
.replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
|
|
1177
|
+
.replace('def', '\\n+(?=' + block.def.source + ')')
|
|
1178
|
+
.getRegex();
|
|
1179
|
+
|
|
1180
|
+
block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
|
|
1181
|
+
+ '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
|
|
1182
|
+
+ '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
|
|
1183
|
+
+ '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
|
|
1184
|
+
+ '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
|
|
1185
|
+
+ '|track|ul';
|
|
965
1186
|
block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
|
|
966
|
-
block.html = edit(block.html,
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1187
|
+
block.html = edit(block.html, 'i')
|
|
1188
|
+
.replace('comment', block._comment)
|
|
1189
|
+
.replace('tag', block._tag)
|
|
1190
|
+
.replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
|
|
1191
|
+
.getRegex();
|
|
1192
|
+
|
|
1193
|
+
block.paragraph = edit(block._paragraph)
|
|
1194
|
+
.replace('hr', block.hr)
|
|
1195
|
+
.replace('heading', ' {0,3}#{1,6} ')
|
|
1196
|
+
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
1197
|
+
.replace('|table', '')
|
|
1198
|
+
.replace('blockquote', ' {0,3}>')
|
|
1199
|
+
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
1200
|
+
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
1201
|
+
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
1202
|
+
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
|
|
1203
|
+
.getRegex();
|
|
1204
|
+
|
|
1205
|
+
block.blockquote = edit(block.blockquote)
|
|
1206
|
+
.replace('paragraph', block.paragraph)
|
|
1207
|
+
.getRegex();
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Normal Block Grammar
|
|
1211
|
+
*/
|
|
1212
|
+
|
|
1213
|
+
block.normal = merge({}, block);
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* GFM Block Grammar
|
|
1217
|
+
*/
|
|
1218
|
+
|
|
1219
|
+
block.gfm = merge({}, block.normal, {
|
|
1220
|
+
table: '^ *([^\\n ].*\\|.*)\\n' // Header
|
|
1221
|
+
+ ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
|
|
1222
|
+
+ '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
block.gfm.table = edit(block.gfm.table)
|
|
1226
|
+
.replace('hr', block.hr)
|
|
1227
|
+
.replace('heading', ' {0,3}#{1,6} ')
|
|
1228
|
+
.replace('blockquote', ' {0,3}>')
|
|
1229
|
+
.replace('code', ' {4}[^\\n]')
|
|
1230
|
+
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
1231
|
+
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
1232
|
+
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
1233
|
+
.replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
|
|
1234
|
+
.getRegex();
|
|
1235
|
+
|
|
1236
|
+
block.gfm.paragraph = edit(block._paragraph)
|
|
1237
|
+
.replace('hr', block.hr)
|
|
1238
|
+
.replace('heading', ' {0,3}#{1,6} ')
|
|
1239
|
+
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
1240
|
+
.replace('table', block.gfm.table) // interrupt paragraphs with table
|
|
1241
|
+
.replace('blockquote', ' {0,3}>')
|
|
1242
|
+
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
1243
|
+
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
1244
|
+
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
1245
|
+
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
|
|
1246
|
+
.getRegex();
|
|
1247
|
+
/**
|
|
1248
|
+
* Pedantic grammar (original John Gruber's loose markdown specification)
|
|
1249
|
+
*/
|
|
1250
|
+
|
|
1251
|
+
block.pedantic = merge({}, block.normal, {
|
|
980
1252
|
html: edit(
|
|
981
|
-
|
|
982
|
-
|
|
1253
|
+
'^ *(?:comment *(?:\\n|\\s*$)'
|
|
1254
|
+
+ '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
|
|
1255
|
+
+ '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
|
|
1256
|
+
.replace('comment', block._comment)
|
|
1257
|
+
.replace(/tag/g, '(?!(?:'
|
|
1258
|
+
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
|
|
1259
|
+
+ '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
|
|
1260
|
+
+ '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
|
|
1261
|
+
.getRegex(),
|
|
983
1262
|
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
|
|
984
1263
|
heading: /^(#{1,6})(.*)(?:\n+|$)/,
|
|
985
|
-
fences: noopTest,
|
|
986
|
-
// fences not supported
|
|
1264
|
+
fences: noopTest, // fences not supported
|
|
987
1265
|
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
988
|
-
paragraph: edit(block.normal._paragraph)
|
|
989
|
-
|
|
990
|
-
|
|
1266
|
+
paragraph: edit(block.normal._paragraph)
|
|
1267
|
+
.replace('hr', block.hr)
|
|
1268
|
+
.replace('heading', ' *#{1,6} *[^\n]')
|
|
1269
|
+
.replace('lheading', block.lheading)
|
|
1270
|
+
.replace('blockquote', ' {0,3}>')
|
|
1271
|
+
.replace('|fences', '')
|
|
1272
|
+
.replace('|list', '')
|
|
1273
|
+
.replace('|html', '')
|
|
1274
|
+
.getRegex()
|
|
1275
|
+
});
|
|
1276
|
+
|
|
1277
|
+
/**
|
|
1278
|
+
* Inline-Level Grammar
|
|
1279
|
+
*/
|
|
1280
|
+
const inline = {
|
|
991
1281
|
escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
|
|
992
1282
|
autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
|
|
993
1283
|
url: noopTest,
|
|
994
|
-
tag:
|
|
995
|
-
|
|
1284
|
+
tag: '^comment'
|
|
1285
|
+
+ '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
|
|
1286
|
+
+ '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
|
|
1287
|
+
+ '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
|
|
1288
|
+
+ '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
|
|
1289
|
+
+ '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
|
|
996
1290
|
link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
|
|
997
1291
|
reflink: /^!?\[(label)\]\[(ref)\]/,
|
|
998
1292
|
nolink: /^!?\[(ref)\](?:\[\])?/,
|
|
999
|
-
reflinkSearch:
|
|
1293
|
+
reflinkSearch: 'reflink|nolink(?!\\()',
|
|
1000
1294
|
emStrong: {
|
|
1001
|
-
lDelim: /^(?:\*+(?:(
|
|
1002
|
-
//
|
|
1003
|
-
//
|
|
1004
|
-
rDelimAst: /^[^_
|
|
1005
|
-
rDelimUnd: /^[^_
|
|
1006
|
-
// ^- Not allowed for _
|
|
1295
|
+
lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
|
|
1296
|
+
// (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
|
|
1297
|
+
// () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
|
|
1298
|
+
rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,
|
|
1299
|
+
rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
|
|
1007
1300
|
},
|
|
1008
1301
|
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
|
1009
1302
|
br: /^( {2,}|\\)\n(?!\s*$)/,
|
|
1010
1303
|
del: noopTest,
|
|
1011
1304
|
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
|
|
1012
|
-
punctuation: /^(
|
|
1305
|
+
punctuation: /^([\spunctuation])/
|
|
1013
1306
|
};
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
inline.
|
|
1018
|
-
inline.
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
inline.
|
|
1022
|
-
|
|
1023
|
-
inline.
|
|
1024
|
-
inline.
|
|
1307
|
+
|
|
1308
|
+
// list of punctuation marks from CommonMark spec
|
|
1309
|
+
// without * and _ to handle the different emphasis markers * and _
|
|
1310
|
+
inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
|
|
1311
|
+
inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
|
|
1312
|
+
|
|
1313
|
+
// sequences em should skip over [title](link), `code`, <html>
|
|
1314
|
+
inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
|
|
1315
|
+
// lookbehind is not available on Safari as of version 16
|
|
1316
|
+
// inline.escapedEmSt = /(?<=(?:^|[^\\)(?:\\[^])*)\\[*_]/g;
|
|
1317
|
+
inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g;
|
|
1318
|
+
|
|
1319
|
+
inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
|
|
1320
|
+
|
|
1321
|
+
inline.emStrong.lDelim = edit(inline.emStrong.lDelim)
|
|
1322
|
+
.replace(/punct/g, inline._punctuation)
|
|
1323
|
+
.getRegex();
|
|
1324
|
+
|
|
1325
|
+
inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g')
|
|
1326
|
+
.replace(/punct/g, inline._punctuation)
|
|
1327
|
+
.getRegex();
|
|
1328
|
+
|
|
1329
|
+
inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g')
|
|
1330
|
+
.replace(/punct/g, inline._punctuation)
|
|
1331
|
+
.getRegex();
|
|
1332
|
+
|
|
1333
|
+
inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
|
|
1334
|
+
|
|
1025
1335
|
inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
|
|
1026
1336
|
inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
|
|
1027
|
-
inline.autolink = edit(inline.autolink)
|
|
1337
|
+
inline.autolink = edit(inline.autolink)
|
|
1338
|
+
.replace('scheme', inline._scheme)
|
|
1339
|
+
.replace('email', inline._email)
|
|
1340
|
+
.getRegex();
|
|
1341
|
+
|
|
1028
1342
|
inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
|
|
1029
|
-
|
|
1343
|
+
|
|
1344
|
+
inline.tag = edit(inline.tag)
|
|
1345
|
+
.replace('comment', inline._comment)
|
|
1346
|
+
.replace('attribute', inline._attribute)
|
|
1347
|
+
.getRegex();
|
|
1348
|
+
|
|
1030
1349
|
inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
|
|
1031
1350
|
inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
|
|
1032
1351
|
inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
|
|
1033
|
-
|
|
1034
|
-
inline.
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1352
|
+
|
|
1353
|
+
inline.link = edit(inline.link)
|
|
1354
|
+
.replace('label', inline._label)
|
|
1355
|
+
.replace('href', inline._href)
|
|
1356
|
+
.replace('title', inline._title)
|
|
1357
|
+
.getRegex();
|
|
1358
|
+
|
|
1359
|
+
inline.reflink = edit(inline.reflink)
|
|
1360
|
+
.replace('label', inline._label)
|
|
1361
|
+
.replace('ref', block._label)
|
|
1362
|
+
.getRegex();
|
|
1363
|
+
|
|
1364
|
+
inline.nolink = edit(inline.nolink)
|
|
1365
|
+
.replace('ref', block._label)
|
|
1366
|
+
.getRegex();
|
|
1367
|
+
|
|
1368
|
+
inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
|
|
1369
|
+
.replace('reflink', inline.reflink)
|
|
1370
|
+
.replace('nolink', inline.nolink)
|
|
1371
|
+
.getRegex();
|
|
1372
|
+
|
|
1373
|
+
/**
|
|
1374
|
+
* Normal Inline Grammar
|
|
1375
|
+
*/
|
|
1376
|
+
|
|
1377
|
+
inline.normal = merge({}, inline);
|
|
1378
|
+
|
|
1379
|
+
/**
|
|
1380
|
+
* Pedantic Inline Grammar
|
|
1381
|
+
*/
|
|
1382
|
+
|
|
1383
|
+
inline.pedantic = merge({}, inline.normal, {
|
|
1040
1384
|
strong: {
|
|
1041
1385
|
start: /^__|\*\*/,
|
|
1042
1386
|
middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
|
@@ -1049,47 +1393,94 @@ inline.pedantic = {
|
|
|
1049
1393
|
endAst: /\*(?!\*)/g,
|
|
1050
1394
|
endUnd: /_(?!_)/g
|
|
1051
1395
|
},
|
|
1052
|
-
link: edit(/^!?\[(label)\]\((.*?)\)/)
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1396
|
+
link: edit(/^!?\[(label)\]\((.*?)\)/)
|
|
1397
|
+
.replace('label', inline._label)
|
|
1398
|
+
.getRegex(),
|
|
1399
|
+
reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
|
|
1400
|
+
.replace('label', inline._label)
|
|
1401
|
+
.getRegex()
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
/**
|
|
1405
|
+
* GFM Inline Grammar
|
|
1406
|
+
*/
|
|
1407
|
+
|
|
1408
|
+
inline.gfm = merge({}, inline.normal, {
|
|
1409
|
+
escape: edit(inline.escape).replace('])', '~|])').getRegex(),
|
|
1058
1410
|
_extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
|
|
1059
1411
|
url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
|
|
1060
1412
|
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
|
|
1061
1413
|
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
|
|
1062
1414
|
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
|
1063
|
-
};
|
|
1064
|
-
|
|
1065
|
-
inline.
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1417
|
+
inline.gfm.url = edit(inline.gfm.url, 'i')
|
|
1418
|
+
.replace('email', inline.gfm._extended_email)
|
|
1419
|
+
.getRegex();
|
|
1420
|
+
/**
|
|
1421
|
+
* GFM + Line Breaks Inline Grammar
|
|
1422
|
+
*/
|
|
1070
1423
|
|
|
1071
|
-
|
|
1424
|
+
inline.breaks = merge({}, inline.gfm, {
|
|
1425
|
+
br: edit(inline.br).replace('{2,}', '*').getRegex(),
|
|
1426
|
+
text: edit(inline.gfm.text)
|
|
1427
|
+
.replace('\\b_', '\\b_| {2,}\\n')
|
|
1428
|
+
.replace(/\{2,\}/g, '*')
|
|
1429
|
+
.getRegex()
|
|
1430
|
+
});
|
|
1431
|
+
|
|
1432
|
+
/**
|
|
1433
|
+
* smartypants text replacement
|
|
1434
|
+
* @param {string} text
|
|
1435
|
+
*/
|
|
1072
1436
|
function smartypants(text) {
|
|
1073
|
-
return text
|
|
1437
|
+
return text
|
|
1438
|
+
// em-dashes
|
|
1439
|
+
.replace(/---/g, '\u2014')
|
|
1440
|
+
// en-dashes
|
|
1441
|
+
.replace(/--/g, '\u2013')
|
|
1442
|
+
// opening singles
|
|
1443
|
+
.replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
|
|
1444
|
+
// closing singles & apostrophes
|
|
1445
|
+
.replace(/'/g, '\u2019')
|
|
1446
|
+
// opening doubles
|
|
1447
|
+
.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
|
|
1448
|
+
// closing doubles
|
|
1449
|
+
.replace(/"/g, '\u201d')
|
|
1450
|
+
// ellipses
|
|
1451
|
+
.replace(/\.{3}/g, '\u2026');
|
|
1074
1452
|
}
|
|
1453
|
+
|
|
1454
|
+
/**
|
|
1455
|
+
* mangle email addresses
|
|
1456
|
+
* @param {string} text
|
|
1457
|
+
*/
|
|
1075
1458
|
function mangle(text) {
|
|
1076
|
-
let out =
|
|
1459
|
+
let out = '',
|
|
1460
|
+
i,
|
|
1461
|
+
ch;
|
|
1462
|
+
|
|
1077
1463
|
const l = text.length;
|
|
1078
1464
|
for (i = 0; i < l; i++) {
|
|
1079
1465
|
ch = text.charCodeAt(i);
|
|
1080
1466
|
if (Math.random() > 0.5) {
|
|
1081
|
-
ch =
|
|
1467
|
+
ch = 'x' + ch.toString(16);
|
|
1082
1468
|
}
|
|
1083
|
-
out +=
|
|
1469
|
+
out += '&#' + ch + ';';
|
|
1084
1470
|
}
|
|
1471
|
+
|
|
1085
1472
|
return out;
|
|
1086
1473
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1474
|
+
|
|
1475
|
+
/**
|
|
1476
|
+
* Block Lexer
|
|
1477
|
+
*/
|
|
1478
|
+
class Lexer {
|
|
1479
|
+
constructor(options) {
|
|
1089
1480
|
this.tokens = [];
|
|
1090
|
-
this.tokens.links =
|
|
1091
|
-
this.options =
|
|
1092
|
-
this.options.tokenizer = this.options.tokenizer || new
|
|
1481
|
+
this.tokens.links = Object.create(null);
|
|
1482
|
+
this.options = options || defaults;
|
|
1483
|
+
this.options.tokenizer = this.options.tokenizer || new Tokenizer();
|
|
1093
1484
|
this.tokenizer = this.options.tokenizer;
|
|
1094
1485
|
this.tokenizer.options = this.options;
|
|
1095
1486
|
this.tokenizer.lexer = this;
|
|
@@ -1099,10 +1490,12 @@ var _Lexer = class {
|
|
|
1099
1490
|
inRawBlock: false,
|
|
1100
1491
|
top: true
|
|
1101
1492
|
};
|
|
1493
|
+
|
|
1102
1494
|
const rules = {
|
|
1103
1495
|
block: block.normal,
|
|
1104
1496
|
inline: inline.normal
|
|
1105
1497
|
};
|
|
1498
|
+
|
|
1106
1499
|
if (this.options.pedantic) {
|
|
1107
1500
|
rules.block = block.pedantic;
|
|
1108
1501
|
rules.inline = inline.pedantic;
|
|
@@ -1116,6 +1509,7 @@ var _Lexer = class {
|
|
|
1116
1509
|
}
|
|
1117
1510
|
this.tokenizer.rules = rules;
|
|
1118
1511
|
}
|
|
1512
|
+
|
|
1119
1513
|
/**
|
|
1120
1514
|
* Expose Rules
|
|
1121
1515
|
*/
|
|
@@ -1125,109 +1519,145 @@ var _Lexer = class {
|
|
|
1125
1519
|
inline
|
|
1126
1520
|
};
|
|
1127
1521
|
}
|
|
1522
|
+
|
|
1128
1523
|
/**
|
|
1129
1524
|
* Static Lex Method
|
|
1130
1525
|
*/
|
|
1131
|
-
static lex(src,
|
|
1132
|
-
const
|
|
1133
|
-
return
|
|
1526
|
+
static lex(src, options) {
|
|
1527
|
+
const lexer = new Lexer(options);
|
|
1528
|
+
return lexer.lex(src);
|
|
1134
1529
|
}
|
|
1530
|
+
|
|
1135
1531
|
/**
|
|
1136
1532
|
* Static Lex Inline Method
|
|
1137
1533
|
*/
|
|
1138
|
-
static lexInline(src,
|
|
1139
|
-
const
|
|
1140
|
-
return
|
|
1534
|
+
static lexInline(src, options) {
|
|
1535
|
+
const lexer = new Lexer(options);
|
|
1536
|
+
return lexer.inlineTokens(src);
|
|
1141
1537
|
}
|
|
1538
|
+
|
|
1142
1539
|
/**
|
|
1143
1540
|
* Preprocessing
|
|
1144
1541
|
*/
|
|
1145
1542
|
lex(src) {
|
|
1146
|
-
src = src
|
|
1543
|
+
src = src
|
|
1544
|
+
.replace(/\r\n|\r/g, '\n');
|
|
1545
|
+
|
|
1147
1546
|
this.blockTokens(src, this.tokens);
|
|
1547
|
+
|
|
1148
1548
|
let next;
|
|
1149
1549
|
while (next = this.inlineQueue.shift()) {
|
|
1150
1550
|
this.inlineTokens(next.src, next.tokens);
|
|
1151
1551
|
}
|
|
1552
|
+
|
|
1152
1553
|
return this.tokens;
|
|
1153
1554
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Lexing
|
|
1558
|
+
*/
|
|
1559
|
+
blockTokens(src, tokens = []) {
|
|
1560
|
+
if (this.options.pedantic) {
|
|
1561
|
+
src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
|
|
1157
1562
|
} else {
|
|
1158
1563
|
src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
|
|
1159
|
-
return leading +
|
|
1564
|
+
return leading + ' '.repeat(tabs.length);
|
|
1160
1565
|
});
|
|
1161
1566
|
}
|
|
1567
|
+
|
|
1162
1568
|
let token, lastToken, cutSrc, lastParagraphClipped;
|
|
1569
|
+
|
|
1163
1570
|
while (src) {
|
|
1164
|
-
if (this.options.extensions
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1571
|
+
if (this.options.extensions
|
|
1572
|
+
&& this.options.extensions.block
|
|
1573
|
+
&& this.options.extensions.block.some((extTokenizer) => {
|
|
1574
|
+
if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
|
|
1575
|
+
src = src.substring(token.raw.length);
|
|
1576
|
+
tokens.push(token);
|
|
1577
|
+
return true;
|
|
1578
|
+
}
|
|
1579
|
+
return false;
|
|
1580
|
+
})) {
|
|
1172
1581
|
continue;
|
|
1173
1582
|
}
|
|
1583
|
+
|
|
1584
|
+
// newline
|
|
1174
1585
|
if (token = this.tokenizer.space(src)) {
|
|
1175
1586
|
src = src.substring(token.raw.length);
|
|
1176
1587
|
if (token.raw.length === 1 && tokens.length > 0) {
|
|
1177
|
-
|
|
1588
|
+
// if there's a single \n as a spacer, it's terminating the last line,
|
|
1589
|
+
// so move it there so that we don't get unecessary paragraph tags
|
|
1590
|
+
tokens[tokens.length - 1].raw += '\n';
|
|
1178
1591
|
} else {
|
|
1179
1592
|
tokens.push(token);
|
|
1180
1593
|
}
|
|
1181
1594
|
continue;
|
|
1182
1595
|
}
|
|
1596
|
+
|
|
1597
|
+
// code
|
|
1183
1598
|
if (token = this.tokenizer.code(src)) {
|
|
1184
1599
|
src = src.substring(token.raw.length);
|
|
1185
1600
|
lastToken = tokens[tokens.length - 1];
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
lastToken.
|
|
1601
|
+
// An indented code block cannot interrupt a paragraph.
|
|
1602
|
+
if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
|
|
1603
|
+
lastToken.raw += '\n' + token.raw;
|
|
1604
|
+
lastToken.text += '\n' + token.text;
|
|
1189
1605
|
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
1190
1606
|
} else {
|
|
1191
1607
|
tokens.push(token);
|
|
1192
1608
|
}
|
|
1193
1609
|
continue;
|
|
1194
1610
|
}
|
|
1611
|
+
|
|
1612
|
+
// fences
|
|
1195
1613
|
if (token = this.tokenizer.fences(src)) {
|
|
1196
1614
|
src = src.substring(token.raw.length);
|
|
1197
1615
|
tokens.push(token);
|
|
1198
1616
|
continue;
|
|
1199
1617
|
}
|
|
1618
|
+
|
|
1619
|
+
// heading
|
|
1200
1620
|
if (token = this.tokenizer.heading(src)) {
|
|
1201
1621
|
src = src.substring(token.raw.length);
|
|
1202
1622
|
tokens.push(token);
|
|
1203
1623
|
continue;
|
|
1204
1624
|
}
|
|
1625
|
+
|
|
1626
|
+
// hr
|
|
1205
1627
|
if (token = this.tokenizer.hr(src)) {
|
|
1206
1628
|
src = src.substring(token.raw.length);
|
|
1207
1629
|
tokens.push(token);
|
|
1208
1630
|
continue;
|
|
1209
1631
|
}
|
|
1632
|
+
|
|
1633
|
+
// blockquote
|
|
1210
1634
|
if (token = this.tokenizer.blockquote(src)) {
|
|
1211
1635
|
src = src.substring(token.raw.length);
|
|
1212
1636
|
tokens.push(token);
|
|
1213
1637
|
continue;
|
|
1214
1638
|
}
|
|
1639
|
+
|
|
1640
|
+
// list
|
|
1215
1641
|
if (token = this.tokenizer.list(src)) {
|
|
1216
1642
|
src = src.substring(token.raw.length);
|
|
1217
1643
|
tokens.push(token);
|
|
1218
1644
|
continue;
|
|
1219
1645
|
}
|
|
1646
|
+
|
|
1647
|
+
// html
|
|
1220
1648
|
if (token = this.tokenizer.html(src)) {
|
|
1221
1649
|
src = src.substring(token.raw.length);
|
|
1222
1650
|
tokens.push(token);
|
|
1223
1651
|
continue;
|
|
1224
1652
|
}
|
|
1653
|
+
|
|
1654
|
+
// def
|
|
1225
1655
|
if (token = this.tokenizer.def(src)) {
|
|
1226
1656
|
src = src.substring(token.raw.length);
|
|
1227
1657
|
lastToken = tokens[tokens.length - 1];
|
|
1228
|
-
if (lastToken && (lastToken.type ===
|
|
1229
|
-
lastToken.raw +=
|
|
1230
|
-
lastToken.text +=
|
|
1658
|
+
if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
|
|
1659
|
+
lastToken.raw += '\n' + token.raw;
|
|
1660
|
+
lastToken.text += '\n' + token.raw;
|
|
1231
1661
|
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
1232
1662
|
} else if (!this.tokens.links[token.tag]) {
|
|
1233
1663
|
this.tokens.links[token.tag] = {
|
|
@@ -1237,26 +1667,31 @@ var _Lexer = class {
|
|
|
1237
1667
|
}
|
|
1238
1668
|
continue;
|
|
1239
1669
|
}
|
|
1670
|
+
|
|
1671
|
+
// table (gfm)
|
|
1240
1672
|
if (token = this.tokenizer.table(src)) {
|
|
1241
1673
|
src = src.substring(token.raw.length);
|
|
1242
1674
|
tokens.push(token);
|
|
1243
1675
|
continue;
|
|
1244
1676
|
}
|
|
1677
|
+
|
|
1678
|
+
// lheading
|
|
1245
1679
|
if (token = this.tokenizer.lheading(src)) {
|
|
1246
1680
|
src = src.substring(token.raw.length);
|
|
1247
1681
|
tokens.push(token);
|
|
1248
1682
|
continue;
|
|
1249
1683
|
}
|
|
1684
|
+
|
|
1685
|
+
// top-level paragraph
|
|
1686
|
+
// prevent paragraph consuming extensions by clipping 'src' to extension start
|
|
1250
1687
|
cutSrc = src;
|
|
1251
1688
|
if (this.options.extensions && this.options.extensions.startBlock) {
|
|
1252
1689
|
let startIndex = Infinity;
|
|
1253
1690
|
const tempSrc = src.slice(1);
|
|
1254
1691
|
let tempStart;
|
|
1255
|
-
this.options.extensions.startBlock.forEach((getStartIndex)
|
|
1692
|
+
this.options.extensions.startBlock.forEach(function(getStartIndex) {
|
|
1256
1693
|
tempStart = getStartIndex.call({ lexer: this }, tempSrc);
|
|
1257
|
-
if (typeof tempStart ===
|
|
1258
|
-
startIndex = Math.min(startIndex, tempStart);
|
|
1259
|
-
}
|
|
1694
|
+
if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
|
|
1260
1695
|
});
|
|
1261
1696
|
if (startIndex < Infinity && startIndex >= 0) {
|
|
1262
1697
|
cutSrc = src.substring(0, startIndex + 1);
|
|
@@ -1264,24 +1699,26 @@ var _Lexer = class {
|
|
|
1264
1699
|
}
|
|
1265
1700
|
if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
|
|
1266
1701
|
lastToken = tokens[tokens.length - 1];
|
|
1267
|
-
if (lastParagraphClipped && lastToken.type ===
|
|
1268
|
-
lastToken.raw +=
|
|
1269
|
-
lastToken.text +=
|
|
1702
|
+
if (lastParagraphClipped && lastToken.type === 'paragraph') {
|
|
1703
|
+
lastToken.raw += '\n' + token.raw;
|
|
1704
|
+
lastToken.text += '\n' + token.text;
|
|
1270
1705
|
this.inlineQueue.pop();
|
|
1271
1706
|
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
1272
1707
|
} else {
|
|
1273
1708
|
tokens.push(token);
|
|
1274
1709
|
}
|
|
1275
|
-
lastParagraphClipped = cutSrc.length !== src.length;
|
|
1710
|
+
lastParagraphClipped = (cutSrc.length !== src.length);
|
|
1276
1711
|
src = src.substring(token.raw.length);
|
|
1277
1712
|
continue;
|
|
1278
1713
|
}
|
|
1714
|
+
|
|
1715
|
+
// text
|
|
1279
1716
|
if (token = this.tokenizer.text(src)) {
|
|
1280
1717
|
src = src.substring(token.raw.length);
|
|
1281
1718
|
lastToken = tokens[tokens.length - 1];
|
|
1282
|
-
if (lastToken && lastToken.type ===
|
|
1283
|
-
lastToken.raw +=
|
|
1284
|
-
lastToken.text +=
|
|
1719
|
+
if (lastToken && lastToken.type === 'text') {
|
|
1720
|
+
lastToken.raw += '\n' + token.raw;
|
|
1721
|
+
lastToken.text += '\n' + token.text;
|
|
1285
1722
|
this.inlineQueue.pop();
|
|
1286
1723
|
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
1287
1724
|
} else {
|
|
@@ -1289,8 +1726,9 @@ var _Lexer = class {
|
|
|
1289
1726
|
}
|
|
1290
1727
|
continue;
|
|
1291
1728
|
}
|
|
1729
|
+
|
|
1292
1730
|
if (src) {
|
|
1293
|
-
const errMsg =
|
|
1731
|
+
const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
|
|
1294
1732
|
if (this.options.silent) {
|
|
1295
1733
|
console.error(errMsg);
|
|
1296
1734
|
break;
|
|
@@ -1299,61 +1737,81 @@ var _Lexer = class {
|
|
|
1299
1737
|
}
|
|
1300
1738
|
}
|
|
1301
1739
|
}
|
|
1740
|
+
|
|
1302
1741
|
this.state.top = true;
|
|
1303
1742
|
return tokens;
|
|
1304
1743
|
}
|
|
1744
|
+
|
|
1305
1745
|
inline(src, tokens = []) {
|
|
1306
1746
|
this.inlineQueue.push({ src, tokens });
|
|
1307
1747
|
return tokens;
|
|
1308
1748
|
}
|
|
1749
|
+
|
|
1309
1750
|
/**
|
|
1310
1751
|
* Lexing/Compiling
|
|
1311
1752
|
*/
|
|
1312
1753
|
inlineTokens(src, tokens = []) {
|
|
1313
1754
|
let token, lastToken, cutSrc;
|
|
1755
|
+
|
|
1756
|
+
// String with links masked to avoid interference with em and strong
|
|
1314
1757
|
let maskedSrc = src;
|
|
1315
1758
|
let match;
|
|
1316
1759
|
let keepPrevChar, prevChar;
|
|
1760
|
+
|
|
1761
|
+
// Mask out reflinks
|
|
1317
1762
|
if (this.tokens.links) {
|
|
1318
1763
|
const links = Object.keys(this.tokens.links);
|
|
1319
1764
|
if (links.length > 0) {
|
|
1320
1765
|
while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
|
|
1321
|
-
if (links.includes(match[0].slice(match[0].lastIndexOf(
|
|
1322
|
-
maskedSrc = maskedSrc.slice(0, match.index) +
|
|
1766
|
+
if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
|
|
1767
|
+
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
|
|
1323
1768
|
}
|
|
1324
1769
|
}
|
|
1325
1770
|
}
|
|
1326
1771
|
}
|
|
1772
|
+
// Mask out other blocks
|
|
1327
1773
|
while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
|
|
1328
|
-
maskedSrc = maskedSrc.slice(0, match.index) +
|
|
1774
|
+
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
|
1329
1775
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1776
|
+
|
|
1777
|
+
// Mask out escaped em & strong delimiters
|
|
1778
|
+
while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
|
|
1779
|
+
maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
|
|
1780
|
+
this.tokenizer.rules.inline.escapedEmSt.lastIndex--;
|
|
1332
1781
|
}
|
|
1782
|
+
|
|
1333
1783
|
while (src) {
|
|
1334
1784
|
if (!keepPrevChar) {
|
|
1335
|
-
prevChar =
|
|
1785
|
+
prevChar = '';
|
|
1336
1786
|
}
|
|
1337
1787
|
keepPrevChar = false;
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1788
|
+
|
|
1789
|
+
// extensions
|
|
1790
|
+
if (this.options.extensions
|
|
1791
|
+
&& this.options.extensions.inline
|
|
1792
|
+
&& this.options.extensions.inline.some((extTokenizer) => {
|
|
1793
|
+
if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
|
|
1794
|
+
src = src.substring(token.raw.length);
|
|
1795
|
+
tokens.push(token);
|
|
1796
|
+
return true;
|
|
1797
|
+
}
|
|
1798
|
+
return false;
|
|
1799
|
+
})) {
|
|
1346
1800
|
continue;
|
|
1347
1801
|
}
|
|
1802
|
+
|
|
1803
|
+
// escape
|
|
1348
1804
|
if (token = this.tokenizer.escape(src)) {
|
|
1349
1805
|
src = src.substring(token.raw.length);
|
|
1350
1806
|
tokens.push(token);
|
|
1351
1807
|
continue;
|
|
1352
1808
|
}
|
|
1809
|
+
|
|
1810
|
+
// tag
|
|
1353
1811
|
if (token = this.tokenizer.tag(src)) {
|
|
1354
1812
|
src = src.substring(token.raw.length);
|
|
1355
1813
|
lastToken = tokens[tokens.length - 1];
|
|
1356
|
-
if (lastToken && token.type ===
|
|
1814
|
+
if (lastToken && token.type === 'text' && lastToken.type === 'text') {
|
|
1357
1815
|
lastToken.raw += token.raw;
|
|
1358
1816
|
lastToken.text += token.text;
|
|
1359
1817
|
} else {
|
|
@@ -1361,15 +1819,19 @@ var _Lexer = class {
|
|
|
1361
1819
|
}
|
|
1362
1820
|
continue;
|
|
1363
1821
|
}
|
|
1822
|
+
|
|
1823
|
+
// link
|
|
1364
1824
|
if (token = this.tokenizer.link(src)) {
|
|
1365
1825
|
src = src.substring(token.raw.length);
|
|
1366
1826
|
tokens.push(token);
|
|
1367
1827
|
continue;
|
|
1368
1828
|
}
|
|
1829
|
+
|
|
1830
|
+
// reflink, nolink
|
|
1369
1831
|
if (token = this.tokenizer.reflink(src, this.tokens.links)) {
|
|
1370
1832
|
src = src.substring(token.raw.length);
|
|
1371
1833
|
lastToken = tokens[tokens.length - 1];
|
|
1372
|
-
if (lastToken && token.type ===
|
|
1834
|
+
if (lastToken && token.type === 'text' && lastToken.type === 'text') {
|
|
1373
1835
|
lastToken.raw += token.raw;
|
|
1374
1836
|
lastToken.text += token.text;
|
|
1375
1837
|
} else {
|
|
@@ -1377,46 +1839,59 @@ var _Lexer = class {
|
|
|
1377
1839
|
}
|
|
1378
1840
|
continue;
|
|
1379
1841
|
}
|
|
1842
|
+
|
|
1843
|
+
// em & strong
|
|
1380
1844
|
if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
|
|
1381
1845
|
src = src.substring(token.raw.length);
|
|
1382
1846
|
tokens.push(token);
|
|
1383
1847
|
continue;
|
|
1384
1848
|
}
|
|
1849
|
+
|
|
1850
|
+
// code
|
|
1385
1851
|
if (token = this.tokenizer.codespan(src)) {
|
|
1386
1852
|
src = src.substring(token.raw.length);
|
|
1387
1853
|
tokens.push(token);
|
|
1388
1854
|
continue;
|
|
1389
1855
|
}
|
|
1856
|
+
|
|
1857
|
+
// br
|
|
1390
1858
|
if (token = this.tokenizer.br(src)) {
|
|
1391
1859
|
src = src.substring(token.raw.length);
|
|
1392
1860
|
tokens.push(token);
|
|
1393
1861
|
continue;
|
|
1394
1862
|
}
|
|
1863
|
+
|
|
1864
|
+
// del (gfm)
|
|
1395
1865
|
if (token = this.tokenizer.del(src)) {
|
|
1396
1866
|
src = src.substring(token.raw.length);
|
|
1397
1867
|
tokens.push(token);
|
|
1398
1868
|
continue;
|
|
1399
1869
|
}
|
|
1870
|
+
|
|
1871
|
+
// autolink
|
|
1400
1872
|
if (token = this.tokenizer.autolink(src, mangle)) {
|
|
1401
1873
|
src = src.substring(token.raw.length);
|
|
1402
1874
|
tokens.push(token);
|
|
1403
1875
|
continue;
|
|
1404
1876
|
}
|
|
1877
|
+
|
|
1878
|
+
// url (gfm)
|
|
1405
1879
|
if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
|
|
1406
1880
|
src = src.substring(token.raw.length);
|
|
1407
1881
|
tokens.push(token);
|
|
1408
1882
|
continue;
|
|
1409
1883
|
}
|
|
1884
|
+
|
|
1885
|
+
// text
|
|
1886
|
+
// prevent inlineText consuming extensions by clipping 'src' to extension start
|
|
1410
1887
|
cutSrc = src;
|
|
1411
1888
|
if (this.options.extensions && this.options.extensions.startInline) {
|
|
1412
1889
|
let startIndex = Infinity;
|
|
1413
1890
|
const tempSrc = src.slice(1);
|
|
1414
1891
|
let tempStart;
|
|
1415
|
-
this.options.extensions.startInline.forEach((getStartIndex)
|
|
1892
|
+
this.options.extensions.startInline.forEach(function(getStartIndex) {
|
|
1416
1893
|
tempStart = getStartIndex.call({ lexer: this }, tempSrc);
|
|
1417
|
-
if (typeof tempStart ===
|
|
1418
|
-
startIndex = Math.min(startIndex, tempStart);
|
|
1419
|
-
}
|
|
1894
|
+
if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
|
|
1420
1895
|
});
|
|
1421
1896
|
if (startIndex < Infinity && startIndex >= 0) {
|
|
1422
1897
|
cutSrc = src.substring(0, startIndex + 1);
|
|
@@ -1424,12 +1899,12 @@ var _Lexer = class {
|
|
|
1424
1899
|
}
|
|
1425
1900
|
if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
|
|
1426
1901
|
src = src.substring(token.raw.length);
|
|
1427
|
-
if (token.raw.slice(-1) !==
|
|
1902
|
+
if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
|
|
1428
1903
|
prevChar = token.raw.slice(-1);
|
|
1429
1904
|
}
|
|
1430
1905
|
keepPrevChar = true;
|
|
1431
1906
|
lastToken = tokens[tokens.length - 1];
|
|
1432
|
-
if (lastToken && lastToken.type ===
|
|
1907
|
+
if (lastToken && lastToken.type === 'text') {
|
|
1433
1908
|
lastToken.raw += token.raw;
|
|
1434
1909
|
lastToken.text += token.text;
|
|
1435
1910
|
} else {
|
|
@@ -1437,8 +1912,9 @@ var _Lexer = class {
|
|
|
1437
1912
|
}
|
|
1438
1913
|
continue;
|
|
1439
1914
|
}
|
|
1915
|
+
|
|
1440
1916
|
if (src) {
|
|
1441
|
-
const errMsg =
|
|
1917
|
+
const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
|
|
1442
1918
|
if (this.options.silent) {
|
|
1443
1919
|
console.error(errMsg);
|
|
1444
1920
|
break;
|
|
@@ -1447,17 +1923,21 @@ var _Lexer = class {
|
|
|
1447
1923
|
}
|
|
1448
1924
|
}
|
|
1449
1925
|
}
|
|
1926
|
+
|
|
1450
1927
|
return tokens;
|
|
1451
1928
|
}
|
|
1452
|
-
}
|
|
1929
|
+
}
|
|
1453
1930
|
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1931
|
+
/**
|
|
1932
|
+
* Renderer
|
|
1933
|
+
*/
|
|
1934
|
+
class Renderer {
|
|
1935
|
+
constructor(options) {
|
|
1936
|
+
this.options = options || defaults;
|
|
1458
1937
|
}
|
|
1938
|
+
|
|
1459
1939
|
code(code, infostring, escaped) {
|
|
1460
|
-
const lang = (infostring ||
|
|
1940
|
+
const lang = (infostring || '').match(/\S*/)[0];
|
|
1461
1941
|
if (this.options.highlight) {
|
|
1462
1942
|
const out = this.options.highlight(code, lang);
|
|
1463
1943
|
if (out != null && out !== code) {
|
|
@@ -1465,81 +1945,150 @@ var _Renderer = class {
|
|
|
1465
1945
|
code = out;
|
|
1466
1946
|
}
|
|
1467
1947
|
}
|
|
1468
|
-
|
|
1948
|
+
|
|
1949
|
+
code = code.replace(/\n$/, '') + '\n';
|
|
1950
|
+
|
|
1469
1951
|
if (!lang) {
|
|
1470
|
-
return
|
|
1952
|
+
return '<pre><code>'
|
|
1953
|
+
+ (escaped ? code : escape(code, true))
|
|
1954
|
+
+ '</code></pre>\n';
|
|
1471
1955
|
}
|
|
1472
|
-
|
|
1956
|
+
|
|
1957
|
+
return '<pre><code class="'
|
|
1958
|
+
+ this.options.langPrefix
|
|
1959
|
+
+ escape(lang)
|
|
1960
|
+
+ '">'
|
|
1961
|
+
+ (escaped ? code : escape(code, true))
|
|
1962
|
+
+ '</code></pre>\n';
|
|
1473
1963
|
}
|
|
1964
|
+
|
|
1965
|
+
/**
|
|
1966
|
+
* @param {string} quote
|
|
1967
|
+
*/
|
|
1474
1968
|
blockquote(quote) {
|
|
1475
|
-
return `<blockquote
|
|
1476
|
-
${quote}</blockquote>
|
|
1477
|
-
`;
|
|
1969
|
+
return `<blockquote>\n${quote}</blockquote>\n`;
|
|
1478
1970
|
}
|
|
1479
|
-
|
|
1971
|
+
|
|
1972
|
+
html(html) {
|
|
1480
1973
|
return html;
|
|
1481
1974
|
}
|
|
1975
|
+
|
|
1976
|
+
/**
|
|
1977
|
+
* @param {string} text
|
|
1978
|
+
* @param {string} level
|
|
1979
|
+
* @param {string} raw
|
|
1980
|
+
* @param {any} slugger
|
|
1981
|
+
*/
|
|
1482
1982
|
heading(text, level, raw, slugger) {
|
|
1483
1983
|
if (this.options.headerIds) {
|
|
1484
1984
|
const id = this.options.headerPrefix + slugger.slug(raw);
|
|
1485
|
-
return `<h${level} id="${id}">${text}</h${level}
|
|
1486
|
-
`;
|
|
1985
|
+
return `<h${level} id="${id}">${text}</h${level}>\n`;
|
|
1487
1986
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1987
|
+
|
|
1988
|
+
// ignore IDs
|
|
1989
|
+
return `<h${level}>${text}</h${level}>\n`;
|
|
1490
1990
|
}
|
|
1991
|
+
|
|
1491
1992
|
hr() {
|
|
1492
|
-
return this.options.xhtml ?
|
|
1993
|
+
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
|
1493
1994
|
}
|
|
1995
|
+
|
|
1494
1996
|
list(body, ordered, start) {
|
|
1495
|
-
const type = ordered ?
|
|
1496
|
-
|
|
1997
|
+
const type = ordered ? 'ol' : 'ul',
|
|
1998
|
+
startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
|
|
1999
|
+
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
|
|
1497
2000
|
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
2001
|
+
|
|
2002
|
+
/**
|
|
2003
|
+
* @param {string} text
|
|
2004
|
+
*/
|
|
2005
|
+
listitem(text) {
|
|
2006
|
+
return `<li>${text}</li>\n`;
|
|
1501
2007
|
}
|
|
2008
|
+
|
|
1502
2009
|
checkbox(checked) {
|
|
1503
|
-
return
|
|
2010
|
+
return '<input '
|
|
2011
|
+
+ (checked ? 'checked="" ' : '')
|
|
2012
|
+
+ 'disabled="" type="checkbox"'
|
|
2013
|
+
+ (this.options.xhtml ? ' /' : '')
|
|
2014
|
+
+ '> ';
|
|
1504
2015
|
}
|
|
2016
|
+
|
|
2017
|
+
/**
|
|
2018
|
+
* @param {string} text
|
|
2019
|
+
*/
|
|
1505
2020
|
paragraph(text) {
|
|
1506
|
-
return `<p>${text}</p
|
|
1507
|
-
`;
|
|
2021
|
+
return `<p>${text}</p>\n`;
|
|
1508
2022
|
}
|
|
2023
|
+
|
|
2024
|
+
/**
|
|
2025
|
+
* @param {string} header
|
|
2026
|
+
* @param {string} body
|
|
2027
|
+
*/
|
|
1509
2028
|
table(header, body) {
|
|
1510
|
-
if (body)
|
|
1511
|
-
|
|
1512
|
-
return
|
|
2029
|
+
if (body) body = `<tbody>${body}</tbody>`;
|
|
2030
|
+
|
|
2031
|
+
return '<table>\n'
|
|
2032
|
+
+ '<thead>\n'
|
|
2033
|
+
+ header
|
|
2034
|
+
+ '</thead>\n'
|
|
2035
|
+
+ body
|
|
2036
|
+
+ '</table>\n';
|
|
1513
2037
|
}
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* @param {string} content
|
|
2041
|
+
*/
|
|
1514
2042
|
tablerow(content) {
|
|
1515
|
-
return `<tr
|
|
1516
|
-
${content}</tr>
|
|
1517
|
-
`;
|
|
2043
|
+
return `<tr>\n${content}</tr>\n`;
|
|
1518
2044
|
}
|
|
2045
|
+
|
|
1519
2046
|
tablecell(content, flags) {
|
|
1520
|
-
const type = flags.header ?
|
|
1521
|
-
const tag = flags.align
|
|
1522
|
-
|
|
1523
|
-
|
|
2047
|
+
const type = flags.header ? 'th' : 'td';
|
|
2048
|
+
const tag = flags.align
|
|
2049
|
+
? `<${type} align="${flags.align}">`
|
|
2050
|
+
: `<${type}>`;
|
|
2051
|
+
return tag + content + `</${type}>\n`;
|
|
1524
2052
|
}
|
|
2053
|
+
|
|
1525
2054
|
/**
|
|
1526
2055
|
* span level renderer
|
|
2056
|
+
* @param {string} text
|
|
1527
2057
|
*/
|
|
1528
2058
|
strong(text) {
|
|
1529
2059
|
return `<strong>${text}</strong>`;
|
|
1530
2060
|
}
|
|
2061
|
+
|
|
2062
|
+
/**
|
|
2063
|
+
* @param {string} text
|
|
2064
|
+
*/
|
|
1531
2065
|
em(text) {
|
|
1532
2066
|
return `<em>${text}</em>`;
|
|
1533
2067
|
}
|
|
2068
|
+
|
|
2069
|
+
/**
|
|
2070
|
+
* @param {string} text
|
|
2071
|
+
*/
|
|
1534
2072
|
codespan(text) {
|
|
1535
2073
|
return `<code>${text}</code>`;
|
|
1536
2074
|
}
|
|
2075
|
+
|
|
1537
2076
|
br() {
|
|
1538
|
-
return this.options.xhtml ?
|
|
2077
|
+
return this.options.xhtml ? '<br/>' : '<br>';
|
|
1539
2078
|
}
|
|
2079
|
+
|
|
2080
|
+
/**
|
|
2081
|
+
* @param {string} text
|
|
2082
|
+
*/
|
|
1540
2083
|
del(text) {
|
|
1541
2084
|
return `<del>${text}</del>`;
|
|
1542
2085
|
}
|
|
2086
|
+
|
|
2087
|
+
/**
|
|
2088
|
+
* @param {string} href
|
|
2089
|
+
* @param {string} title
|
|
2090
|
+
* @param {string} text
|
|
2091
|
+
*/
|
|
1543
2092
|
link(href, title, text) {
|
|
1544
2093
|
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
1545
2094
|
if (href === null) {
|
|
@@ -1549,68 +2098,103 @@ ${content}</tr>
|
|
|
1549
2098
|
if (title) {
|
|
1550
2099
|
out += ' title="' + title + '"';
|
|
1551
2100
|
}
|
|
1552
|
-
out +=
|
|
2101
|
+
out += '>' + text + '</a>';
|
|
1553
2102
|
return out;
|
|
1554
2103
|
}
|
|
2104
|
+
|
|
2105
|
+
/**
|
|
2106
|
+
* @param {string} href
|
|
2107
|
+
* @param {string} title
|
|
2108
|
+
* @param {string} text
|
|
2109
|
+
*/
|
|
1555
2110
|
image(href, title, text) {
|
|
1556
2111
|
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
1557
2112
|
if (href === null) {
|
|
1558
2113
|
return text;
|
|
1559
2114
|
}
|
|
2115
|
+
|
|
1560
2116
|
let out = `<img src="${href}" alt="${text}"`;
|
|
1561
2117
|
if (title) {
|
|
1562
2118
|
out += ` title="${title}"`;
|
|
1563
2119
|
}
|
|
1564
|
-
out += this.options.xhtml ?
|
|
2120
|
+
out += this.options.xhtml ? '/>' : '>';
|
|
1565
2121
|
return out;
|
|
1566
2122
|
}
|
|
2123
|
+
|
|
1567
2124
|
text(text) {
|
|
1568
2125
|
return text;
|
|
1569
2126
|
}
|
|
1570
|
-
}
|
|
2127
|
+
}
|
|
1571
2128
|
|
|
1572
|
-
|
|
1573
|
-
|
|
2129
|
+
/**
|
|
2130
|
+
* TextRenderer
|
|
2131
|
+
* returns only the textual part of the token
|
|
2132
|
+
*/
|
|
2133
|
+
class TextRenderer {
|
|
1574
2134
|
// no need for block level renderers
|
|
1575
2135
|
strong(text) {
|
|
1576
2136
|
return text;
|
|
1577
2137
|
}
|
|
2138
|
+
|
|
1578
2139
|
em(text) {
|
|
1579
2140
|
return text;
|
|
1580
2141
|
}
|
|
2142
|
+
|
|
1581
2143
|
codespan(text) {
|
|
1582
2144
|
return text;
|
|
1583
2145
|
}
|
|
2146
|
+
|
|
1584
2147
|
del(text) {
|
|
1585
2148
|
return text;
|
|
1586
2149
|
}
|
|
2150
|
+
|
|
1587
2151
|
html(text) {
|
|
1588
2152
|
return text;
|
|
1589
2153
|
}
|
|
2154
|
+
|
|
1590
2155
|
text(text) {
|
|
1591
2156
|
return text;
|
|
1592
2157
|
}
|
|
2158
|
+
|
|
1593
2159
|
link(href, title, text) {
|
|
1594
|
-
return
|
|
2160
|
+
return '' + text;
|
|
1595
2161
|
}
|
|
2162
|
+
|
|
1596
2163
|
image(href, title, text) {
|
|
1597
|
-
return
|
|
2164
|
+
return '' + text;
|
|
1598
2165
|
}
|
|
2166
|
+
|
|
1599
2167
|
br() {
|
|
1600
|
-
return
|
|
2168
|
+
return '';
|
|
1601
2169
|
}
|
|
1602
|
-
}
|
|
2170
|
+
}
|
|
1603
2171
|
|
|
1604
|
-
|
|
1605
|
-
|
|
2172
|
+
/**
|
|
2173
|
+
* Slugger generates header id
|
|
2174
|
+
*/
|
|
2175
|
+
class Slugger {
|
|
1606
2176
|
constructor() {
|
|
1607
2177
|
this.seen = {};
|
|
1608
2178
|
}
|
|
2179
|
+
|
|
2180
|
+
/**
|
|
2181
|
+
* @param {string} value
|
|
2182
|
+
*/
|
|
1609
2183
|
serialize(value) {
|
|
1610
|
-
return value
|
|
2184
|
+
return value
|
|
2185
|
+
.toLowerCase()
|
|
2186
|
+
.trim()
|
|
2187
|
+
// remove html tags
|
|
2188
|
+
.replace(/<[!\/a-z].*?>/ig, '')
|
|
2189
|
+
// remove unwanted chars
|
|
2190
|
+
.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
|
|
2191
|
+
.replace(/\s/g, '-');
|
|
1611
2192
|
}
|
|
2193
|
+
|
|
1612
2194
|
/**
|
|
1613
2195
|
* Finds the next safe (unique) slug to use
|
|
2196
|
+
* @param {string} originalSlug
|
|
2197
|
+
* @param {boolean} isDryRun
|
|
1614
2198
|
*/
|
|
1615
2199
|
getNextSafeSlug(originalSlug, isDryRun) {
|
|
1616
2200
|
let slug = originalSlug;
|
|
@@ -1619,7 +2203,7 @@ var _Slugger = class {
|
|
|
1619
2203
|
occurenceAccumulator = this.seen[originalSlug];
|
|
1620
2204
|
do {
|
|
1621
2205
|
occurenceAccumulator++;
|
|
1622
|
-
slug = originalSlug +
|
|
2206
|
+
slug = originalSlug + '-' + occurenceAccumulator;
|
|
1623
2207
|
} while (this.seen.hasOwnProperty(slug));
|
|
1624
2208
|
}
|
|
1625
2209
|
if (!isDryRun) {
|
|
@@ -1628,82 +2212,113 @@ var _Slugger = class {
|
|
|
1628
2212
|
}
|
|
1629
2213
|
return slug;
|
|
1630
2214
|
}
|
|
2215
|
+
|
|
1631
2216
|
/**
|
|
1632
2217
|
* Convert string to unique id
|
|
2218
|
+
* @param {object} [options]
|
|
2219
|
+
* @param {boolean} [options.dryrun] Generates the next unique slug without
|
|
2220
|
+
* updating the internal accumulator.
|
|
1633
2221
|
*/
|
|
1634
|
-
slug(value,
|
|
2222
|
+
slug(value, options = {}) {
|
|
1635
2223
|
const slug = this.serialize(value);
|
|
1636
|
-
return this.getNextSafeSlug(slug,
|
|
2224
|
+
return this.getNextSafeSlug(slug, options.dryrun);
|
|
1637
2225
|
}
|
|
1638
|
-
}
|
|
2226
|
+
}
|
|
1639
2227
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
2228
|
+
/**
|
|
2229
|
+
* Parsing & Compiling
|
|
2230
|
+
*/
|
|
2231
|
+
class Parser {
|
|
2232
|
+
constructor(options) {
|
|
2233
|
+
this.options = options || defaults;
|
|
2234
|
+
this.options.renderer = this.options.renderer || new Renderer();
|
|
1645
2235
|
this.renderer = this.options.renderer;
|
|
1646
2236
|
this.renderer.options = this.options;
|
|
1647
|
-
this.textRenderer = new
|
|
1648
|
-
this.slugger = new
|
|
2237
|
+
this.textRenderer = new TextRenderer();
|
|
2238
|
+
this.slugger = new Slugger();
|
|
1649
2239
|
}
|
|
2240
|
+
|
|
1650
2241
|
/**
|
|
1651
2242
|
* Static Parse Method
|
|
1652
2243
|
*/
|
|
1653
|
-
static parse(tokens,
|
|
1654
|
-
const
|
|
1655
|
-
return
|
|
2244
|
+
static parse(tokens, options) {
|
|
2245
|
+
const parser = new Parser(options);
|
|
2246
|
+
return parser.parse(tokens);
|
|
1656
2247
|
}
|
|
2248
|
+
|
|
1657
2249
|
/**
|
|
1658
2250
|
* Static Parse Inline Method
|
|
1659
2251
|
*/
|
|
1660
|
-
static parseInline(tokens,
|
|
1661
|
-
const
|
|
1662
|
-
return
|
|
2252
|
+
static parseInline(tokens, options) {
|
|
2253
|
+
const parser = new Parser(options);
|
|
2254
|
+
return parser.parseInline(tokens);
|
|
1663
2255
|
}
|
|
2256
|
+
|
|
1664
2257
|
/**
|
|
1665
2258
|
* Parse Loop
|
|
1666
2259
|
*/
|
|
1667
2260
|
parse(tokens, top = true) {
|
|
1668
|
-
let out =
|
|
2261
|
+
let out = '',
|
|
2262
|
+
i,
|
|
2263
|
+
j,
|
|
2264
|
+
k,
|
|
2265
|
+
l2,
|
|
2266
|
+
l3,
|
|
2267
|
+
row,
|
|
2268
|
+
cell,
|
|
2269
|
+
header,
|
|
2270
|
+
body,
|
|
2271
|
+
token,
|
|
2272
|
+
ordered,
|
|
2273
|
+
start,
|
|
2274
|
+
loose,
|
|
2275
|
+
itemBody,
|
|
2276
|
+
item,
|
|
2277
|
+
checked,
|
|
2278
|
+
task,
|
|
2279
|
+
checkbox,
|
|
2280
|
+
ret;
|
|
2281
|
+
|
|
1669
2282
|
const l = tokens.length;
|
|
1670
2283
|
for (i = 0; i < l; i++) {
|
|
1671
2284
|
token = tokens[i];
|
|
2285
|
+
|
|
2286
|
+
// Run any renderer extensions
|
|
1672
2287
|
if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
|
|
1673
2288
|
ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
|
|
1674
|
-
if (ret !== false || ![
|
|
1675
|
-
out += ret ||
|
|
2289
|
+
if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
|
|
2290
|
+
out += ret || '';
|
|
1676
2291
|
continue;
|
|
1677
2292
|
}
|
|
1678
2293
|
}
|
|
2294
|
+
|
|
1679
2295
|
switch (token.type) {
|
|
1680
|
-
case
|
|
2296
|
+
case 'space': {
|
|
1681
2297
|
continue;
|
|
1682
2298
|
}
|
|
1683
|
-
case
|
|
2299
|
+
case 'hr': {
|
|
1684
2300
|
out += this.renderer.hr();
|
|
1685
2301
|
continue;
|
|
1686
2302
|
}
|
|
1687
|
-
case
|
|
2303
|
+
case 'heading': {
|
|
1688
2304
|
out += this.renderer.heading(
|
|
1689
2305
|
this.parseInline(token.tokens),
|
|
1690
2306
|
token.depth,
|
|
1691
2307
|
unescape(this.parseInline(token.tokens, this.textRenderer)),
|
|
1692
|
-
this.slugger
|
|
1693
|
-
);
|
|
2308
|
+
this.slugger);
|
|
1694
2309
|
continue;
|
|
1695
2310
|
}
|
|
1696
|
-
case
|
|
1697
|
-
out += this.renderer.code(
|
|
1698
|
-
token.text,
|
|
2311
|
+
case 'code': {
|
|
2312
|
+
out += this.renderer.code(token.text,
|
|
1699
2313
|
token.lang,
|
|
1700
|
-
|
|
1701
|
-
);
|
|
2314
|
+
token.escaped);
|
|
1702
2315
|
continue;
|
|
1703
2316
|
}
|
|
1704
|
-
case
|
|
1705
|
-
header =
|
|
1706
|
-
|
|
2317
|
+
case 'table': {
|
|
2318
|
+
header = '';
|
|
2319
|
+
|
|
2320
|
+
// header
|
|
2321
|
+
cell = '';
|
|
1707
2322
|
l2 = token.header.length;
|
|
1708
2323
|
for (j = 0; j < l2; j++) {
|
|
1709
2324
|
cell += this.renderer.tablecell(
|
|
@@ -1712,11 +2327,13 @@ var _Parser = class {
|
|
|
1712
2327
|
);
|
|
1713
2328
|
}
|
|
1714
2329
|
header += this.renderer.tablerow(cell);
|
|
1715
|
-
|
|
2330
|
+
|
|
2331
|
+
body = '';
|
|
1716
2332
|
l2 = token.rows.length;
|
|
1717
2333
|
for (j = 0; j < l2; j++) {
|
|
1718
2334
|
row = token.rows[j];
|
|
1719
|
-
|
|
2335
|
+
|
|
2336
|
+
cell = '';
|
|
1720
2337
|
l3 = row.length;
|
|
1721
2338
|
for (k = 0; k < l3; k++) {
|
|
1722
2339
|
cell += this.renderer.tablecell(
|
|
@@ -1724,38 +2341,41 @@ var _Parser = class {
|
|
|
1724
2341
|
{ header: false, align: token.align[k] }
|
|
1725
2342
|
);
|
|
1726
2343
|
}
|
|
2344
|
+
|
|
1727
2345
|
body += this.renderer.tablerow(cell);
|
|
1728
2346
|
}
|
|
1729
2347
|
out += this.renderer.table(header, body);
|
|
1730
2348
|
continue;
|
|
1731
2349
|
}
|
|
1732
|
-
case
|
|
2350
|
+
case 'blockquote': {
|
|
1733
2351
|
body = this.parse(token.tokens);
|
|
1734
2352
|
out += this.renderer.blockquote(body);
|
|
1735
2353
|
continue;
|
|
1736
2354
|
}
|
|
1737
|
-
case
|
|
2355
|
+
case 'list': {
|
|
1738
2356
|
ordered = token.ordered;
|
|
1739
2357
|
start = token.start;
|
|
1740
2358
|
loose = token.loose;
|
|
1741
2359
|
l2 = token.items.length;
|
|
1742
|
-
|
|
2360
|
+
|
|
2361
|
+
body = '';
|
|
1743
2362
|
for (j = 0; j < l2; j++) {
|
|
1744
2363
|
item = token.items[j];
|
|
1745
2364
|
checked = item.checked;
|
|
1746
2365
|
task = item.task;
|
|
1747
|
-
|
|
2366
|
+
|
|
2367
|
+
itemBody = '';
|
|
1748
2368
|
if (item.task) {
|
|
1749
|
-
checkbox = this.renderer.checkbox(
|
|
2369
|
+
checkbox = this.renderer.checkbox(checked);
|
|
1750
2370
|
if (loose) {
|
|
1751
|
-
if (item.tokens.length > 0 && item.tokens[0].type ===
|
|
1752
|
-
item.tokens[0].text = checkbox +
|
|
1753
|
-
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type ===
|
|
1754
|
-
item.tokens[0].tokens[0].text = checkbox +
|
|
2371
|
+
if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
|
|
2372
|
+
item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
|
|
2373
|
+
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
|
|
2374
|
+
item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
|
|
1755
2375
|
}
|
|
1756
2376
|
} else {
|
|
1757
2377
|
item.tokens.unshift({
|
|
1758
|
-
type:
|
|
2378
|
+
type: 'text',
|
|
1759
2379
|
text: checkbox
|
|
1760
2380
|
});
|
|
1761
2381
|
}
|
|
@@ -1763,96 +2383,109 @@ var _Parser = class {
|
|
|
1763
2383
|
itemBody += checkbox;
|
|
1764
2384
|
}
|
|
1765
2385
|
}
|
|
2386
|
+
|
|
1766
2387
|
itemBody += this.parse(item.tokens, loose);
|
|
1767
|
-
body += this.renderer.listitem(itemBody, task,
|
|
2388
|
+
body += this.renderer.listitem(itemBody, task, checked);
|
|
1768
2389
|
}
|
|
2390
|
+
|
|
1769
2391
|
out += this.renderer.list(body, ordered, start);
|
|
1770
2392
|
continue;
|
|
1771
2393
|
}
|
|
1772
|
-
case
|
|
1773
|
-
|
|
2394
|
+
case 'html': {
|
|
2395
|
+
// TODO parse inline content if parameter markdown=1
|
|
2396
|
+
out += this.renderer.html(token.text);
|
|
1774
2397
|
continue;
|
|
1775
2398
|
}
|
|
1776
|
-
case
|
|
2399
|
+
case 'paragraph': {
|
|
1777
2400
|
out += this.renderer.paragraph(this.parseInline(token.tokens));
|
|
1778
2401
|
continue;
|
|
1779
2402
|
}
|
|
1780
|
-
case
|
|
2403
|
+
case 'text': {
|
|
1781
2404
|
body = token.tokens ? this.parseInline(token.tokens) : token.text;
|
|
1782
|
-
while (i + 1 < l && tokens[i + 1].type ===
|
|
2405
|
+
while (i + 1 < l && tokens[i + 1].type === 'text') {
|
|
1783
2406
|
token = tokens[++i];
|
|
1784
|
-
body +=
|
|
2407
|
+
body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
|
|
1785
2408
|
}
|
|
1786
2409
|
out += top ? this.renderer.paragraph(body) : body;
|
|
1787
2410
|
continue;
|
|
1788
2411
|
}
|
|
2412
|
+
|
|
1789
2413
|
default: {
|
|
1790
2414
|
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
1791
2415
|
if (this.options.silent) {
|
|
1792
2416
|
console.error(errMsg);
|
|
1793
|
-
return
|
|
2417
|
+
return;
|
|
1794
2418
|
} else {
|
|
1795
2419
|
throw new Error(errMsg);
|
|
1796
2420
|
}
|
|
1797
2421
|
}
|
|
1798
2422
|
}
|
|
1799
2423
|
}
|
|
2424
|
+
|
|
1800
2425
|
return out;
|
|
1801
2426
|
}
|
|
2427
|
+
|
|
1802
2428
|
/**
|
|
1803
2429
|
* Parse Inline Tokens
|
|
1804
2430
|
*/
|
|
1805
2431
|
parseInline(tokens, renderer) {
|
|
1806
2432
|
renderer = renderer || this.renderer;
|
|
1807
|
-
let out =
|
|
2433
|
+
let out = '',
|
|
2434
|
+
i,
|
|
2435
|
+
token,
|
|
2436
|
+
ret;
|
|
2437
|
+
|
|
1808
2438
|
const l = tokens.length;
|
|
1809
2439
|
for (i = 0; i < l; i++) {
|
|
1810
2440
|
token = tokens[i];
|
|
2441
|
+
|
|
2442
|
+
// Run any renderer extensions
|
|
1811
2443
|
if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
|
|
1812
2444
|
ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
|
|
1813
|
-
if (ret !== false || ![
|
|
1814
|
-
out += ret ||
|
|
2445
|
+
if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
|
|
2446
|
+
out += ret || '';
|
|
1815
2447
|
continue;
|
|
1816
2448
|
}
|
|
1817
2449
|
}
|
|
2450
|
+
|
|
1818
2451
|
switch (token.type) {
|
|
1819
|
-
case
|
|
2452
|
+
case 'escape': {
|
|
1820
2453
|
out += renderer.text(token.text);
|
|
1821
2454
|
break;
|
|
1822
2455
|
}
|
|
1823
|
-
case
|
|
2456
|
+
case 'html': {
|
|
1824
2457
|
out += renderer.html(token.text);
|
|
1825
2458
|
break;
|
|
1826
2459
|
}
|
|
1827
|
-
case
|
|
2460
|
+
case 'link': {
|
|
1828
2461
|
out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
|
|
1829
2462
|
break;
|
|
1830
2463
|
}
|
|
1831
|
-
case
|
|
2464
|
+
case 'image': {
|
|
1832
2465
|
out += renderer.image(token.href, token.title, token.text);
|
|
1833
2466
|
break;
|
|
1834
2467
|
}
|
|
1835
|
-
case
|
|
2468
|
+
case 'strong': {
|
|
1836
2469
|
out += renderer.strong(this.parseInline(token.tokens, renderer));
|
|
1837
2470
|
break;
|
|
1838
2471
|
}
|
|
1839
|
-
case
|
|
2472
|
+
case 'em': {
|
|
1840
2473
|
out += renderer.em(this.parseInline(token.tokens, renderer));
|
|
1841
2474
|
break;
|
|
1842
2475
|
}
|
|
1843
|
-
case
|
|
2476
|
+
case 'codespan': {
|
|
1844
2477
|
out += renderer.codespan(token.text);
|
|
1845
2478
|
break;
|
|
1846
2479
|
}
|
|
1847
|
-
case
|
|
2480
|
+
case 'br': {
|
|
1848
2481
|
out += renderer.br();
|
|
1849
2482
|
break;
|
|
1850
2483
|
}
|
|
1851
|
-
case
|
|
2484
|
+
case 'del': {
|
|
1852
2485
|
out += renderer.del(this.parseInline(token.tokens, renderer));
|
|
1853
2486
|
break;
|
|
1854
2487
|
}
|
|
1855
|
-
case
|
|
2488
|
+
case 'text': {
|
|
1856
2489
|
out += renderer.text(token.text);
|
|
1857
2490
|
break;
|
|
1858
2491
|
}
|
|
@@ -1860,7 +2493,7 @@ var _Parser = class {
|
|
|
1860
2493
|
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
1861
2494
|
if (this.options.silent) {
|
|
1862
2495
|
console.error(errMsg);
|
|
1863
|
-
return
|
|
2496
|
+
return;
|
|
1864
2497
|
} else {
|
|
1865
2498
|
throw new Error(errMsg);
|
|
1866
2499
|
}
|
|
@@ -1869,388 +2502,353 @@ var _Parser = class {
|
|
|
1869
2502
|
}
|
|
1870
2503
|
return out;
|
|
1871
2504
|
}
|
|
1872
|
-
}
|
|
2505
|
+
}
|
|
1873
2506
|
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
*/
|
|
1882
|
-
preprocess(markdown) {
|
|
1883
|
-
return markdown;
|
|
2507
|
+
/**
|
|
2508
|
+
* Marked
|
|
2509
|
+
*/
|
|
2510
|
+
function marked(src, opt, callback) {
|
|
2511
|
+
// throw error in case of non string input
|
|
2512
|
+
if (typeof src === 'undefined' || src === null) {
|
|
2513
|
+
throw new Error('marked(): input parameter is undefined or null');
|
|
1884
2514
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
postprocess(html) {
|
|
1889
|
-
return html;
|
|
2515
|
+
if (typeof src !== 'string') {
|
|
2516
|
+
throw new Error('marked(): input parameter is of type '
|
|
2517
|
+
+ Object.prototype.toString.call(src) + ', string expected');
|
|
1890
2518
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
]);
|
|
1896
|
-
|
|
1897
|
-
// src/Instance.ts
|
|
1898
|
-
var _parseMarkdown, parseMarkdown_fn, _onError, onError_fn;
|
|
1899
|
-
var Marked = class {
|
|
1900
|
-
constructor(...args) {
|
|
1901
|
-
__privateAdd(this, _parseMarkdown);
|
|
1902
|
-
__privateAdd(this, _onError);
|
|
1903
|
-
this.defaults = _getDefaults();
|
|
1904
|
-
this.options = this.setOptions;
|
|
1905
|
-
this.parse = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer.lex, _Parser.parse);
|
|
1906
|
-
this.parseInline = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer.lexInline, _Parser.parseInline);
|
|
1907
|
-
this.Parser = _Parser;
|
|
1908
|
-
this.parser = _Parser.parse;
|
|
1909
|
-
this.Renderer = _Renderer;
|
|
1910
|
-
this.TextRenderer = _TextRenderer;
|
|
1911
|
-
this.Lexer = _Lexer;
|
|
1912
|
-
this.lexer = _Lexer.lex;
|
|
1913
|
-
this.Tokenizer = _Tokenizer;
|
|
1914
|
-
this.Slugger = _Slugger;
|
|
1915
|
-
this.Hooks = _Hooks;
|
|
1916
|
-
this.use(...args);
|
|
2519
|
+
|
|
2520
|
+
if (typeof opt === 'function') {
|
|
2521
|
+
callback = opt;
|
|
2522
|
+
opt = null;
|
|
1917
2523
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
break;
|
|
1940
|
-
}
|
|
1941
|
-
default: {
|
|
1942
|
-
if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) {
|
|
1943
|
-
this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
|
|
1944
|
-
values = values.concat(this.walkTokens(token[childTokens], callback));
|
|
1945
|
-
});
|
|
1946
|
-
} else if (token.tokens) {
|
|
1947
|
-
values = values.concat(this.walkTokens(token.tokens, callback));
|
|
2524
|
+
|
|
2525
|
+
opt = merge({}, marked.defaults, opt || {});
|
|
2526
|
+
checkSanitizeDeprecation(opt);
|
|
2527
|
+
|
|
2528
|
+
if (callback) {
|
|
2529
|
+
const highlight = opt.highlight;
|
|
2530
|
+
let tokens;
|
|
2531
|
+
|
|
2532
|
+
try {
|
|
2533
|
+
tokens = Lexer.lex(src, opt);
|
|
2534
|
+
} catch (e) {
|
|
2535
|
+
return callback(e);
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2538
|
+
const done = function(err) {
|
|
2539
|
+
let out;
|
|
2540
|
+
|
|
2541
|
+
if (!err) {
|
|
2542
|
+
try {
|
|
2543
|
+
if (opt.walkTokens) {
|
|
2544
|
+
marked.walkTokens(tokens, opt.walkTokens);
|
|
1948
2545
|
}
|
|
2546
|
+
out = Parser.parse(tokens, opt);
|
|
2547
|
+
} catch (e) {
|
|
2548
|
+
err = e;
|
|
1949
2549
|
}
|
|
1950
2550
|
}
|
|
2551
|
+
|
|
2552
|
+
opt.highlight = highlight;
|
|
2553
|
+
|
|
2554
|
+
return err
|
|
2555
|
+
? callback(err)
|
|
2556
|
+
: callback(null, out);
|
|
2557
|
+
};
|
|
2558
|
+
|
|
2559
|
+
if (!highlight || highlight.length < 3) {
|
|
2560
|
+
return done();
|
|
1951
2561
|
}
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
if (
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
const prevRenderer = extensions.renderers[ext.name];
|
|
1966
|
-
if (prevRenderer) {
|
|
1967
|
-
extensions.renderers[ext.name] = function(...args2) {
|
|
1968
|
-
let ret = ext.renderer.apply(this, args2);
|
|
1969
|
-
if (ret === false) {
|
|
1970
|
-
ret = prevRenderer.apply(this, args2);
|
|
1971
|
-
}
|
|
1972
|
-
return ret;
|
|
1973
|
-
};
|
|
1974
|
-
} else {
|
|
1975
|
-
extensions.renderers[ext.name] = ext.renderer;
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
if ("tokenizer" in ext) {
|
|
1979
|
-
if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
|
|
1980
|
-
throw new Error("extension level must be 'block' or 'inline'");
|
|
1981
|
-
}
|
|
1982
|
-
if (extensions[ext.level]) {
|
|
1983
|
-
extensions[ext.level].unshift(ext.tokenizer);
|
|
1984
|
-
} else {
|
|
1985
|
-
extensions[ext.level] = [ext.tokenizer];
|
|
2562
|
+
|
|
2563
|
+
delete opt.highlight;
|
|
2564
|
+
|
|
2565
|
+
if (!tokens.length) return done();
|
|
2566
|
+
|
|
2567
|
+
let pending = 0;
|
|
2568
|
+
marked.walkTokens(tokens, function(token) {
|
|
2569
|
+
if (token.type === 'code') {
|
|
2570
|
+
pending++;
|
|
2571
|
+
setTimeout(() => {
|
|
2572
|
+
highlight(token.text, token.lang, function(err, code) {
|
|
2573
|
+
if (err) {
|
|
2574
|
+
return done(err);
|
|
1986
2575
|
}
|
|
1987
|
-
if (
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
extensions.startBlock.push(ext.start);
|
|
1991
|
-
} else {
|
|
1992
|
-
extensions.startBlock = [ext.start];
|
|
1993
|
-
}
|
|
1994
|
-
} else if (ext.level === "inline") {
|
|
1995
|
-
if (extensions.startInline) {
|
|
1996
|
-
extensions.startInline.push(ext.start);
|
|
1997
|
-
} else {
|
|
1998
|
-
extensions.startInline = [ext.start];
|
|
1999
|
-
}
|
|
2000
|
-
}
|
|
2576
|
+
if (code != null && code !== token.text) {
|
|
2577
|
+
token.text = code;
|
|
2578
|
+
token.escaped = true;
|
|
2001
2579
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
});
|
|
2007
|
-
opts.extensions = extensions;
|
|
2008
|
-
}
|
|
2009
|
-
if (pack.renderer) {
|
|
2010
|
-
const renderer = this.defaults.renderer || new _Renderer(this.defaults);
|
|
2011
|
-
for (const prop in pack.renderer) {
|
|
2012
|
-
const prevRenderer = renderer[prop];
|
|
2013
|
-
renderer[prop] = (...args2) => {
|
|
2014
|
-
let ret = pack.renderer[prop].apply(renderer, args2);
|
|
2015
|
-
if (ret === false) {
|
|
2016
|
-
ret = prevRenderer.apply(renderer, args2);
|
|
2580
|
+
|
|
2581
|
+
pending--;
|
|
2582
|
+
if (pending === 0) {
|
|
2583
|
+
done();
|
|
2017
2584
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
}
|
|
2021
|
-
opts.renderer = renderer;
|
|
2585
|
+
});
|
|
2586
|
+
}, 0);
|
|
2022
2587
|
}
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2588
|
+
});
|
|
2589
|
+
|
|
2590
|
+
if (pending === 0) {
|
|
2591
|
+
done();
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
return;
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
function onError(e) {
|
|
2598
|
+
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
2599
|
+
if (opt.silent) {
|
|
2600
|
+
return '<p>An error occurred:</p><pre>'
|
|
2601
|
+
+ escape(e.message + '', true)
|
|
2602
|
+
+ '</pre>';
|
|
2603
|
+
}
|
|
2604
|
+
throw e;
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
try {
|
|
2608
|
+
const tokens = Lexer.lex(src, opt);
|
|
2609
|
+
if (opt.walkTokens) {
|
|
2610
|
+
if (opt.async) {
|
|
2611
|
+
return Promise.all(marked.walkTokens(tokens, opt.walkTokens))
|
|
2612
|
+
.then(() => {
|
|
2613
|
+
return Parser.parse(tokens, opt);
|
|
2614
|
+
})
|
|
2615
|
+
.catch(onError);
|
|
2616
|
+
}
|
|
2617
|
+
marked.walkTokens(tokens, opt.walkTokens);
|
|
2618
|
+
}
|
|
2619
|
+
return Parser.parse(tokens, opt);
|
|
2620
|
+
} catch (e) {
|
|
2621
|
+
onError(e);
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
/**
|
|
2626
|
+
* Options
|
|
2627
|
+
*/
|
|
2628
|
+
|
|
2629
|
+
marked.options =
|
|
2630
|
+
marked.setOptions = function(opt) {
|
|
2631
|
+
merge(marked.defaults, opt);
|
|
2632
|
+
changeDefaults(marked.defaults);
|
|
2633
|
+
return marked;
|
|
2634
|
+
};
|
|
2635
|
+
|
|
2636
|
+
marked.getDefaults = getDefaults;
|
|
2637
|
+
|
|
2638
|
+
marked.defaults = defaults;
|
|
2639
|
+
|
|
2640
|
+
/**
|
|
2641
|
+
* Use Extension
|
|
2642
|
+
*/
|
|
2643
|
+
|
|
2644
|
+
marked.use = function(...args) {
|
|
2645
|
+
const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };
|
|
2646
|
+
|
|
2647
|
+
args.forEach((pack) => {
|
|
2648
|
+
// copy options to new object
|
|
2649
|
+
const opts = merge({}, pack);
|
|
2650
|
+
|
|
2651
|
+
// set async to true if it was set to true before
|
|
2652
|
+
opts.async = marked.defaults.async || opts.async;
|
|
2653
|
+
|
|
2654
|
+
// ==-- Parse "addon" extensions --== //
|
|
2655
|
+
if (pack.extensions) {
|
|
2656
|
+
pack.extensions.forEach((ext) => {
|
|
2657
|
+
if (!ext.name) {
|
|
2658
|
+
throw new Error('extension name required');
|
|
2659
|
+
}
|
|
2660
|
+
if (ext.renderer) { // Renderer extensions
|
|
2661
|
+
const prevRenderer = extensions.renderers[ext.name];
|
|
2662
|
+
if (prevRenderer) {
|
|
2663
|
+
// Replace extension with func to run new extension but fall back if false
|
|
2664
|
+
extensions.renderers[ext.name] = function(...args) {
|
|
2665
|
+
let ret = ext.renderer.apply(this, args);
|
|
2054
2666
|
if (ret === false) {
|
|
2055
|
-
ret =
|
|
2667
|
+
ret = prevRenderer.apply(this, args);
|
|
2056
2668
|
}
|
|
2057
2669
|
return ret;
|
|
2058
2670
|
};
|
|
2671
|
+
} else {
|
|
2672
|
+
extensions.renderers[ext.name] = ext.renderer;
|
|
2059
2673
|
}
|
|
2060
2674
|
}
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
const walkTokens2 = this.defaults.walkTokens;
|
|
2065
|
-
opts.walkTokens = function(token) {
|
|
2066
|
-
let values = [];
|
|
2067
|
-
values.push(pack.walkTokens.call(this, token));
|
|
2068
|
-
if (walkTokens2) {
|
|
2069
|
-
values = values.concat(walkTokens2.call(this, token));
|
|
2675
|
+
if (ext.tokenizer) { // Tokenizer Extensions
|
|
2676
|
+
if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
|
|
2677
|
+
throw new Error("extension level must be 'block' or 'inline'");
|
|
2070
2678
|
}
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
});
|
|
2076
|
-
return this;
|
|
2077
|
-
}
|
|
2078
|
-
setOptions(opt) {
|
|
2079
|
-
this.defaults = { ...this.defaults, ...opt };
|
|
2080
|
-
return this;
|
|
2081
|
-
}
|
|
2082
|
-
};
|
|
2083
|
-
_parseMarkdown = new WeakSet();
|
|
2084
|
-
parseMarkdown_fn = function(lexer2, parser2) {
|
|
2085
|
-
return (src, optOrCallback, callback) => {
|
|
2086
|
-
if (typeof optOrCallback === "function") {
|
|
2087
|
-
callback = optOrCallback;
|
|
2088
|
-
optOrCallback = null;
|
|
2089
|
-
}
|
|
2090
|
-
const origOpt = { ...optOrCallback };
|
|
2091
|
-
const opt = { ...this.defaults, ...origOpt };
|
|
2092
|
-
const throwError = __privateMethod(this, _onError, onError_fn).call(this, !!opt.silent, !!opt.async, callback);
|
|
2093
|
-
if (typeof src === "undefined" || src === null) {
|
|
2094
|
-
return throwError(new Error("marked(): input parameter is undefined or null"));
|
|
2095
|
-
}
|
|
2096
|
-
if (typeof src !== "string") {
|
|
2097
|
-
return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"));
|
|
2098
|
-
}
|
|
2099
|
-
checkDeprecations(opt, callback);
|
|
2100
|
-
if (opt.hooks) {
|
|
2101
|
-
opt.hooks.options = opt;
|
|
2102
|
-
}
|
|
2103
|
-
if (callback) {
|
|
2104
|
-
const highlight = opt.highlight;
|
|
2105
|
-
let tokens;
|
|
2106
|
-
try {
|
|
2107
|
-
if (opt.hooks) {
|
|
2108
|
-
src = opt.hooks.preprocess(src);
|
|
2109
|
-
}
|
|
2110
|
-
tokens = lexer2(src, opt);
|
|
2111
|
-
} catch (e) {
|
|
2112
|
-
return throwError(e);
|
|
2113
|
-
}
|
|
2114
|
-
const done = (err) => {
|
|
2115
|
-
let out;
|
|
2116
|
-
if (!err) {
|
|
2117
|
-
try {
|
|
2118
|
-
if (opt.walkTokens) {
|
|
2119
|
-
this.walkTokens(tokens, opt.walkTokens);
|
|
2120
|
-
}
|
|
2121
|
-
out = parser2(tokens, opt);
|
|
2122
|
-
if (opt.hooks) {
|
|
2123
|
-
out = opt.hooks.postprocess(out);
|
|
2124
|
-
}
|
|
2125
|
-
} catch (e) {
|
|
2126
|
-
err = e;
|
|
2679
|
+
if (extensions[ext.level]) {
|
|
2680
|
+
extensions[ext.level].unshift(ext.tokenizer);
|
|
2681
|
+
} else {
|
|
2682
|
+
extensions[ext.level] = [ext.tokenizer];
|
|
2127
2683
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
}
|
|
2135
|
-
delete opt.highlight;
|
|
2136
|
-
if (!tokens.length)
|
|
2137
|
-
return done();
|
|
2138
|
-
let pending = 0;
|
|
2139
|
-
this.walkTokens(tokens, (token) => {
|
|
2140
|
-
if (token.type === "code") {
|
|
2141
|
-
pending++;
|
|
2142
|
-
setTimeout(() => {
|
|
2143
|
-
highlight(token.text, token.lang, (err, code) => {
|
|
2144
|
-
if (err) {
|
|
2145
|
-
return done(err);
|
|
2146
|
-
}
|
|
2147
|
-
if (code != null && code !== token.text) {
|
|
2148
|
-
token.text = code;
|
|
2149
|
-
token.escaped = true;
|
|
2684
|
+
if (ext.start) { // Function to check for start of token
|
|
2685
|
+
if (ext.level === 'block') {
|
|
2686
|
+
if (extensions.startBlock) {
|
|
2687
|
+
extensions.startBlock.push(ext.start);
|
|
2688
|
+
} else {
|
|
2689
|
+
extensions.startBlock = [ext.start];
|
|
2150
2690
|
}
|
|
2151
|
-
|
|
2152
|
-
if (
|
|
2153
|
-
|
|
2691
|
+
} else if (ext.level === 'inline') {
|
|
2692
|
+
if (extensions.startInline) {
|
|
2693
|
+
extensions.startInline.push(ext.start);
|
|
2694
|
+
} else {
|
|
2695
|
+
extensions.startInline = [ext.start];
|
|
2154
2696
|
}
|
|
2155
|
-
}
|
|
2156
|
-
}
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
if (ext.childTokens) { // Child tokens to be visited by walkTokens
|
|
2701
|
+
extensions.childTokens[ext.name] = ext.childTokens;
|
|
2157
2702
|
}
|
|
2158
2703
|
});
|
|
2159
|
-
|
|
2160
|
-
done();
|
|
2161
|
-
}
|
|
2162
|
-
return;
|
|
2704
|
+
opts.extensions = extensions;
|
|
2163
2705
|
}
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2706
|
+
|
|
2707
|
+
// ==-- Parse "overwrite" extensions --== //
|
|
2708
|
+
if (pack.renderer) {
|
|
2709
|
+
const renderer = marked.defaults.renderer || new Renderer();
|
|
2710
|
+
for (const prop in pack.renderer) {
|
|
2711
|
+
const prevRenderer = renderer[prop];
|
|
2712
|
+
// Replace renderer with func to run extension, but fall back if false
|
|
2713
|
+
renderer[prop] = (...args) => {
|
|
2714
|
+
let ret = pack.renderer[prop].apply(renderer, args);
|
|
2715
|
+
if (ret === false) {
|
|
2716
|
+
ret = prevRenderer.apply(renderer, args);
|
|
2717
|
+
}
|
|
2718
|
+
return ret;
|
|
2719
|
+
};
|
|
2174
2720
|
}
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2721
|
+
opts.renderer = renderer;
|
|
2722
|
+
}
|
|
2723
|
+
if (pack.tokenizer) {
|
|
2724
|
+
const tokenizer = marked.defaults.tokenizer || new Tokenizer();
|
|
2725
|
+
for (const prop in pack.tokenizer) {
|
|
2726
|
+
const prevTokenizer = tokenizer[prop];
|
|
2727
|
+
// Replace tokenizer with func to run extension, but fall back if false
|
|
2728
|
+
tokenizer[prop] = (...args) => {
|
|
2729
|
+
let ret = pack.tokenizer[prop].apply(tokenizer, args);
|
|
2730
|
+
if (ret === false) {
|
|
2731
|
+
ret = prevTokenizer.apply(tokenizer, args);
|
|
2732
|
+
}
|
|
2733
|
+
return ret;
|
|
2734
|
+
};
|
|
2178
2735
|
}
|
|
2179
|
-
|
|
2180
|
-
} catch (e) {
|
|
2181
|
-
return throwError(e);
|
|
2736
|
+
opts.tokenizer = tokenizer;
|
|
2182
2737
|
}
|
|
2183
|
-
|
|
2738
|
+
|
|
2739
|
+
// ==-- Parse WalkTokens extensions --== //
|
|
2740
|
+
if (pack.walkTokens) {
|
|
2741
|
+
const walkTokens = marked.defaults.walkTokens;
|
|
2742
|
+
opts.walkTokens = function(token) {
|
|
2743
|
+
let values = [];
|
|
2744
|
+
values.push(pack.walkTokens.call(this, token));
|
|
2745
|
+
if (walkTokens) {
|
|
2746
|
+
values = values.concat(walkTokens.call(this, token));
|
|
2747
|
+
}
|
|
2748
|
+
return values;
|
|
2749
|
+
};
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
marked.setOptions(opts);
|
|
2753
|
+
});
|
|
2184
2754
|
};
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2755
|
+
|
|
2756
|
+
/**
|
|
2757
|
+
* Run callback for every token
|
|
2758
|
+
*/
|
|
2759
|
+
|
|
2760
|
+
marked.walkTokens = function(tokens, callback) {
|
|
2761
|
+
let values = [];
|
|
2762
|
+
for (const token of tokens) {
|
|
2763
|
+
values = values.concat(callback.call(marked, token));
|
|
2764
|
+
switch (token.type) {
|
|
2765
|
+
case 'table': {
|
|
2766
|
+
for (const cell of token.header) {
|
|
2767
|
+
values = values.concat(marked.walkTokens(cell.tokens, callback));
|
|
2768
|
+
}
|
|
2769
|
+
for (const row of token.rows) {
|
|
2770
|
+
for (const cell of row) {
|
|
2771
|
+
values = values.concat(marked.walkTokens(cell.tokens, callback));
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
break;
|
|
2775
|
+
}
|
|
2776
|
+
case 'list': {
|
|
2777
|
+
values = values.concat(marked.walkTokens(token.items, callback));
|
|
2778
|
+
break;
|
|
2193
2779
|
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2780
|
+
default: {
|
|
2781
|
+
if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions
|
|
2782
|
+
marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {
|
|
2783
|
+
values = values.concat(marked.walkTokens(token[childTokens], callback));
|
|
2784
|
+
});
|
|
2785
|
+
} else if (token.tokens) {
|
|
2786
|
+
values = values.concat(marked.walkTokens(token.tokens, callback));
|
|
2787
|
+
}
|
|
2197
2788
|
}
|
|
2198
|
-
return msg;
|
|
2199
2789
|
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2790
|
+
}
|
|
2791
|
+
return values;
|
|
2792
|
+
};
|
|
2793
|
+
|
|
2794
|
+
/**
|
|
2795
|
+
* Parse Inline
|
|
2796
|
+
* @param {string} src
|
|
2797
|
+
*/
|
|
2798
|
+
marked.parseInline = function(src, opt) {
|
|
2799
|
+
// throw error in case of non string input
|
|
2800
|
+
if (typeof src === 'undefined' || src === null) {
|
|
2801
|
+
throw new Error('marked.parseInline(): input parameter is undefined or null');
|
|
2802
|
+
}
|
|
2803
|
+
if (typeof src !== 'string') {
|
|
2804
|
+
throw new Error('marked.parseInline(): input parameter is of type '
|
|
2805
|
+
+ Object.prototype.toString.call(src) + ', string expected');
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
opt = merge({}, marked.defaults, opt || {});
|
|
2809
|
+
checkSanitizeDeprecation(opt);
|
|
2810
|
+
|
|
2811
|
+
try {
|
|
2812
|
+
const tokens = Lexer.lexInline(src, opt);
|
|
2813
|
+
if (opt.walkTokens) {
|
|
2814
|
+
marked.walkTokens(tokens, opt.walkTokens);
|
|
2202
2815
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2816
|
+
return Parser.parseInline(tokens, opt);
|
|
2817
|
+
} catch (e) {
|
|
2818
|
+
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
2819
|
+
if (opt.silent) {
|
|
2820
|
+
return '<p>An error occurred:</p><pre>'
|
|
2821
|
+
+ escape(e.message + '', true)
|
|
2822
|
+
+ '</pre>';
|
|
2206
2823
|
}
|
|
2207
2824
|
throw e;
|
|
2208
|
-
}
|
|
2825
|
+
}
|
|
2209
2826
|
};
|
|
2210
2827
|
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
marked.
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
marked.getDefaults = _getDefaults;
|
|
2223
|
-
marked.defaults = _defaults;
|
|
2224
|
-
marked.use = function(...args) {
|
|
2225
|
-
markedInstance.use(...args);
|
|
2226
|
-
marked.defaults = markedInstance.defaults;
|
|
2227
|
-
changeDefaults(marked.defaults);
|
|
2228
|
-
return marked;
|
|
2229
|
-
};
|
|
2230
|
-
marked.walkTokens = function(tokens, callback) {
|
|
2231
|
-
return markedInstance.walkTokens(tokens, callback);
|
|
2232
|
-
};
|
|
2233
|
-
marked.parseInline = markedInstance.parseInline;
|
|
2234
|
-
marked.Parser = _Parser;
|
|
2235
|
-
marked.parser = _Parser.parse;
|
|
2236
|
-
marked.Renderer = _Renderer;
|
|
2237
|
-
marked.TextRenderer = _TextRenderer;
|
|
2238
|
-
marked.Lexer = _Lexer;
|
|
2239
|
-
marked.lexer = _Lexer.lex;
|
|
2240
|
-
marked.Tokenizer = _Tokenizer;
|
|
2241
|
-
marked.Slugger = _Slugger;
|
|
2242
|
-
marked.Hooks = _Hooks;
|
|
2828
|
+
/**
|
|
2829
|
+
* Expose
|
|
2830
|
+
*/
|
|
2831
|
+
marked.Parser = Parser;
|
|
2832
|
+
marked.parser = Parser.parse;
|
|
2833
|
+
marked.Renderer = Renderer;
|
|
2834
|
+
marked.TextRenderer = TextRenderer;
|
|
2835
|
+
marked.Lexer = Lexer;
|
|
2836
|
+
marked.lexer = Lexer.lex;
|
|
2837
|
+
marked.Tokenizer = Tokenizer;
|
|
2838
|
+
marked.Slugger = Slugger;
|
|
2243
2839
|
marked.parse = marked;
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2840
|
+
|
|
2841
|
+
const options = marked.options;
|
|
2842
|
+
const setOptions = marked.setOptions;
|
|
2843
|
+
const use = marked.use;
|
|
2844
|
+
const walkTokens = marked.walkTokens;
|
|
2845
|
+
const parseInline = marked.parseInline;
|
|
2846
|
+
const parse = marked;
|
|
2847
|
+
const parser = Parser.parse;
|
|
2848
|
+
const lexer = Lexer.lex;
|
|
2849
|
+
|
|
2850
|
+
|
|
2851
|
+
|
|
2254
2852
|
|
|
2255
2853
|
/***/ })
|
|
2256
2854
|
|