UNPKG

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