UNPKG

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