@subiz/widget-v4 4.0.90 → 4.0.91

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