UNPKG

28.5 kBJavaScriptView Raw
1function merge(obj) {
2 var arguments$1 = arguments;
3
4 var i = 1;
5 var target;
6 var key;
7
8 for (; i < arguments.length; i++) {
9 target = arguments$1[i];
10 for (key in target) {
11 if (Object.prototype.hasOwnProperty.call(target, key)) {
12 obj[key] = target[key];
13 }
14 }
15 }
16
17 return obj
18}
19
20function noop() {}
21noop.exec = noop;
22
23function escape$1(html, encode) {
24 return html
25 .replace(encode ? /&/g : /&(?!#?\w+;)/g, '&amp;')
26 .replace(/</g, '&lt;')
27 .replace(/>/g, '&gt;')
28 .replace(/"/g, '&quot;')
29 .replace(/'/g, '&#39;')
30}
31
32function unescape(html) {
33 // explicitly match decimal, hex, and named HTML entities
34 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function (_, n) {
35 n = n.toLowerCase();
36 if (n === 'colon') { return ':' }
37 if (n.charAt(0) === '#') {
38 return n.charAt(1) === 'x' ?
39 String.fromCharCode(parseInt(n.substring(2), 16)) :
40 String.fromCharCode(Number(n.substring(1)))
41 }
42 return ''
43 })
44}
45
46function replace(regex, opt) {
47 regex = regex.source;
48 opt = opt || '';
49 return function self(name, val) {
50 if (!name) { return new RegExp(regex, opt) }
51 val = val.source || val;
52 val = val.replace(/(^|[^\[])\^/g, '$1');
53 regex = regex.replace(name, val);
54 return self
55 }
56}
57
58function slugify(input) {
59 return input
60 // remove html tags
61 .replace(/<(?:.|\n)*?>/gm, '')
62 .replace(/[!\"#$%&'\(\)\*\+,\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '') // eslint-disable-line no-useless-escape
63 // Replace dots and spaces with a sepeator
64 .replace(/(\s|\.)/g, '-')
65 // Convert 2 or more sepeators into just one sepeator
66 .replace(/-{2,}/g, '-')
67 // Make the whole thing lowercase
68 .toLowerCase()
69}
70
71var Renderer = function Renderer(options) {
72 this.options = options || {};
73 this._headings = [];
74};
75
76Renderer.prototype.code = function code (code$1, lang, escaped) {
77 if (this.options.highlight) {
78 var out = this.options.highlight(code$1, lang);
79 if (out !== null && out !== code$1) {
80 escaped = true;
81 code$1 = out;
82 }
83 }
84
85 if (!lang) {
86 return ("<pre><code>" + (escaped ? code$1 : escape$1(code$1, true)) + "\n</code></pre>")
87 }
88
89 return ("<pre><code class=\"" + (this.options.langPrefix) + (escape$1(lang, true)) + "\">" + (escaped ? code$1 : escape$1(code$1, true)) + "\n</code></pre>\n")
90};
91
92Renderer.prototype.blockquote = function blockquote (quote) {
93 return ("<blockquote>\n" + quote + "</blockquote>\n")
94};
95
96Renderer.prototype.html = function html (html$1) {
97 return html$1
98};
99
100Renderer.prototype.heading = function heading (text, level, raw) {
101 var slug = slugify(raw);
102 var count = this._headings.filter(function (h) { return h === raw; }).length;
103 if (count > 0) {
104 slug += "-" + count;
105 }
106 this._headings.push(raw);
107 return ("<h" + level + " id=\"" + (this.options.headerPrefix) + slug + "\">" + text + "</h" + level + ">\n")
108};
109
110Renderer.prototype.hr = function hr () {
111 return this.options.xhtml ? '<hr/>\n' : '<hr>\n'
112};
113
114Renderer.prototype.list = function list (body, ordered, taskList) {
115 var type = ordered ? 'ol' : 'ul';
116 var classNames = taskList ? ' class="task-list"' : '';
117 return ("<" + type + classNames + ">\n" + body + "</" + type + ">\n")
118};
119
120Renderer.prototype.listitem = function listitem (text, checked) {
121 if (checked === undefined) {
122 return ("<li>" + text + "</li>\n")
123 }
124
125 return '<li class="task-list-item">' +
126 '<input type="checkbox" class="task-list-item-checkbox"' +
127 (checked ? ' checked' : '') +
128 '> ' +
129 text +
130 '</li>\n'
131};
132
133Renderer.prototype.paragraph = function paragraph (text) {
134 return ("<p>" + text + "</p>\n")
135};
136
137Renderer.prototype.table = function table (header, body) {
138 return ("<table>\n<thead>\n" + header + "</thead>\n<tbody>\n" + body + "</tbody>\n</table>\n")
139};
140
141Renderer.prototype.tablerow = function tablerow (content) {
142 return ("<tr>\n" + content + "</tr>\n")
143};
144
145Renderer.prototype.tablecell = function tablecell (content, flags) {
146 var type = flags.header ? 'th' : 'td';
147 var tag = flags.align ?
148 ("<" + type + " style=\"text-align:" + (flags.align) + "\">") :
149 ("<" + type + ">");
150 return ((tag + content) + "</" + type + ">\n")
151};
152
153// span level renderer
154Renderer.prototype.strong = function strong (text) {
155 return ("<strong>" + text + "</strong>")
156};
157
158Renderer.prototype.em = function em (text) {
159 return ("<em>" + text + "</em>")
160};
161
162Renderer.prototype.codespan = function codespan (text) {
163 return ("<code>" + text + "</code>")
164};
165
166Renderer.prototype.br = function br () {
167 return this.options.xhtml ? '<br/>' : '<br>'
168};
169
170Renderer.prototype.del = function del (text) {
171 return ("<del>" + text + "</del>")
172};
173
174Renderer.prototype.link = function link (href, title, text) {
175 if (this.options.sanitize) {
176 var prot;
177 try {
178 prot = decodeURIComponent(unescape(href))
179 .replace(/[^\w:]/g, '')
180 .toLowerCase();
181 } catch (err) {
182 return ''
183 }
184 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { // eslint-disable-line no-script-url
185 return ''
186 }
187 }
188 var out = "<a href=\"" + href + "\"";
189 if (title) {
190 out += " title=\"" + title + "\"";
191 }
192 out += ">" + text + "</a>";
193 return out
194};
195
196Renderer.prototype.image = function image (href, title, text) {
197 var out = "<img src=\"" + href + "\" alt=\"" + text + "\"";
198 if (title) {
199 out += " title=\"" + title + "\"";
200 }
201 out += this.options.xhtml ? '/>' : '>';
202 return out
203};
204
205Renderer.prototype.text = function text (text$1) {
206 return text$1
207};
208
209var defaultOptions = {
210 gfm: true,
211 tables: true,
212 taskLists: true,
213 breaks: false,
214 pedantic: false,
215 sanitize: false,
216 sanitizer: null,
217 mangle: true,
218 smartLists: false,
219 silent: false,
220 highlight: null,
221 langPrefix: 'lang-',
222 smartypants: false,
223 headerPrefix: '',
224 renderer: new Renderer(),
225 xhtml: false
226};
227
228/**
229 * Inline-Level Grammar
230 */
231
232var inline = {
233 escape: /^\\([\\`*{}[\]()#+\-.!_>])/,
234 autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
235 url: noop,
236 tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
237 link: /^!?\[(inside)\]\(href\)/,
238 reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
239 nolink: /^!?\[((?:\[[^\]]*\]|[^[\]])*)\]/,
240 strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
241 em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
242 code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
243 br: /^ {2,}\n(?!\s*$)/,
244 del: noop,
245 text: /^[\s\S]+?(?=[\\<![_*`]| {2,}\n|$)/
246};
247
248inline._inside = /(?:\[[^\]]*\]|[^[\]]|\](?=[^[]*\]))*/;
249inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
250
251inline.link = replace(inline.link)
252 ('inside', inline._inside)
253 ('href', inline._href)
254 ();
255
256inline.reflink = replace(inline.reflink)
257 ('inside', inline._inside)
258 ();
259
260/**
261 * Normal Inline Grammar
262 */
263
264inline.normal = merge ({}, inline);
265
266/**
267 * Pedantic Inline Grammar
268 */
269
270inline.pedantic = merge ({}, inline.normal, {
271 strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
272 em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
273});
274
275/**
276 * GFM Inline Grammar
277 */
278
279inline.gfm = merge ({}, inline.normal, {
280 escape: replace(inline.escape) ('])', '~|])') (),
281 url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
282 del: /^~~(?=\S)([\s\S]*?\S)~~/,
283 text: replace(inline.text)
284 (']|', '~]|')
285 ('|', '|https?://|')
286 ()
287});
288
289/**
290 * GFM + Line Breaks Inline Grammar
291 */
292
293inline.breaks = merge ({}, inline.gfm, {
294 br: replace(inline.br) ('{2,}', '*') (),
295 text: replace(inline.gfm.text) ('{2,}', '*') ()
296});
297
298var InlineLexer = function InlineLexer(links, options) {
299 if ( options === void 0 ) options = defaultOptions;
300
301 this.options = options;
302 this.links = links;
303 this.renderer = this.options.renderer || new Renderer();
304 this.renderer.options = this.options;
305
306 if (!this.links) {
307 throw new Error('Tokens array requires a `links` property.')
308 }
309
310 if (this.options.gfm) {
311 if (this.options.breaks) {
312 this.rules = inline.breaks;
313 } else {
314 this.rules = inline.gfm;
315 }
316 } else if (this.options.pedantic) {
317 this.rules = inline.pedantic;
318 } else {
319 this.rules = inline.normal;
320 }
321};
322
323InlineLexer.output = function output (src, links, options) {
324 return new InlineLexer(links, options).output(src)
325};
326
327InlineLexer.prototype.output = function output (src) {
328 var this$1 = this;
329
330 var out = '';
331 var link;
332 var text;
333 var href;
334 var cap;
335
336 while (src) {
337 // escape
338 if (cap = this$1.rules.escape.exec(src)) {
339 src = src.substring(cap[0].length);
340 out += cap[1];
341 continue
342 }
343
344 // autolink
345 if (cap = this$1.rules.autolink.exec(src)) {
346 src = src.substring(cap[0].length);
347 if (cap[2] === '@') {
348 text = cap[1].charAt(6) === ':' ?
349 this$1.mangle(cap[1].substring(7)) :
350 this$1.mangle(cap[1]);
351 href = this$1.mangle('mailto:') + text;
352 } else {
353 text = escape$1(cap[1]);
354 href = text;
355 }
356 out += this$1.renderer.link(href, null, text);
357 continue
358 }
359
360 // url (gfm)
361 if (!this$1.inLink && (cap = this$1.rules.url.exec(src))) {
362 src = src.substring(cap[0].length);
363 text = escape$1(cap[1]);
364 href = text;
365 out += this$1.renderer.link(href, null, text);
366 continue
367 }
368
369 // tag
370 if (cap = this$1.rules.tag.exec(src)) {
371 if (!this$1.inLink && /^<a /i.test(cap[0])) {
372 this$1.inLink = true;
373 } else if (this$1.inLink && /^<\/a>/i.test(cap[0])) {
374 this$1.inLink = false;
375 }
376 src = src.substring(cap[0].length);
377 out += this$1.options.sanitize ?
378 this$1.options.sanitizer ?
379 this$1.options.sanitizer(cap[0]) :
380 escape$1(cap[0]) :
381 cap[0];
382 continue
383 }
384
385 // link
386 if (cap = this$1.rules.link.exec(src)) {
387 src = src.substring(cap[0].length);
388 this$1.inLink = true;
389 out += this$1.outputLink(cap, {
390 href: cap[2],
391 title: cap[3]
392 });
393 this$1.inLink = false;
394 continue
395 }
396
397 // reflink, nolink
398 if ((cap = this$1.rules.reflink.exec(src)) ||
399 (cap = this$1.rules.nolink.exec(src))) {
400 src = src.substring(cap[0].length);
401 link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
402 link = this$1.links[link.toLowerCase()];
403 if (!link || !link.href) {
404 out += cap[0].charAt(0);
405 src = cap[0].substring(1) + src;
406 continue
407 }
408 this$1.inLink = true;
409 out += this$1.outputLink(cap, link);
410 this$1.inLink = false;
411 continue
412 }
413
414 // strong
415 if (cap = this$1.rules.strong.exec(src)) {
416 src = src.substring(cap[0].length);
417 out += this$1.renderer.strong(this$1.output(cap[2] || cap[1]));
418 continue
419 }
420
421 // em
422 if (cap = this$1.rules.em.exec(src)) {
423 src = src.substring(cap[0].length);
424 out += this$1.renderer.em(this$1.output(cap[2] || cap[1]));
425 continue
426 }
427
428 // code
429 if (cap = this$1.rules.code.exec(src)) {
430 src = src.substring(cap[0].length);
431 out += this$1.renderer.codespan(escape$1(cap[2], true));
432 continue
433 }
434
435 // br
436 if (cap = this$1.rules.br.exec(src)) {
437 src = src.substring(cap[0].length);
438 out += this$1.renderer.br();
439 continue
440 }
441
442 // del (gfm)
443 if (cap = this$1.rules.del.exec(src)) {
444 src = src.substring(cap[0].length);
445 out += this$1.renderer.del(this$1.output(cap[1]));
446 continue
447 }
448
449 // text
450 if (cap = this$1.rules.text.exec(src)) {
451 src = src.substring(cap[0].length);
452 out += this$1.renderer.text(escape$1(this$1.smartypants(cap[0])));
453 continue
454 }
455
456 if (src) {
457 throw new Error('Infinite loop on byte: ' + src.charCodeAt(0))
458 }
459 }
460
461 return out
462};
463
464InlineLexer.prototype.outputLink = function outputLink (cap, link) {
465 var href = escape$1(link.href);
466 var title = link.title ? escape$1(link.title) : null;
467
468 return cap[0].charAt(0) === '!' ?
469 this.renderer.image(href, title, escape$1(cap[1])) :
470 this.renderer.link(href, title, this.output(cap[1]))
471};
472
473InlineLexer.prototype.smartypants = function smartypants (text) {
474 if (!this.options.smartypants) { return text }
475 return text
476 // em-dashes
477 .replace(/---/g, '\u2014')
478 // en-dashes
479 .replace(/--/g, '\u2013')
480 // opening singles
481 .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
482 // closing singles & apostrophes
483 .replace(/'/g, '\u2019')
484 // opening doubles
485 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
486 // closing doubles
487 .replace(/"/g, '\u201d')
488 // ellipses
489 .replace(/\.{3}/g, '\u2026')
490};
491
492InlineLexer.prototype.mangle = function mangle (text) {
493 if (!this.options.mangle) { return text }
494 var out = '';
495 var i = 0;
496 var ch;
497
498 for (; i < text.length; i++) {
499 ch = text.charCodeAt(i);
500 if (Math.random() > 0.5) {
501 ch = 'x' + ch.toString(16);
502 }
503 out += '&#' + ch + ';';
504 }
505
506 return out
507};
508
509InlineLexer.rules = inline;
510
511/**
512 * Parsing & Compiling
513 */
514
515var Parser = function Parser(options) {
516 if ( options === void 0 ) options = defaultOptions;
517
518 this.tokens = [];
519 this.token = null;
520 this.options = options;
521 this.options.renderer = this.options.renderer || new Renderer();
522 this.renderer = this.options.renderer;
523 this.renderer.options = this.options;
524};
525
526Parser.parse = function parse (src, options, renderer) {
527 return new Parser(options, renderer).parse(src)
528};
529
530/**
531 * Parse Loop
532 */
533
534Parser.prototype.parse = function parse (src) {
535 var this$1 = this;
536
537 this.inline = new InlineLexer(src.links, this.options, this.renderer);
538 this.tokens = src.reverse();
539
540 var out = '';
541 while (this.next()) {
542 out += this$1.tok();
543 }
544
545 // Remove cached headings
546 this.renderer._headings = [];
547 return out
548};
549
550/**
551 * Next Token
552 */
553
554Parser.prototype.next = function next () {
555 this.token = this.tokens.pop();
556 return this.token
557};
558
559/**
560 * Preview Next Token
561 */
562
563Parser.prototype.peek = function peek () {
564 return this.tokens[this.tokens.length - 1] || 0
565};
566
567/**
568 * Parse Text Tokens
569 */
570
571Parser.prototype.parseText = function parseText () {
572 var this$1 = this;
573
574 var body = this.token.text;
575
576 while (this.peek().type === 'text') {
577 body += "\n" + (this$1.next().text);
578 }
579
580 return this.inline.output(body)
581};
582
583/**
584 * Parse Current Token
585 */
586
587Parser.prototype.tok = function tok () {
588 var this$1 = this;
589
590 switch (this.token.type) {
591 case 'space': {
592 return ''
593 }
594 case 'hr': {
595 return this.renderer.hr()
596 }
597 case 'heading': {
598 return this.renderer.heading(
599 this.inline.output(this.token.text),
600 this.token.depth,
601 this.token.text)
602 }
603 case 'code': {
604 return this.renderer.code(this.token.text,
605 this.token.lang,
606 this.token.escaped)
607 }
608 case 'table': {
609 var header = '';
610 var body = '';
611 var i;
612 var row;
613 var cell;
614 var j;
615
616 // header
617 cell = '';
618 for (i = 0; i < this.token.header.length; i++) {
619 cell += this$1.renderer.tablecell(
620 this$1.inline.output(this$1.token.header[i]),
621 { header: true, align: this$1.token.align[i] }
622 );
623 }
624 header += this.renderer.tablerow(cell);
625
626 for (i = 0; i < this.token.cells.length; i++) {
627 row = this$1.token.cells[i];
628
629 cell = '';
630 for (j = 0; j < row.length; j++) {
631 cell += this$1.renderer.tablecell(
632 this$1.inline.output(row[j]),
633 { header: false, align: this$1.token.align[j] }
634 );
635 }
636
637 body += this$1.renderer.tablerow(cell);
638 }
639 return this.renderer.table(header, body)
640 }
641 case 'blockquote_start': {
642 var body$1 = '';
643
644 while (this.next().type !== 'blockquote_end') {
645 body$1 += this$1.tok();
646 }
647
648 return this.renderer.blockquote(body$1)
649 }
650 case 'list_start': {
651 var body$2 = '';
652 var taskList = false;
653 var ordered = this.token.ordered;
654
655 while (this.next().type !== 'list_end') {
656 if (this$1.token.checked !== undefined) {
657 taskList = true;
658 }
659 body$2 += this$1.tok();
660 }
661
662 return this.renderer.list(body$2, ordered, taskList)
663 }
664 case 'list_item_start': {
665 var body$3 = '';
666 var checked = this.token.checked;
667
668 while (this.next().type !== 'list_item_end') {
669 body$3 += this$1.token.type === 'text' ?
670 this$1.parseText() :
671 this$1.tok();
672 }
673
674 return this.renderer.listitem(body$3, checked)
675 }
676 case 'loose_item_start': {
677 var body$4 = '';
678 var checked$1 = this.token.checked;
679
680 while (this.next().type !== 'list_item_end') {
681 body$4 += this$1.tok();
682 }
683
684 return this.renderer.listitem(body$4, checked$1)
685 }
686 case 'html': {
687 var html = !this.token.pre && !this.options.pedantic ?
688 this.inline.output(this.token.text) :
689 this.token.text;
690 return this.renderer.html(html)
691 }
692 case 'paragraph': {
693 return this.renderer.paragraph(this.inline.output(this.token.text))
694 }
695 case 'text': {
696 return this.renderer.paragraph(this.parseText())
697 }
698 default: {
699 throw new Error('Unknow type')
700 }
701 }
702};
703
704var block = {
705 newline: /^\n+/,
706 code: /^( {4}[^\n]+\n*)+/,
707 fences: noop,
708 hr: /^( *[-*_]){3,} *(?:\n+|$)/,
709 heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
710 nptable: noop,
711 lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
712 blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
713 list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
714 html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
715 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
716 table: noop,
717 paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
718 text: /^[^\n]+/
719};
720
721block.bullet = /(?:[*+-]|\d+\.)/;
722block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
723block.item = replace(block.item, 'gm')
724 (/bull/g, block.bullet)
725 ();
726
727block.list = replace(block.list)
728 (/bull/g, block.bullet)
729 ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
730 ('def', '\\n+(?=' + block.def.source + ')')
731 ();
732
733block.blockquote = replace(block.blockquote)
734 ('def', block.def)
735 ();
736
737block._tag = '(?!(?:' +
738 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' +
739 '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' +
740 '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
741
742block.html = replace(block.html)
743 ('comment', /<!--[\s\S]*?-->/)
744 ('closed', /<(tag)[\s\S]+?<\/\1>/)
745 ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
746 (/tag/g, block._tag)
747 ();
748
749block.paragraph = replace(block.paragraph)
750 ('hr', block.hr)
751 ('heading', block.heading)
752 ('lheading', block.lheading)
753 ('blockquote', block.blockquote)
754 ('tag', '<' + block._tag)
755 ('def', block.def)
756 ();
757
758/**
759 * Normal Block Grammar
760 */
761
762block.normal = merge({}, block);
763
764/**
765 * GFM Block Grammar
766 */
767
768block.gfm = merge({}, block.normal, {
769 fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
770 paragraph: /^/,
771 heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/,
772 checkbox: /^\[([ x])\] +/
773});
774
775block.gfm.paragraph = replace(block.paragraph)
776 ('(?!', '(?!' +
777 block.gfm.fences.source.replace('\\1', '\\2') + '|' +
778 block.list.source.replace('\\1', '\\3') + '|')
779 ();
780
781/**
782 * GFM + Tables Block Grammar
783 */
784
785block.tables = merge({}, block.gfm, {
786 nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
787 table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
788});
789
790var Lexer = function Lexer(options) {
791 if ( options === void 0 ) options = defaultOptions;
792
793 this.tokens = [];
794 this.tokens.links = {};
795 this.options = options;
796
797 if (this.options.gfm) {
798 if (this.options.table) {
799 this.rules = block.table;
800 } else {
801 this.rules = block.gfm;
802 }
803 } else {
804 this.rules = block.normal;
805 }
806};
807
808Lexer.lex = function lex (src, options) {
809 return new Lexer(options).lex(src)
810};
811
812Lexer.prototype.lex = function lex (src) {
813 src = src
814 .replace(/\r\n|\r/g, '\n')
815 .replace(/\t/g, ' ')
816 .replace(/\u00a0/g, ' ')
817 .replace(/\u2424/g, '\n');
818
819 return this.token(src, true)
820};
821
822Lexer.prototype.token = function token (src, top, bq) {
823 var this$1 = this;
824
825 src = src.replace(/^ +$/gm, '');
826
827 var next;
828 var loose;
829 var cap;
830 var bull;
831 var b;
832 var item;
833 var space;
834 var i;
835 var l;
836 var checked;
837
838 while (src) {
839 // newline
840 if (cap = this$1.rules.newline.exec(src)) {
841 src = src.substring(cap[0].length);
842 if (cap[0].length > 1) {
843 this$1.tokens.push({
844 type: 'space'
845 });
846 }
847 }
848
849 // code
850 if (cap = this$1.rules.code.exec(src)) {
851 src = src.substring(cap[0].length);
852 cap = cap[0].replace(/^ {4}/gm, '');
853 this$1.tokens.push({
854 type: 'code',
855 text: this$1.options.pedantic ?
856 cap :
857 cap.replace(/\n+$/, '')
858 });
859 continue
860 }
861
862 // fences (gfm)
863 if (cap = this$1.rules.fences.exec(src)) {
864 src = src.substring(cap[0].length);
865 this$1.tokens.push({
866 type: 'code',
867 lang: cap[2],
868 text: cap[3] || ''
869 });
870 continue
871 }
872
873 // heading
874 if (cap = this$1.rules.heading.exec(src)) {
875 src = src.substring(cap[0].length);
876 this$1.tokens.push({
877 type: 'heading',
878 depth: cap[1].length,
879 text: cap[2]
880 });
881 continue
882 }
883
884 // table no leading pipe (gfm)
885 if (top && (cap = this$1.rules.nptable.exec(src))) {
886 src = src.substring(cap[0].length);
887
888 item = {
889 type: 'table',
890 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
891 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
892 cells: cap[3].replace(/\n$/, '').split('\n')
893 };
894
895 for (i = 0; i < item.align.length; i++) {
896 if (/^ *-+: *$/.test(item.align[i])) {
897 item.align[i] = 'right';
898 } else if (/^ *:-+: *$/.test(item.align[i])) {
899 item.align[i] = 'center';
900 } else if (/^ *:-+ *$/.test(item.align[i])) {
901 item.align[i] = 'left';
902 } else {
903 item.align[i] = null;
904 }
905 }
906
907 for (i = 0; i < item.cells.length; i++) {
908 item.cells[i] = item.cells[i].split(/ *\| */);
909 }
910
911 this$1.tokens.push(item);
912
913 continue
914 }
915
916 // lheading
917 if (cap = this$1.rules.lheading.exec(src)) {
918 src = src.substring(cap[0].length);
919 this$1.tokens.push({
920 type: 'heading',
921 depth: cap[2] === '=' ? 1 : 2,
922 text: cap[1]
923 });
924 continue
925 }
926
927 // hr
928 if (cap = this$1.rules.hr.exec(src)) {
929 src = src.substring(cap[0].length);
930 this$1.tokens.push({
931 type: 'hr'
932 });
933 continue
934 }
935
936 // blockquote
937 if (cap = this$1.rules.blockquote.exec(src)) {
938 src = src.substring(cap[0].length);
939
940 this$1.tokens.push({
941 type: 'blockquote_start'
942 });
943
944 cap = cap[0].replace(/^ *> ?/gm, '');
945
946 // Pass `top` to keep the current
947 // "toplevel" state. This is exactly
948 // how markdown.pl works.
949 this$1.token(cap, top, true);
950
951 this$1.tokens.push({
952 type: 'blockquote_end'
953 });
954
955 continue
956 }
957
958 // list
959 if (cap = this$1.rules.list.exec(src)) {
960 src = src.substring(cap[0].length);
961 bull = cap[2];
962
963 this$1.tokens.push({
964 type: 'list_start',
965 ordered: bull.length > 1
966 });
967
968 // Get each top-level item.
969 cap = cap[0].match(this$1.rules.item);
970
971 next = false;
972 l = cap.length;
973 i = 0;
974
975 for (; i < l; i++) {
976 item = cap[i];
977
978 // Remove the list item's bullet
979 // so it is seen as the next token.
980 space = item.length;
981 item = item.replace(/^ *([*+-]|\d+\.) +/, '');
982
983 if (this$1.options.gfm && this$1.options.taskLists) {
984 checked = this$1.rules.checkbox.exec(item);
985
986 if (checked) {
987 checked = checked[1] === 'x';
988 item = item.replace(this$1.rules.checkbox, '');
989 } else {
990 checked = undefined;
991 }
992 }
993
994 // Outdent whatever the
995 // list item contains. Hacky.
996 if (item.indexOf('\n ') !== -1) {
997 space -= item.length;
998 item = this$1.options.pedantic ?
999 item.replace(/^ {1,4}/gm, '') :
1000 item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '');
1001 }
1002
1003 // Determine whether the next list item belongs here.
1004 // Backpedal if it does not belong in this list.
1005 if (this$1.options.smartLists && i !== l - 1) {
1006 b = this$1.rules.bullet.exec(cap[i + 1])[0];
1007 if (bull !== b && !(bull.length > 1 && b.length > 1)) {
1008 src = cap.slice(i + 1).join('\n') + src;
1009 i = l - 1;
1010 }
1011 }
1012
1013 // Determine whether item is loose or not.
1014 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
1015 // for discount behavior.
1016 loose = next || /\n\n(?!\s*$)/.test(item);
1017 if (i !== l - 1) {
1018 next = item.charAt(item.length - 1) === '\n';
1019 if (!loose) { loose = next; }
1020 }
1021
1022 this$1.tokens.push({
1023 checked: checked,
1024 type: loose ?
1025 'loose_item_start' :
1026 'list_item_start'
1027 });
1028
1029 // Recurse.
1030 this$1.token(item, false, bq);
1031
1032 this$1.tokens.push({
1033 type: 'list_item_end'
1034 });
1035 }
1036
1037 this$1.tokens.push({
1038 type: 'list_end'
1039 });
1040
1041 continue
1042 }
1043
1044 // html
1045 if (cap = this$1.rules.html.exec(src)) {
1046 src = src.substring(cap[0].length);
1047 this$1.tokens.push({
1048 type: this$1.options.sanitize ?
1049 'paragraph' :
1050 'html',
1051 pre: !this$1.options.sanitizer &&
1052 (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
1053 text: cap[0]
1054 });
1055 continue
1056 }
1057
1058 // def
1059 if ((!bq && top) && (cap = this$1.rules.def.exec(src))) {
1060 src = src.substring(cap[0].length);
1061 this$1.tokens.links[cap[1].toLowerCase()] = {
1062 href: cap[2],
1063 title: cap[3]
1064 };
1065 continue
1066 }
1067
1068 // table (gfm)
1069 if (top && (cap = this$1.rules.table.exec(src))) {
1070 src = src.substring(cap[0].length);
1071
1072 item = {
1073 type: 'table',
1074 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
1075 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
1076 cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
1077 };
1078
1079 for (i = 0; i < item.align.length; i++) {
1080 if (/^ *-+: *$/.test(item.align[i])) {
1081 item.align[i] = 'right';
1082 } else if (/^ *:-+: *$/.test(item.align[i])) {
1083 item.align[i] = 'center';
1084 } else if (/^ *:-+ *$/.test(item.align[i])) {
1085 item.align[i] = 'left';
1086 } else {
1087 item.align[i] = null;
1088 }
1089 }
1090
1091 for (i = 0; i < item.cells.length; i++) {
1092 item.cells[i] = item.cells[i]
1093 .replace(/^ *\| *| *\| *$/g, '')
1094 .split(/ *\| */);
1095 }
1096
1097 this$1.tokens.push(item);
1098
1099 continue
1100 }
1101
1102 // top-level paragraph
1103 if (top && (cap = this$1.rules.paragraph.exec(src))) {
1104 src = src.substring(cap[0].length);
1105 this$1.tokens.push({
1106 type: 'paragraph',
1107 text: cap[1].charAt(cap[1].length - 1) === '\n' ?
1108 cap[1].slice(0, -1) :
1109 cap[1]
1110 });
1111 continue
1112 }
1113
1114 // text
1115 if (cap = this$1.rules.text.exec(src)) {
1116 // Top-level should never reach here.
1117 src = src.substring(cap[0].length);
1118 this$1.tokens.push({
1119 type: 'text',
1120 text: cap[0]
1121 });
1122 continue
1123 }
1124
1125 if (src) {
1126 throw new
1127 Error('Infinite loop on byte: ' + src.charCodeAt(0))
1128 }
1129 }
1130
1131 return this.tokens
1132};
1133
1134Lexer.rules = block;
1135
1136function marked3(src, opt) {
1137 try {
1138 if (opt) { opt = merge({}, defaultOptions, opt); }
1139 return Parser.parse(Lexer.lex(src, opt), opt)
1140 } catch (err) {
1141 err.message += '\nPlease report this to https://github.com/egoist/marked3.';
1142 if ((opt || defaultOptions).silent) {
1143 return '<p>An error occured:</p><pre>' +
1144 escape(String(err.message), true) +
1145 '</pre>'
1146 }
1147 throw err
1148 }
1149}
1150
1151marked3.Renderer = Renderer;
1152marked3.Parser = Parser;
1153marked3.Lexer = Lexer;
1154marked3.InlineLexer = InlineLexer;
1155
1156export default marked3;