UNPKG

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