UNPKG

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