UNPKG

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