UNPKG

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