@subiz/widget-v4 4.1.18 → 4.1.19

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 (93) hide show
  1. package/assets/less/widget_header.less +1 -0
  2. package/package.json +1 -1
  3. package/dist/132.js +0 -6612
  4. package/dist/178.js +0 -406
  5. package/dist/1861083ae18.132.js +0 -1
  6. package/dist/1861083ae18.178.js +0 -1
  7. package/dist/1861083ae18.213.js +0 -1
  8. package/dist/1861083ae18.335.js +0 -1
  9. package/dist/1861083ae18.362.js +0 -1
  10. package/dist/1861083ae18.441.js +0 -1
  11. package/dist/1861083ae18.605.js +0 -1
  12. package/dist/1861083ae18.678.js +0 -1
  13. package/dist/1861083ae18.782.js +0 -1
  14. package/dist/1861083ae18.app.js +0 -1
  15. package/dist/1861083ae18.index.html +0 -26
  16. package/dist/1861083ae18.library.html +0 -26
  17. package/dist/1861083ae18.library.js +0 -1
  18. package/dist/1861083ae18.preview.html +0 -759
  19. package/dist/1861083ae18.preview.js +0 -1
  20. package/dist/1861083ae18.screenshoot.js +0 -1
  21. package/dist/1861083ae18.webview.js +0 -1
  22. package/dist/213.js +0 -2779
  23. package/dist/335.js +0 -372
  24. package/dist/362.js +0 -107
  25. package/dist/441.js +0 -2855
  26. package/dist/605.js +0 -305
  27. package/dist/678.js +0 -107
  28. package/dist/782.js +0 -107
  29. package/dist/HASH +0 -1
  30. package/dist/assets/img/Facebook.64607ec.png +0 -0
  31. package/dist/assets/img/Zalo.6845707.png +0 -0
  32. package/dist/assets/img/award1a.1a58e10.png +0 -0
  33. package/dist/assets/img/award3a.3b74423.png +0 -0
  34. package/dist/assets/img/award4a.ed6ccd4.png +0 -0
  35. package/dist/assets/img/award5.39eb7ae.png +0 -0
  36. package/dist/assets/img/bubble_default.7d5e4ab.svg +0 -20
  37. package/dist/assets/img/caret.998eb8f.svg +0 -1
  38. package/dist/assets/img/convos_empty.2353007.svg +0 -72
  39. package/dist/assets/img/default.06e6ee0.jpg +0 -0
  40. package/dist/assets/img/default_avatar.5b74dc1.png +0 -0
  41. package/dist/assets/img/done_gray.d7e8203.svg +0 -4
  42. package/dist/assets/img/done_green.b817fd4.svg +0 -4
  43. package/dist/assets/img/emoji/messenger/sub_23.529_58.824.d5faf14.png +0 -0
  44. package/dist/assets/img/emoji/messenger/sub_23.529_60.784.1420241.png +0 -0
  45. package/dist/assets/img/emoji/messenger/sub_25.490_0.000.1e6b2c0.png +0 -0
  46. package/dist/assets/img/emoji/messenger/sub_25.490_45.098.3dfbc08.png +0 -0
  47. package/dist/assets/img/emoji/messenger/sub_25.490_5.882.4b49e94.png +0 -0
  48. package/dist/assets/img/emoji/messenger/sub_27.451_72.549.7114f58.png +0 -0
  49. package/dist/assets/img/emoji/messenger/sub_27.451_84.314.231e2b7.png +0 -0
  50. package/dist/assets/img/emoji/messenger/sub_27.451_96.078.ddbb008.png +0 -0
  51. package/dist/assets/img/emoji/messenger/sub_29.412_5.882.61f3359.png +0 -0
  52. package/dist/assets/img/emoji/messenger/sub_58.824_100.000.6df72bc.png +0 -0
  53. package/dist/assets/img/emoji/messenger/sub_58.824_45.098.3d7a7ad.png +0 -0
  54. package/dist/assets/img/emoji/messenger/sub_58.824_47.059.0f4d6e2.png +0 -0
  55. package/dist/assets/img/emoji/messenger/sub_58.824_54.902.65724c1.png +0 -0
  56. package/dist/assets/img/emoji/messenger/sub_58.824_64.706.9da3cba.png +0 -0
  57. package/dist/assets/img/emoji/messenger/sub_58.824_72.549.edca5cf.png +0 -0
  58. package/dist/assets/img/emoji/messenger/sub_58.824_78.431.f910f2a.png +0 -0
  59. package/dist/assets/img/emoji/messenger/sub_58.824_88.235.def4e71.png +0 -0
  60. package/dist/assets/img/emoji/messenger/sub_60.784_11.765.49c03d0.png +0 -0
  61. package/dist/assets/img/emoji/messenger/sub_60.784_27.451.46b54e5.png +0 -0
  62. package/dist/assets/img/emoji/messenger/sub_60.784_29.412.e36d284.png +0 -0
  63. package/dist/assets/img/emoji/messenger/sub_60.784_3.922.bb191b0.png +0 -0
  64. package/dist/assets/img/emoji/messenger/sub_60.784_35.294.af7b927.png +0 -0
  65. package/dist/assets/img/emoji/messenger/sub_60.784_7.843.98f2a99.png +0 -0
  66. package/dist/assets/img/empty.29bed2d.svg +0 -23
  67. package/dist/assets/img/empty_1.0b98af0.svg +0 -11
  68. package/dist/assets/img/examplte_logo.f86535f.svg +0 -1
  69. package/dist/assets/img/external-link.90577cc.svg +0 -1
  70. package/dist/assets/img/fb_inverse_circle.36c2cfc.png +0 -0
  71. package/dist/assets/img/ghn.070f8e3.svg +0 -17
  72. package/dist/assets/img/ghtk.326eac1.svg +0 -18
  73. package/dist/assets/img/image_default.be0698b.png +0 -0
  74. package/dist/assets/img/info.ebce7ea.svg +0 -1
  75. package/dist/assets/img/loader.37000a7.svg +0 -1
  76. package/dist/assets/img/loading_static.8f403ae.svg +0 -10
  77. package/dist/assets/img/main-service1.d536cc2.png +0 -0
  78. package/dist/assets/img/main-service2.9b99549.png +0 -0
  79. package/dist/assets/img/not_found_search.2ddb8d1.png +0 -0
  80. package/dist/assets/img/package.8d37d0f.svg +0 -5
  81. package/dist/assets/img/package_fade.763c001.svg +0 -1
  82. package/dist/assets/img/rating--average.1ea492c.svg +0 -12
  83. package/dist/assets/img/rating--great.e3d712e.svg +0 -16
  84. package/dist/assets/img/rating--poor.2938a25.svg +0 -12
  85. package/dist/assets/img/search.f9705ff.svg +0 -1
  86. package/dist/assets/img/send.6db52a9.svg +0 -3
  87. package/dist/assets/img/shop.f7dc7d8.svg +0 -1
  88. package/dist/assets/img/shop_faded.df7845a.svg +0 -1
  89. package/dist/assets/img/subiz-mono.877e9f5.svg +0 -3
  90. package/dist/assets/img/x.26fdfa3.svg +0 -5
  91. package/dist/malicious-app.js +0 -13
  92. package/dist/screenshoot.html +0 -7
  93. package/dist/screenshoot.js +0 -5633
package/dist/441.js DELETED
@@ -1,2855 +0,0 @@
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 v4.2.12 - a markdown parser
29
- * Copyright (c) 2011-2023, 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
- async: false,
41
- baseUrl: null,
42
- breaks: false,
43
- extensions: null,
44
- gfm: true,
45
- headerIds: true,
46
- headerPrefix: '',
47
- highlight: null,
48
- langPrefix: 'language-',
49
- mangle: true,
50
- pedantic: false,
51
- renderer: null,
52
- sanitize: false,
53
- sanitizer: null,
54
- silent: 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 = 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
- '&': '&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
- /**
100
- * @param {string} html
101
- */
102
- function unescape(html) {
103
- // explicitly match decimal, hex, and named HTML entities
104
- return html.replace(unescapeTest, (_, n) => {
105
- n = n.toLowerCase();
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));
111
- }
112
- return '';
113
- });
114
- }
115
-
116
- const caret = /(^|[^\[])\^/g;
117
-
118
- /**
119
- * @param {string | RegExp} regex
120
- * @param {string} opt
121
- */
122
- function edit(regex, opt) {
123
- regex = typeof regex === 'string' ? regex : regex.source;
124
- opt = opt || '';
125
- const obj = {
126
- replace: (name, val) => {
127
- val = val.source || val;
128
- val = val.replace(caret, '$1');
129
- regex = regex.replace(name, val);
130
- return obj;
131
- },
132
- getRegex: () => {
133
- return new RegExp(regex, opt);
134
- }
135
- };
136
- return obj;
137
- }
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
- */
147
- function cleanUrl(sanitize, base, href) {
148
- if (sanitize) {
149
- let prot;
150
- try {
151
- prot = decodeURIComponent(unescape(href))
152
- .replace(nonWordAndColonTest, '')
153
- .toLowerCase();
154
- } catch (e) {
155
- return null;
156
- }
157
- if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
158
- return null;
159
- }
160
- }
161
- if (base && !originIndependentUrl.test(href)) {
162
- href = resolveUrl(base, href);
163
- }
164
- try {
165
- href = encodeURI(href).replace(/%25/g, '%');
166
- } catch (e) {
167
- return null;
168
- }
169
- return href;
170
- }
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
- */
181
- function resolveUrl(base, href) {
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
186
- if (justDomain.test(base)) {
187
- baseUrls[' ' + base] = base + '/';
188
- } else {
189
- baseUrls[' ' + base] = rtrim(base, '/', true);
190
- }
191
- }
192
- base = baseUrls[' ' + base];
193
- const relativeBase = base.indexOf(':') === -1;
194
-
195
- if (href.substring(0, 2) === '//') {
196
- if (relativeBase) {
197
- return href;
198
- }
199
- return base.replace(protocol, '$1') + href;
200
- } else if (href.charAt(0) === '/') {
201
- if (relativeBase) {
202
- return href;
203
- }
204
- return base.replace(domain, '$1') + href;
205
- } else {
206
- return base + href;
207
- }
208
- }
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
-
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
232
- const row = tableRow.replace(/\|/g, (match, offset, str) => {
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(/ \|/);
246
- let i = 0;
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
-
252
- if (cells.length > count) {
253
- cells.splice(count);
254
- } else {
255
- while (cells.length < count) cells.push('');
256
- }
257
-
258
- for (; i < cells.length; i++) {
259
- // leading or trailing whitespace is ignored per the gfm spec
260
- cells[i] = cells[i].trim().replace(/\\\|/g, '|');
261
- }
262
- return cells;
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
- */
273
- function rtrim(str, c, invert) {
274
- const l = str.length;
275
- if (l === 0) {
276
- return '';
277
- }
278
-
279
- // Length of suffix matching the invert condition.
280
- let suffLen = 0;
281
-
282
- // Step left until we fail to match the invert condition.
283
- while (suffLen < l) {
284
- const currChar = str.charAt(l - suffLen - 1);
285
- if (currChar === c && !invert) {
286
- suffLen++;
287
- } else if (currChar !== c && invert) {
288
- suffLen++;
289
- } else {
290
- break;
291
- }
292
- }
293
-
294
- return str.slice(0, l - suffLen);
295
- }
296
-
297
- function findClosingBracket(str, b) {
298
- if (str.indexOf(b[1]) === -1) {
299
- return -1;
300
- }
301
- const l = str.length;
302
- let level = 0,
303
- i = 0;
304
- for (; i < l; i++) {
305
- if (str[i] === '\\') {
306
- i++;
307
- } else if (str[i] === b[0]) {
308
- level++;
309
- } else if (str[i] === b[1]) {
310
- level--;
311
- if (level < 0) {
312
- return i;
313
- }
314
- }
315
- }
316
- return -1;
317
- }
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');
322
- }
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 '';
333
- }
334
- let result = '';
335
- while (count > 1) {
336
- if (count & 1) {
337
- result += pattern;
338
- }
339
- count >>= 1;
340
- pattern += pattern;
341
- }
342
- return result + pattern;
343
- }
344
-
345
- function outputLink(cap, link, raw, lexer) {
346
- const href = link.href;
347
- const title = link.title ? escape(link.title) : null;
348
- const text = cap[1].replace(/\\([\[\]])/g, '$1');
349
-
350
- if (cap[0].charAt(0) !== '!') {
351
- lexer.state.inLink = true;
352
- const token = {
353
- type: 'link',
354
- raw,
355
- href,
356
- title,
357
- text,
358
- tokens: lexer.inlineTokens(text)
359
- };
360
- lexer.state.inLink = false;
361
- return token;
362
- }
363
- return {
364
- type: 'image',
365
- raw,
366
- href,
367
- title,
368
- text: escape(text)
369
- };
370
- }
371
-
372
- function indentCodeCompensation(raw, text) {
373
- const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
374
-
375
- if (matchIndentToCode === null) {
376
- return text;
377
- }
378
-
379
- const indentToCode = matchIndentToCode[1];
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
-
395
- return node;
396
- })
397
- .join('\n');
398
- }
399
-
400
- /**
401
- * Tokenizer
402
- */
403
- class Tokenizer {
404
- constructor(options) {
405
- this.options = options || defaults;
406
- }
407
-
408
- space(src) {
409
- const cap = this.rules.block.newline.exec(src);
410
- if (cap && cap[0].length > 0) {
411
- return {
412
- type: 'space',
413
- raw: cap[0]
414
- };
415
- }
416
- }
417
-
418
- code(src) {
419
- const cap = this.rules.block.code.exec(src);
420
- if (cap) {
421
- const text = cap[0].replace(/^ {1,4}/gm, '');
422
- return {
423
- type: 'code',
424
- raw: cap[0],
425
- codeBlockStyle: 'indented',
426
- text: !this.options.pedantic
427
- ? rtrim(text, '\n')
428
- : text
429
- };
430
- }
431
- }
432
-
433
- fences(src) {
434
- const cap = this.rules.block.fences.exec(src);
435
- if (cap) {
436
- const raw = cap[0];
437
- const text = indentCodeCompensation(raw, cap[3] || '');
438
-
439
- return {
440
- type: 'code',
441
- raw,
442
- lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
443
- text
444
- };
445
- }
446
- }
447
-
448
- heading(src) {
449
- const cap = this.rules.block.heading.exec(src);
450
- if (cap) {
451
- let text = cap[2].trim();
452
-
453
- // remove trailing #s
454
- if (/#$/.test(text)) {
455
- const trimmed = rtrim(text, '#');
456
- if (this.options.pedantic) {
457
- text = trimmed.trim();
458
- } else if (!trimmed || / $/.test(trimmed)) {
459
- // CommonMark requires space before trailing #s
460
- text = trimmed.trim();
461
- }
462
- }
463
-
464
- return {
465
- type: 'heading',
466
- raw: cap[0],
467
- depth: cap[1].length,
468
- text,
469
- tokens: this.lexer.inline(text)
470
- };
471
- }
472
- }
473
-
474
- hr(src) {
475
- const cap = this.rules.block.hr.exec(src);
476
- if (cap) {
477
- return {
478
- type: 'hr',
479
- raw: cap[0]
480
- };
481
- }
482
- }
483
-
484
- blockquote(src) {
485
- const cap = this.rules.block.blockquote.exec(src);
486
- if (cap) {
487
- const text = cap[0].replace(/^ *>[ \t]?/gm, '');
488
- const top = this.lexer.state.top;
489
- this.lexer.state.top = true;
490
- const tokens = this.lexer.blockTokens(text);
491
- this.lexer.state.top = top;
492
- return {
493
- type: 'blockquote',
494
- raw: cap[0],
495
- tokens,
496
- text
497
- };
498
- }
499
- }
500
-
501
- list(src) {
502
- let cap = this.rules.block.list.exec(src);
503
- if (cap) {
504
- let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine,
505
- line, nextLine, rawLine, itemContents, endEarly;
506
-
507
- let bull = cap[1].trim();
508
- const isordered = bull.length > 1;
509
-
510
- const list = {
511
- type: 'list',
512
- raw: '',
513
- ordered: isordered,
514
- start: isordered ? +bull.slice(0, -1) : '',
515
- loose: false,
516
- items: []
517
- };
518
-
519
- bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
520
-
521
- if (this.options.pedantic) {
522
- bull = isordered ? bull : '[*+-]';
523
- }
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
529
- while (src) {
530
- endEarly = false;
531
- if (!(cap = itemRegex.exec(src))) {
532
- break;
533
- }
534
-
535
- if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
536
- break;
537
- }
538
-
539
- raw = cap[0];
540
- src = src.substring(raw.length);
541
-
542
- line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
543
- nextLine = src.split('\n', 1)[0];
544
-
545
- if (this.options.pedantic) {
546
- indent = 2;
547
- itemContents = line.trimLeft();
548
- } else {
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
551
- itemContents = line.slice(indent);
552
- indent += cap[1].length;
553
- }
554
-
555
- blankLine = false;
556
-
557
- if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
558
- raw += nextLine + '\n';
559
- src = src.substring(nextLine.length + 1);
560
- endEarly = true;
561
- }
562
-
563
- if (!endEarly) {
564
- const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
565
- const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
566
- const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
567
- const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
568
-
569
- // Check if following lines should be included in List Item
570
- while (src) {
571
- rawLine = src.split('\n', 1)[0];
572
- nextLine = rawLine;
573
-
574
- // Re-align to follow commonmark nesting rules
575
- if (this.options.pedantic) {
576
- nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');
577
- }
578
-
579
- // End list item if found code fences
580
- if (fencesBeginRegex.test(nextLine)) {
581
- break;
582
- }
583
-
584
- // End list item if found start of new heading
585
- if (headingBeginRegex.test(nextLine)) {
586
- break;
587
- }
588
-
589
- // End list item if found start of new bullet
590
- if (nextBulletRegex.test(nextLine)) {
591
- break;
592
- }
593
-
594
- // Horizontal rule found
595
- if (hrRegex.test(src)) {
596
- break;
597
- }
598
-
599
- if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
600
- itemContents += '\n' + nextLine.slice(indent);
601
- } else {
602
- // not enough indentation
603
- if (blankLine) {
604
- break;
605
- }
606
-
607
- // paragraph continuation unless last line was a different block level element
608
- if (line.search(/[^ ]/) >= 4) { // indented code block
609
- break;
610
- }
611
- if (fencesBeginRegex.test(line)) {
612
- break;
613
- }
614
- if (headingBeginRegex.test(line)) {
615
- break;
616
- }
617
- if (hrRegex.test(line)) {
618
- break;
619
- }
620
-
621
- itemContents += '\n' + nextLine;
622
- }
623
-
624
- if (!blankLine && !nextLine.trim()) { // Check if current line is blank
625
- blankLine = true;
626
- }
627
-
628
- raw += rawLine + '\n';
629
- src = src.substring(rawLine.length + 1);
630
- line = nextLine.slice(indent);
631
- }
632
- }
633
-
634
- if (!list.loose) {
635
- // If the previous item ended with a blank line, the list is loose
636
- if (endsWithBlankLine) {
637
- list.loose = true;
638
- } else if (/\n *\n *$/.test(raw)) {
639
- endsWithBlankLine = true;
640
- }
641
- }
642
-
643
- // Check for task list items
644
- if (this.options.gfm) {
645
- istask = /^\[[ xX]\] /.exec(itemContents);
646
- if (istask) {
647
- ischecked = istask[0] !== '[ ] ';
648
- itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
649
- }
650
- }
651
-
652
- list.items.push({
653
- type: 'list_item',
654
- raw,
655
- task: !!istask,
656
- checked: ischecked,
657
- loose: false,
658
- text: itemContents
659
- });
660
-
661
- list.raw += raw;
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
665
- list.items[list.items.length - 1].raw = raw.trimRight();
666
- list.items[list.items.length - 1].text = itemContents.trimRight();
667
- list.raw = list.raw.trimRight();
668
-
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
672
- for (i = 0; i < l; i++) {
673
- this.lexer.state.top = false;
674
- list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
675
-
676
- if (!list.loose) {
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
-
681
- list.loose = hasMultipleLineBreaks;
682
- }
683
- }
684
-
685
- // Set all items to loose if list is loose
686
- if (list.loose) {
687
- for (i = 0; i < l; i++) {
688
- list.items[i].loose = true;
689
- }
690
- }
691
-
692
- return list;
693
- }
694
- }
695
-
696
- html(src) {
697
- const cap = this.rules.block.html.exec(src);
698
- if (cap) {
699
- const token = {
700
- type: 'html',
701
- raw: cap[0],
702
- pre: !this.options.sanitizer
703
- && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
704
- text: cap[0]
705
- };
706
- if (this.options.sanitize) {
707
- const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
708
- token.type = 'paragraph';
709
- token.text = text;
710
- token.tokens = this.lexer.inline(text);
711
- }
712
- return token;
713
- }
714
- }
715
-
716
- def(src) {
717
- const cap = this.rules.block.def.exec(src);
718
- if (cap) {
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];
722
- return {
723
- type: 'def',
724
- tag,
725
- raw: cap[0],
726
- href,
727
- title
728
- };
729
- }
730
- }
731
-
732
- table(src) {
733
- const cap = this.rules.block.table.exec(src);
734
- if (cap) {
735
- const item = {
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') : []
740
- };
741
-
742
- if (item.header.length === item.align.length) {
743
- item.raw = cap[0];
744
-
745
- let l = item.align.length;
746
- let i, j, k, row;
747
- for (i = 0; i < l; i++) {
748
- if (/^ *-+: *$/.test(item.align[i])) {
749
- item.align[i] = 'right';
750
- } else if (/^ *:-+: *$/.test(item.align[i])) {
751
- item.align[i] = 'center';
752
- } else if (/^ *:-+ *$/.test(item.align[i])) {
753
- item.align[i] = 'left';
754
- } else {
755
- item.align[i] = null;
756
- }
757
- }
758
-
759
- l = item.rows.length;
760
- for (i = 0; i < l; i++) {
761
- item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; });
762
- }
763
-
764
- // parse child tokens inside headers and cells
765
-
766
- // header child tokens
767
- l = item.header.length;
768
- for (j = 0; j < l; j++) {
769
- item.header[j].tokens = this.lexer.inline(item.header[j].text);
770
- }
771
-
772
- // cell child tokens
773
- l = item.rows.length;
774
- for (j = 0; j < l; j++) {
775
- row = item.rows[j];
776
- for (k = 0; k < row.length; k++) {
777
- row[k].tokens = this.lexer.inline(row[k].text);
778
- }
779
- }
780
-
781
- return item;
782
- }
783
- }
784
- }
785
-
786
- lheading(src) {
787
- const cap = this.rules.block.lheading.exec(src);
788
- if (cap) {
789
- return {
790
- type: 'heading',
791
- raw: cap[0],
792
- depth: cap[2].charAt(0) === '=' ? 1 : 2,
793
- text: cap[1],
794
- tokens: this.lexer.inline(cap[1])
795
- };
796
- }
797
- }
798
-
799
- paragraph(src) {
800
- const cap = this.rules.block.paragraph.exec(src);
801
- if (cap) {
802
- const text = cap[1].charAt(cap[1].length - 1) === '\n'
803
- ? cap[1].slice(0, -1)
804
- : cap[1];
805
- return {
806
- type: 'paragraph',
807
- raw: cap[0],
808
- text,
809
- tokens: this.lexer.inline(text)
810
- };
811
- }
812
- }
813
-
814
- text(src) {
815
- const cap = this.rules.block.text.exec(src);
816
- if (cap) {
817
- return {
818
- type: 'text',
819
- raw: cap[0],
820
- text: cap[0],
821
- tokens: this.lexer.inline(cap[0])
822
- };
823
- }
824
- }
825
-
826
- escape(src) {
827
- const cap = this.rules.inline.escape.exec(src);
828
- if (cap) {
829
- return {
830
- type: 'escape',
831
- raw: cap[0],
832
- text: escape(cap[1])
833
- };
834
- }
835
- }
836
-
837
- tag(src) {
838
- const cap = this.rules.inline.tag.exec(src);
839
- if (cap) {
840
- if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
841
- this.lexer.state.inLink = true;
842
- } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
843
- this.lexer.state.inLink = false;
844
- }
845
- if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
846
- this.lexer.state.inRawBlock = true;
847
- } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
848
- this.lexer.state.inRawBlock = false;
849
- }
850
-
851
- return {
852
- type: this.options.sanitize
853
- ? 'text'
854
- : 'html',
855
- raw: cap[0],
856
- inLink: this.lexer.state.inLink,
857
- inRawBlock: this.lexer.state.inRawBlock,
858
- text: this.options.sanitize
859
- ? (this.options.sanitizer
860
- ? this.options.sanitizer(cap[0])
861
- : escape(cap[0]))
862
- : cap[0]
863
- };
864
- }
865
- }
866
-
867
- link(src) {
868
- const cap = this.rules.inline.link.exec(src);
869
- if (cap) {
870
- const trimmedUrl = cap[2].trim();
871
- if (!this.options.pedantic && /^</.test(trimmedUrl)) {
872
- // commonmark requires matching angle brackets
873
- if (!(/>$/.test(trimmedUrl))) {
874
- return;
875
- }
876
-
877
- // ending angle bracket cannot be escaped
878
- const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
879
- if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
880
- return;
881
- }
882
- } else {
883
- // find closing parenthesis
884
- const lastParenIndex = findClosingBracket(cap[2], '()');
885
- if (lastParenIndex > -1) {
886
- const start = cap[0].indexOf('!') === 0 ? 5 : 4;
887
- const linkLen = start + cap[1].length + lastParenIndex;
888
- cap[2] = cap[2].substring(0, lastParenIndex);
889
- cap[0] = cap[0].substring(0, linkLen).trim();
890
- cap[3] = '';
891
- }
892
- }
893
- let href = cap[2];
894
- let title = '';
895
- if (this.options.pedantic) {
896
- // split pedantic href and title
897
- const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
898
-
899
- if (link) {
900
- href = link[1];
901
- title = link[3];
902
- }
903
- } else {
904
- title = cap[3] ? cap[3].slice(1, -1) : '';
905
- }
906
-
907
- href = href.trim();
908
- if (/^</.test(href)) {
909
- if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
910
- // pedantic allows starting angle bracket without ending angle bracket
911
- href = href.slice(1);
912
- } else {
913
- href = href.slice(1, -1);
914
- }
915
- }
916
- return outputLink(cap, {
917
- href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
918
- title: title ? title.replace(this.rules.inline._escapes, '$1') : title
919
- }, cap[0], this.lexer);
920
- }
921
- }
922
-
923
- reflink(src, links) {
924
- let cap;
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, ' ');
928
- link = links[link.toLowerCase()];
929
- if (!link) {
930
- const text = cap[0].charAt(0);
931
- return {
932
- type: 'text',
933
- raw: text,
934
- text
935
- };
936
- }
937
- return outputLink(cap, link, cap[0], this.lexer);
938
- }
939
- }
940
-
941
- emStrong(src, maskedSrc, prevChar = '') {
942
- let match = this.rules.inline.emStrong.lDelim.exec(src);
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)))) {
951
- const lLength = match[0].length - 1;
952
- let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
953
-
954
- const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
955
- endReg.lastIndex = 0;
956
-
957
- // Clip maskedSrc to same section of string as src (move to lexer?)
958
- maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
959
-
960
- while ((match = endReg.exec(maskedSrc)) != null) {
961
- rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
962
-
963
- if (!rDelim) continue; // skip single * in __abc*abc__
964
-
965
- rLength = rDelim.length;
966
-
967
- if (match[3] || match[4]) { // found another Left Delim
968
- delimTotal += rLength;
969
- continue;
970
- } else if (match[5] || match[6]) { // either Left or Right Delim
971
- if (lLength % 3 && !((lLength + rLength) % 3)) {
972
- midDelimTotal += rLength;
973
- continue; // CommonMark Emphasis Rules 9-10
974
- }
975
- }
976
-
977
- delimTotal -= rLength;
978
-
979
- if (delimTotal > 0) continue; // Haven't found enough closing delimiters
980
-
981
- // Remove extra characters. *a*** -> *a*
982
- rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
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***
987
- if (Math.min(lLength, rLength) % 2) {
988
- const text = raw.slice(1, -1);
989
- return {
990
- type: 'em',
991
- raw,
992
- text,
993
- tokens: this.lexer.inlineTokens(text)
994
- };
995
- }
996
-
997
- // Create 'strong' if smallest delimiter has even char count. **a***
998
- const text = raw.slice(2, -2);
999
- return {
1000
- type: 'strong',
1001
- raw,
1002
- text,
1003
- tokens: this.lexer.inlineTokens(text)
1004
- };
1005
- }
1006
- }
1007
- }
1008
-
1009
- codespan(src) {
1010
- const cap = this.rules.inline.code.exec(src);
1011
- if (cap) {
1012
- let text = cap[2].replace(/\n/g, ' ');
1013
- const hasNonSpaceChars = /[^ ]/.test(text);
1014
- const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
1015
- if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
1016
- text = text.substring(1, text.length - 1);
1017
- }
1018
- text = escape(text, true);
1019
- return {
1020
- type: 'codespan',
1021
- raw: cap[0],
1022
- text
1023
- };
1024
- }
1025
- }
1026
-
1027
- br(src) {
1028
- const cap = this.rules.inline.br.exec(src);
1029
- if (cap) {
1030
- return {
1031
- type: 'br',
1032
- raw: cap[0]
1033
- };
1034
- }
1035
- }
1036
-
1037
- del(src) {
1038
- const cap = this.rules.inline.del.exec(src);
1039
- if (cap) {
1040
- return {
1041
- type: 'del',
1042
- raw: cap[0],
1043
- text: cap[2],
1044
- tokens: this.lexer.inlineTokens(cap[2])
1045
- };
1046
- }
1047
- }
1048
-
1049
- autolink(src, mangle) {
1050
- const cap = this.rules.inline.autolink.exec(src);
1051
- if (cap) {
1052
- let text, href;
1053
- if (cap[2] === '@') {
1054
- text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
1055
- href = 'mailto:' + text;
1056
- } else {
1057
- text = escape(cap[1]);
1058
- href = text;
1059
- }
1060
-
1061
- return {
1062
- type: 'link',
1063
- raw: cap[0],
1064
- text,
1065
- href,
1066
- tokens: [
1067
- {
1068
- type: 'text',
1069
- raw: text,
1070
- text
1071
- }
1072
- ]
1073
- };
1074
- }
1075
- }
1076
-
1077
- url(src, mangle) {
1078
- let cap;
1079
- if (cap = this.rules.inline.url.exec(src)) {
1080
- let text, href;
1081
- if (cap[2] === '@') {
1082
- text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
1083
- href = 'mailto:' + text;
1084
- } else {
1085
- // do extended autolink path validation
1086
- let prevCapZero;
1087
- do {
1088
- prevCapZero = cap[0];
1089
- cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
1090
- } while (prevCapZero !== cap[0]);
1091
- text = escape(cap[0]);
1092
- if (cap[1] === 'www.') {
1093
- href = 'http://' + cap[0];
1094
- } else {
1095
- href = cap[0];
1096
- }
1097
- }
1098
- return {
1099
- type: 'link',
1100
- raw: cap[0],
1101
- text,
1102
- href,
1103
- tokens: [
1104
- {
1105
- type: 'text',
1106
- raw: text,
1107
- text
1108
- }
1109
- ]
1110
- };
1111
- }
1112
- }
1113
-
1114
- inlineText(src, smartypants) {
1115
- const cap = this.rules.inline.text.exec(src);
1116
- if (cap) {
1117
- let text;
1118
- if (this.lexer.state.inRawBlock) {
1119
- text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];
1120
- } else {
1121
- text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
1122
- }
1123
- return {
1124
- type: 'text',
1125
- raw: cap[0],
1126
- text
1127
- };
1128
- }
1129
- }
1130
- }
1131
-
1132
- /**
1133
- * Block-Level Grammar
1134
- */
1135
- const block = {
1136
- newline: /^(?: *(?:\n|$))+/,
1137
- code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
1138
- fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
1139
- hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
1140
- heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
1141
- blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
1142
- list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
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
- + ')',
1153
- def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
1154
- table: noopTest,
1155
- lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
1156
- // regex template, placeholders will be replaced according to different paragraph
1157
- // interruption rules of commonmark and the original markdown spec:
1158
- _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
1159
- text: /^[^\n]+/
1160
- };
1161
-
1162
- block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
1163
- block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
1164
- block.def = edit(block.def)
1165
- .replace('label', block._label)
1166
- .replace('title', block._title)
1167
- .getRegex();
1168
-
1169
- block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
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';
1186
- block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
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, {
1252
- html: edit(
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(),
1262
- def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
1263
- heading: /^(#{1,6})(.*)(?:\n+|$)/,
1264
- fences: noopTest, // fences not supported
1265
- lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
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 = {
1281
- escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
1282
- autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
1283
- url: noopTest,
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
1290
- link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
1291
- reflink: /^!?\[(label)\]\[(ref)\]/,
1292
- nolink: /^!?\[(ref)\](?:\[\])?/,
1293
- reflinkSearch: 'reflink|nolink(?!\\()',
1294
- emStrong: {
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 _
1300
- },
1301
- code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
1302
- br: /^( {2,}|\\)\n(?!\s*$)/,
1303
- del: noopTest,
1304
- text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
1305
- punctuation: /^([\spunctuation])/
1306
- };
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
-
1335
- inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
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])?)+(?![-_])/;
1337
- inline.autolink = edit(inline.autolink)
1338
- .replace('scheme', inline._scheme)
1339
- .replace('email', inline._email)
1340
- .getRegex();
1341
-
1342
- inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
1343
-
1344
- inline.tag = edit(inline.tag)
1345
- .replace('comment', inline._comment)
1346
- .replace('attribute', inline._attribute)
1347
- .getRegex();
1348
-
1349
- inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
1350
- inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
1351
- inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
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, {
1384
- strong: {
1385
- start: /^__|\*\*/,
1386
- middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
1387
- endAst: /\*\*(?!\*)/g,
1388
- endUnd: /__(?!_)/g
1389
- },
1390
- em: {
1391
- start: /^_|\*/,
1392
- middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
1393
- endAst: /\*(?!\*)/g,
1394
- endUnd: /_(?!_)/g
1395
- },
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(),
1410
- _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
1411
- url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
1412
- _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
1413
- del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
1414
- text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
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
- */
1423
-
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
- */
1436
- function smartypants(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');
1452
- }
1453
-
1454
- /**
1455
- * mangle email addresses
1456
- * @param {string} text
1457
- */
1458
- function mangle(text) {
1459
- let out = '',
1460
- i,
1461
- ch;
1462
-
1463
- const l = text.length;
1464
- for (i = 0; i < l; i++) {
1465
- ch = text.charCodeAt(i);
1466
- if (Math.random() > 0.5) {
1467
- ch = 'x' + ch.toString(16);
1468
- }
1469
- out += '&#' + ch + ';';
1470
- }
1471
-
1472
- return out;
1473
- }
1474
-
1475
- /**
1476
- * Block Lexer
1477
- */
1478
- class Lexer {
1479
- constructor(options) {
1480
- this.tokens = [];
1481
- this.tokens.links = Object.create(null);
1482
- this.options = options || defaults;
1483
- this.options.tokenizer = this.options.tokenizer || new Tokenizer();
1484
- this.tokenizer = this.options.tokenizer;
1485
- this.tokenizer.options = this.options;
1486
- this.tokenizer.lexer = this;
1487
- this.inlineQueue = [];
1488
- this.state = {
1489
- inLink: false,
1490
- inRawBlock: false,
1491
- top: true
1492
- };
1493
-
1494
- const rules = {
1495
- block: block.normal,
1496
- inline: inline.normal
1497
- };
1498
-
1499
- if (this.options.pedantic) {
1500
- rules.block = block.pedantic;
1501
- rules.inline = inline.pedantic;
1502
- } else if (this.options.gfm) {
1503
- rules.block = block.gfm;
1504
- if (this.options.breaks) {
1505
- rules.inline = inline.breaks;
1506
- } else {
1507
- rules.inline = inline.gfm;
1508
- }
1509
- }
1510
- this.tokenizer.rules = rules;
1511
- }
1512
-
1513
- /**
1514
- * Expose Rules
1515
- */
1516
- static get rules() {
1517
- return {
1518
- block,
1519
- inline
1520
- };
1521
- }
1522
-
1523
- /**
1524
- * Static Lex Method
1525
- */
1526
- static lex(src, options) {
1527
- const lexer = new Lexer(options);
1528
- return lexer.lex(src);
1529
- }
1530
-
1531
- /**
1532
- * Static Lex Inline Method
1533
- */
1534
- static lexInline(src, options) {
1535
- const lexer = new Lexer(options);
1536
- return lexer.inlineTokens(src);
1537
- }
1538
-
1539
- /**
1540
- * Preprocessing
1541
- */
1542
- lex(src) {
1543
- src = src
1544
- .replace(/\r\n|\r/g, '\n');
1545
-
1546
- this.blockTokens(src, this.tokens);
1547
-
1548
- let next;
1549
- while (next = this.inlineQueue.shift()) {
1550
- this.inlineTokens(next.src, next.tokens);
1551
- }
1552
-
1553
- return this.tokens;
1554
- }
1555
-
1556
- /**
1557
- * Lexing
1558
- */
1559
- blockTokens(src, tokens = []) {
1560
- if (this.options.pedantic) {
1561
- src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
1562
- } else {
1563
- src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
1564
- return leading + ' '.repeat(tabs.length);
1565
- });
1566
- }
1567
-
1568
- let token, lastToken, cutSrc, lastParagraphClipped;
1569
-
1570
- while (src) {
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
- })) {
1581
- continue;
1582
- }
1583
-
1584
- // newline
1585
- if (token = this.tokenizer.space(src)) {
1586
- src = src.substring(token.raw.length);
1587
- if (token.raw.length === 1 && tokens.length > 0) {
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';
1591
- } else {
1592
- tokens.push(token);
1593
- }
1594
- continue;
1595
- }
1596
-
1597
- // code
1598
- if (token = this.tokenizer.code(src)) {
1599
- src = src.substring(token.raw.length);
1600
- lastToken = tokens[tokens.length - 1];
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;
1605
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1606
- } else {
1607
- tokens.push(token);
1608
- }
1609
- continue;
1610
- }
1611
-
1612
- // fences
1613
- if (token = this.tokenizer.fences(src)) {
1614
- src = src.substring(token.raw.length);
1615
- tokens.push(token);
1616
- continue;
1617
- }
1618
-
1619
- // heading
1620
- if (token = this.tokenizer.heading(src)) {
1621
- src = src.substring(token.raw.length);
1622
- tokens.push(token);
1623
- continue;
1624
- }
1625
-
1626
- // hr
1627
- if (token = this.tokenizer.hr(src)) {
1628
- src = src.substring(token.raw.length);
1629
- tokens.push(token);
1630
- continue;
1631
- }
1632
-
1633
- // blockquote
1634
- if (token = this.tokenizer.blockquote(src)) {
1635
- src = src.substring(token.raw.length);
1636
- tokens.push(token);
1637
- continue;
1638
- }
1639
-
1640
- // list
1641
- if (token = this.tokenizer.list(src)) {
1642
- src = src.substring(token.raw.length);
1643
- tokens.push(token);
1644
- continue;
1645
- }
1646
-
1647
- // html
1648
- if (token = this.tokenizer.html(src)) {
1649
- src = src.substring(token.raw.length);
1650
- tokens.push(token);
1651
- continue;
1652
- }
1653
-
1654
- // def
1655
- if (token = this.tokenizer.def(src)) {
1656
- src = src.substring(token.raw.length);
1657
- lastToken = tokens[tokens.length - 1];
1658
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1659
- lastToken.raw += '\n' + token.raw;
1660
- lastToken.text += '\n' + token.raw;
1661
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1662
- } else if (!this.tokens.links[token.tag]) {
1663
- this.tokens.links[token.tag] = {
1664
- href: token.href,
1665
- title: token.title
1666
- };
1667
- }
1668
- continue;
1669
- }
1670
-
1671
- // table (gfm)
1672
- if (token = this.tokenizer.table(src)) {
1673
- src = src.substring(token.raw.length);
1674
- tokens.push(token);
1675
- continue;
1676
- }
1677
-
1678
- // lheading
1679
- if (token = this.tokenizer.lheading(src)) {
1680
- src = src.substring(token.raw.length);
1681
- tokens.push(token);
1682
- continue;
1683
- }
1684
-
1685
- // top-level paragraph
1686
- // prevent paragraph consuming extensions by clipping 'src' to extension start
1687
- cutSrc = src;
1688
- if (this.options.extensions && this.options.extensions.startBlock) {
1689
- let startIndex = Infinity;
1690
- const tempSrc = src.slice(1);
1691
- let tempStart;
1692
- this.options.extensions.startBlock.forEach(function(getStartIndex) {
1693
- tempStart = getStartIndex.call({ lexer: this }, tempSrc);
1694
- if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
1695
- });
1696
- if (startIndex < Infinity && startIndex >= 0) {
1697
- cutSrc = src.substring(0, startIndex + 1);
1698
- }
1699
- }
1700
- if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1701
- lastToken = tokens[tokens.length - 1];
1702
- if (lastParagraphClipped && lastToken.type === 'paragraph') {
1703
- lastToken.raw += '\n' + token.raw;
1704
- lastToken.text += '\n' + token.text;
1705
- this.inlineQueue.pop();
1706
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1707
- } else {
1708
- tokens.push(token);
1709
- }
1710
- lastParagraphClipped = (cutSrc.length !== src.length);
1711
- src = src.substring(token.raw.length);
1712
- continue;
1713
- }
1714
-
1715
- // text
1716
- if (token = this.tokenizer.text(src)) {
1717
- src = src.substring(token.raw.length);
1718
- lastToken = tokens[tokens.length - 1];
1719
- if (lastToken && lastToken.type === 'text') {
1720
- lastToken.raw += '\n' + token.raw;
1721
- lastToken.text += '\n' + token.text;
1722
- this.inlineQueue.pop();
1723
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1724
- } else {
1725
- tokens.push(token);
1726
- }
1727
- continue;
1728
- }
1729
-
1730
- if (src) {
1731
- const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1732
- if (this.options.silent) {
1733
- console.error(errMsg);
1734
- break;
1735
- } else {
1736
- throw new Error(errMsg);
1737
- }
1738
- }
1739
- }
1740
-
1741
- this.state.top = true;
1742
- return tokens;
1743
- }
1744
-
1745
- inline(src, tokens = []) {
1746
- this.inlineQueue.push({ src, tokens });
1747
- return tokens;
1748
- }
1749
-
1750
- /**
1751
- * Lexing/Compiling
1752
- */
1753
- inlineTokens(src, tokens = []) {
1754
- let token, lastToken, cutSrc;
1755
-
1756
- // String with links masked to avoid interference with em and strong
1757
- let maskedSrc = src;
1758
- let match;
1759
- let keepPrevChar, prevChar;
1760
-
1761
- // Mask out reflinks
1762
- if (this.tokens.links) {
1763
- const links = Object.keys(this.tokens.links);
1764
- if (links.length > 0) {
1765
- while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
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);
1768
- }
1769
- }
1770
- }
1771
- }
1772
- // Mask out other blocks
1773
- while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
1774
- maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
1775
- }
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--;
1781
- }
1782
-
1783
- while (src) {
1784
- if (!keepPrevChar) {
1785
- prevChar = '';
1786
- }
1787
- keepPrevChar = false;
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
- })) {
1800
- continue;
1801
- }
1802
-
1803
- // escape
1804
- if (token = this.tokenizer.escape(src)) {
1805
- src = src.substring(token.raw.length);
1806
- tokens.push(token);
1807
- continue;
1808
- }
1809
-
1810
- // tag
1811
- if (token = this.tokenizer.tag(src)) {
1812
- src = src.substring(token.raw.length);
1813
- lastToken = tokens[tokens.length - 1];
1814
- if (lastToken && token.type === 'text' && lastToken.type === 'text') {
1815
- lastToken.raw += token.raw;
1816
- lastToken.text += token.text;
1817
- } else {
1818
- tokens.push(token);
1819
- }
1820
- continue;
1821
- }
1822
-
1823
- // link
1824
- if (token = this.tokenizer.link(src)) {
1825
- src = src.substring(token.raw.length);
1826
- tokens.push(token);
1827
- continue;
1828
- }
1829
-
1830
- // reflink, nolink
1831
- if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1832
- src = src.substring(token.raw.length);
1833
- lastToken = tokens[tokens.length - 1];
1834
- if (lastToken && token.type === 'text' && lastToken.type === 'text') {
1835
- lastToken.raw += token.raw;
1836
- lastToken.text += token.text;
1837
- } else {
1838
- tokens.push(token);
1839
- }
1840
- continue;
1841
- }
1842
-
1843
- // em & strong
1844
- if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
1845
- src = src.substring(token.raw.length);
1846
- tokens.push(token);
1847
- continue;
1848
- }
1849
-
1850
- // code
1851
- if (token = this.tokenizer.codespan(src)) {
1852
- src = src.substring(token.raw.length);
1853
- tokens.push(token);
1854
- continue;
1855
- }
1856
-
1857
- // br
1858
- if (token = this.tokenizer.br(src)) {
1859
- src = src.substring(token.raw.length);
1860
- tokens.push(token);
1861
- continue;
1862
- }
1863
-
1864
- // del (gfm)
1865
- if (token = this.tokenizer.del(src)) {
1866
- src = src.substring(token.raw.length);
1867
- tokens.push(token);
1868
- continue;
1869
- }
1870
-
1871
- // autolink
1872
- if (token = this.tokenizer.autolink(src, mangle)) {
1873
- src = src.substring(token.raw.length);
1874
- tokens.push(token);
1875
- continue;
1876
- }
1877
-
1878
- // url (gfm)
1879
- if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
1880
- src = src.substring(token.raw.length);
1881
- tokens.push(token);
1882
- continue;
1883
- }
1884
-
1885
- // text
1886
- // prevent inlineText consuming extensions by clipping 'src' to extension start
1887
- cutSrc = src;
1888
- if (this.options.extensions && this.options.extensions.startInline) {
1889
- let startIndex = Infinity;
1890
- const tempSrc = src.slice(1);
1891
- let tempStart;
1892
- this.options.extensions.startInline.forEach(function(getStartIndex) {
1893
- tempStart = getStartIndex.call({ lexer: this }, tempSrc);
1894
- if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
1895
- });
1896
- if (startIndex < Infinity && startIndex >= 0) {
1897
- cutSrc = src.substring(0, startIndex + 1);
1898
- }
1899
- }
1900
- if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
1901
- src = src.substring(token.raw.length);
1902
- if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
1903
- prevChar = token.raw.slice(-1);
1904
- }
1905
- keepPrevChar = true;
1906
- lastToken = tokens[tokens.length - 1];
1907
- if (lastToken && lastToken.type === 'text') {
1908
- lastToken.raw += token.raw;
1909
- lastToken.text += token.text;
1910
- } else {
1911
- tokens.push(token);
1912
- }
1913
- continue;
1914
- }
1915
-
1916
- if (src) {
1917
- const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1918
- if (this.options.silent) {
1919
- console.error(errMsg);
1920
- break;
1921
- } else {
1922
- throw new Error(errMsg);
1923
- }
1924
- }
1925
- }
1926
-
1927
- return tokens;
1928
- }
1929
- }
1930
-
1931
- /**
1932
- * Renderer
1933
- */
1934
- class Renderer {
1935
- constructor(options) {
1936
- this.options = options || defaults;
1937
- }
1938
-
1939
- code(code, infostring, escaped) {
1940
- const lang = (infostring || '').match(/\S*/)[0];
1941
- if (this.options.highlight) {
1942
- const out = this.options.highlight(code, lang);
1943
- if (out != null && out !== code) {
1944
- escaped = true;
1945
- code = out;
1946
- }
1947
- }
1948
-
1949
- code = code.replace(/\n$/, '') + '\n';
1950
-
1951
- if (!lang) {
1952
- return '<pre><code>'
1953
- + (escaped ? code : escape(code, true))
1954
- + '</code></pre>\n';
1955
- }
1956
-
1957
- return '<pre><code class="'
1958
- + this.options.langPrefix
1959
- + escape(lang)
1960
- + '">'
1961
- + (escaped ? code : escape(code, true))
1962
- + '</code></pre>\n';
1963
- }
1964
-
1965
- /**
1966
- * @param {string} quote
1967
- */
1968
- blockquote(quote) {
1969
- return `<blockquote>\n${quote}</blockquote>\n`;
1970
- }
1971
-
1972
- html(html) {
1973
- return html;
1974
- }
1975
-
1976
- /**
1977
- * @param {string} text
1978
- * @param {string} level
1979
- * @param {string} raw
1980
- * @param {any} slugger
1981
- */
1982
- heading(text, level, raw, slugger) {
1983
- if (this.options.headerIds) {
1984
- const id = this.options.headerPrefix + slugger.slug(raw);
1985
- return `<h${level} id="${id}">${text}</h${level}>\n`;
1986
- }
1987
-
1988
- // ignore IDs
1989
- return `<h${level}>${text}</h${level}>\n`;
1990
- }
1991
-
1992
- hr() {
1993
- return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
1994
- }
1995
-
1996
- list(body, ordered, start) {
1997
- const type = ordered ? 'ol' : 'ul',
1998
- startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1999
- return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
2000
- }
2001
-
2002
- /**
2003
- * @param {string} text
2004
- */
2005
- listitem(text) {
2006
- return `<li>${text}</li>\n`;
2007
- }
2008
-
2009
- checkbox(checked) {
2010
- return '<input '
2011
- + (checked ? 'checked="" ' : '')
2012
- + 'disabled="" type="checkbox"'
2013
- + (this.options.xhtml ? ' /' : '')
2014
- + '> ';
2015
- }
2016
-
2017
- /**
2018
- * @param {string} text
2019
- */
2020
- paragraph(text) {
2021
- return `<p>${text}</p>\n`;
2022
- }
2023
-
2024
- /**
2025
- * @param {string} header
2026
- * @param {string} body
2027
- */
2028
- table(header, body) {
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';
2037
- }
2038
-
2039
- /**
2040
- * @param {string} content
2041
- */
2042
- tablerow(content) {
2043
- return `<tr>\n${content}</tr>\n`;
2044
- }
2045
-
2046
- tablecell(content, flags) {
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`;
2052
- }
2053
-
2054
- /**
2055
- * span level renderer
2056
- * @param {string} text
2057
- */
2058
- strong(text) {
2059
- return `<strong>${text}</strong>`;
2060
- }
2061
-
2062
- /**
2063
- * @param {string} text
2064
- */
2065
- em(text) {
2066
- return `<em>${text}</em>`;
2067
- }
2068
-
2069
- /**
2070
- * @param {string} text
2071
- */
2072
- codespan(text) {
2073
- return `<code>${text}</code>`;
2074
- }
2075
-
2076
- br() {
2077
- return this.options.xhtml ? '<br/>' : '<br>';
2078
- }
2079
-
2080
- /**
2081
- * @param {string} text
2082
- */
2083
- del(text) {
2084
- return `<del>${text}</del>`;
2085
- }
2086
-
2087
- /**
2088
- * @param {string} href
2089
- * @param {string} title
2090
- * @param {string} text
2091
- */
2092
- link(href, title, text) {
2093
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
2094
- if (href === null) {
2095
- return text;
2096
- }
2097
- let out = '<a href="' + href + '"';
2098
- if (title) {
2099
- out += ' title="' + title + '"';
2100
- }
2101
- out += '>' + text + '</a>';
2102
- return out;
2103
- }
2104
-
2105
- /**
2106
- * @param {string} href
2107
- * @param {string} title
2108
- * @param {string} text
2109
- */
2110
- image(href, title, text) {
2111
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
2112
- if (href === null) {
2113
- return text;
2114
- }
2115
-
2116
- let out = `<img src="${href}" alt="${text}"`;
2117
- if (title) {
2118
- out += ` title="${title}"`;
2119
- }
2120
- out += this.options.xhtml ? '/>' : '>';
2121
- return out;
2122
- }
2123
-
2124
- text(text) {
2125
- return text;
2126
- }
2127
- }
2128
-
2129
- /**
2130
- * TextRenderer
2131
- * returns only the textual part of the token
2132
- */
2133
- class TextRenderer {
2134
- // no need for block level renderers
2135
- strong(text) {
2136
- return text;
2137
- }
2138
-
2139
- em(text) {
2140
- return text;
2141
- }
2142
-
2143
- codespan(text) {
2144
- return text;
2145
- }
2146
-
2147
- del(text) {
2148
- return text;
2149
- }
2150
-
2151
- html(text) {
2152
- return text;
2153
- }
2154
-
2155
- text(text) {
2156
- return text;
2157
- }
2158
-
2159
- link(href, title, text) {
2160
- return '' + text;
2161
- }
2162
-
2163
- image(href, title, text) {
2164
- return '' + text;
2165
- }
2166
-
2167
- br() {
2168
- return '';
2169
- }
2170
- }
2171
-
2172
- /**
2173
- * Slugger generates header id
2174
- */
2175
- class Slugger {
2176
- constructor() {
2177
- this.seen = {};
2178
- }
2179
-
2180
- /**
2181
- * @param {string} value
2182
- */
2183
- serialize(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, '-');
2192
- }
2193
-
2194
- /**
2195
- * Finds the next safe (unique) slug to use
2196
- * @param {string} originalSlug
2197
- * @param {boolean} isDryRun
2198
- */
2199
- getNextSafeSlug(originalSlug, isDryRun) {
2200
- let slug = originalSlug;
2201
- let occurenceAccumulator = 0;
2202
- if (this.seen.hasOwnProperty(slug)) {
2203
- occurenceAccumulator = this.seen[originalSlug];
2204
- do {
2205
- occurenceAccumulator++;
2206
- slug = originalSlug + '-' + occurenceAccumulator;
2207
- } while (this.seen.hasOwnProperty(slug));
2208
- }
2209
- if (!isDryRun) {
2210
- this.seen[originalSlug] = occurenceAccumulator;
2211
- this.seen[slug] = 0;
2212
- }
2213
- return slug;
2214
- }
2215
-
2216
- /**
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.
2221
- */
2222
- slug(value, options = {}) {
2223
- const slug = this.serialize(value);
2224
- return this.getNextSafeSlug(slug, options.dryrun);
2225
- }
2226
- }
2227
-
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();
2235
- this.renderer = this.options.renderer;
2236
- this.renderer.options = this.options;
2237
- this.textRenderer = new TextRenderer();
2238
- this.slugger = new Slugger();
2239
- }
2240
-
2241
- /**
2242
- * Static Parse Method
2243
- */
2244
- static parse(tokens, options) {
2245
- const parser = new Parser(options);
2246
- return parser.parse(tokens);
2247
- }
2248
-
2249
- /**
2250
- * Static Parse Inline Method
2251
- */
2252
- static parseInline(tokens, options) {
2253
- const parser = new Parser(options);
2254
- return parser.parseInline(tokens);
2255
- }
2256
-
2257
- /**
2258
- * Parse Loop
2259
- */
2260
- parse(tokens, top = true) {
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
-
2282
- const l = tokens.length;
2283
- for (i = 0; i < l; i++) {
2284
- token = tokens[i];
2285
-
2286
- // Run any renderer extensions
2287
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2288
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2289
- if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
2290
- out += ret || '';
2291
- continue;
2292
- }
2293
- }
2294
-
2295
- switch (token.type) {
2296
- case 'space': {
2297
- continue;
2298
- }
2299
- case 'hr': {
2300
- out += this.renderer.hr();
2301
- continue;
2302
- }
2303
- case 'heading': {
2304
- out += this.renderer.heading(
2305
- this.parseInline(token.tokens),
2306
- token.depth,
2307
- unescape(this.parseInline(token.tokens, this.textRenderer)),
2308
- this.slugger);
2309
- continue;
2310
- }
2311
- case 'code': {
2312
- out += this.renderer.code(token.text,
2313
- token.lang,
2314
- token.escaped);
2315
- continue;
2316
- }
2317
- case 'table': {
2318
- header = '';
2319
-
2320
- // header
2321
- cell = '';
2322
- l2 = token.header.length;
2323
- for (j = 0; j < l2; j++) {
2324
- cell += this.renderer.tablecell(
2325
- this.parseInline(token.header[j].tokens),
2326
- { header: true, align: token.align[j] }
2327
- );
2328
- }
2329
- header += this.renderer.tablerow(cell);
2330
-
2331
- body = '';
2332
- l2 = token.rows.length;
2333
- for (j = 0; j < l2; j++) {
2334
- row = token.rows[j];
2335
-
2336
- cell = '';
2337
- l3 = row.length;
2338
- for (k = 0; k < l3; k++) {
2339
- cell += this.renderer.tablecell(
2340
- this.parseInline(row[k].tokens),
2341
- { header: false, align: token.align[k] }
2342
- );
2343
- }
2344
-
2345
- body += this.renderer.tablerow(cell);
2346
- }
2347
- out += this.renderer.table(header, body);
2348
- continue;
2349
- }
2350
- case 'blockquote': {
2351
- body = this.parse(token.tokens);
2352
- out += this.renderer.blockquote(body);
2353
- continue;
2354
- }
2355
- case 'list': {
2356
- ordered = token.ordered;
2357
- start = token.start;
2358
- loose = token.loose;
2359
- l2 = token.items.length;
2360
-
2361
- body = '';
2362
- for (j = 0; j < l2; j++) {
2363
- item = token.items[j];
2364
- checked = item.checked;
2365
- task = item.task;
2366
-
2367
- itemBody = '';
2368
- if (item.task) {
2369
- checkbox = this.renderer.checkbox(checked);
2370
- if (loose) {
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;
2375
- }
2376
- } else {
2377
- item.tokens.unshift({
2378
- type: 'text',
2379
- text: checkbox
2380
- });
2381
- }
2382
- } else {
2383
- itemBody += checkbox;
2384
- }
2385
- }
2386
-
2387
- itemBody += this.parse(item.tokens, loose);
2388
- body += this.renderer.listitem(itemBody, task, checked);
2389
- }
2390
-
2391
- out += this.renderer.list(body, ordered, start);
2392
- continue;
2393
- }
2394
- case 'html': {
2395
- // TODO parse inline content if parameter markdown=1
2396
- out += this.renderer.html(token.text);
2397
- continue;
2398
- }
2399
- case 'paragraph': {
2400
- out += this.renderer.paragraph(this.parseInline(token.tokens));
2401
- continue;
2402
- }
2403
- case 'text': {
2404
- body = token.tokens ? this.parseInline(token.tokens) : token.text;
2405
- while (i + 1 < l && tokens[i + 1].type === 'text') {
2406
- token = tokens[++i];
2407
- body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
2408
- }
2409
- out += top ? this.renderer.paragraph(body) : body;
2410
- continue;
2411
- }
2412
-
2413
- default: {
2414
- const errMsg = 'Token with "' + token.type + '" type was not found.';
2415
- if (this.options.silent) {
2416
- console.error(errMsg);
2417
- return;
2418
- } else {
2419
- throw new Error(errMsg);
2420
- }
2421
- }
2422
- }
2423
- }
2424
-
2425
- return out;
2426
- }
2427
-
2428
- /**
2429
- * Parse Inline Tokens
2430
- */
2431
- parseInline(tokens, renderer) {
2432
- renderer = renderer || this.renderer;
2433
- let out = '',
2434
- i,
2435
- token,
2436
- ret;
2437
-
2438
- const l = tokens.length;
2439
- for (i = 0; i < l; i++) {
2440
- token = tokens[i];
2441
-
2442
- // Run any renderer extensions
2443
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2444
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2445
- if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
2446
- out += ret || '';
2447
- continue;
2448
- }
2449
- }
2450
-
2451
- switch (token.type) {
2452
- case 'escape': {
2453
- out += renderer.text(token.text);
2454
- break;
2455
- }
2456
- case 'html': {
2457
- out += renderer.html(token.text);
2458
- break;
2459
- }
2460
- case 'link': {
2461
- out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
2462
- break;
2463
- }
2464
- case 'image': {
2465
- out += renderer.image(token.href, token.title, token.text);
2466
- break;
2467
- }
2468
- case 'strong': {
2469
- out += renderer.strong(this.parseInline(token.tokens, renderer));
2470
- break;
2471
- }
2472
- case 'em': {
2473
- out += renderer.em(this.parseInline(token.tokens, renderer));
2474
- break;
2475
- }
2476
- case 'codespan': {
2477
- out += renderer.codespan(token.text);
2478
- break;
2479
- }
2480
- case 'br': {
2481
- out += renderer.br();
2482
- break;
2483
- }
2484
- case 'del': {
2485
- out += renderer.del(this.parseInline(token.tokens, renderer));
2486
- break;
2487
- }
2488
- case 'text': {
2489
- out += renderer.text(token.text);
2490
- break;
2491
- }
2492
- default: {
2493
- const errMsg = 'Token with "' + token.type + '" type was not found.';
2494
- if (this.options.silent) {
2495
- console.error(errMsg);
2496
- return;
2497
- } else {
2498
- throw new Error(errMsg);
2499
- }
2500
- }
2501
- }
2502
- }
2503
- return out;
2504
- }
2505
- }
2506
-
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');
2514
- }
2515
- if (typeof src !== 'string') {
2516
- throw new Error('marked(): input parameter is of type '
2517
- + Object.prototype.toString.call(src) + ', string expected');
2518
- }
2519
-
2520
- if (typeof opt === 'function') {
2521
- callback = opt;
2522
- opt = null;
2523
- }
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);
2545
- }
2546
- out = Parser.parse(tokens, opt);
2547
- } catch (e) {
2548
- err = e;
2549
- }
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();
2561
- }
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);
2575
- }
2576
- if (code != null && code !== token.text) {
2577
- token.text = code;
2578
- token.escaped = true;
2579
- }
2580
-
2581
- pending--;
2582
- if (pending === 0) {
2583
- done();
2584
- }
2585
- });
2586
- }, 0);
2587
- }
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);
2666
- if (ret === false) {
2667
- ret = prevRenderer.apply(this, args);
2668
- }
2669
- return ret;
2670
- };
2671
- } else {
2672
- extensions.renderers[ext.name] = ext.renderer;
2673
- }
2674
- }
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'");
2678
- }
2679
- if (extensions[ext.level]) {
2680
- extensions[ext.level].unshift(ext.tokenizer);
2681
- } else {
2682
- extensions[ext.level] = [ext.tokenizer];
2683
- }
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];
2690
- }
2691
- } else if (ext.level === 'inline') {
2692
- if (extensions.startInline) {
2693
- extensions.startInline.push(ext.start);
2694
- } else {
2695
- extensions.startInline = [ext.start];
2696
- }
2697
- }
2698
- }
2699
- }
2700
- if (ext.childTokens) { // Child tokens to be visited by walkTokens
2701
- extensions.childTokens[ext.name] = ext.childTokens;
2702
- }
2703
- });
2704
- opts.extensions = extensions;
2705
- }
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
- };
2720
- }
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
- };
2735
- }
2736
- opts.tokenizer = tokenizer;
2737
- }
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
- });
2754
- };
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;
2779
- }
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
- }
2788
- }
2789
- }
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);
2815
- }
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>';
2823
- }
2824
- throw e;
2825
- }
2826
- };
2827
-
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;
2839
- marked.parse = marked;
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
-
2852
-
2853
- /***/ })
2854
-
2855
- }]);