marked 0.8.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/marked.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * marked - a markdown parser
3
- * Copyright (c) 2011-2019, Christopher Jeffrey. (MIT Licensed)
3
+ * Copyright (c) 2011-2020, Christopher Jeffrey. (MIT Licensed)
4
4
  * https://github.com/markedjs/marked
5
5
  */
6
6
 
@@ -31,6 +31,8 @@ function getDefaults() {
31
31
  silent: false,
32
32
  smartLists: false,
33
33
  smartypants: false,
34
+ tokenizer: null,
35
+ walkTokens: null,
34
36
  xhtml: false
35
37
  };
36
38
  }
@@ -293,6 +295,640 @@ var helpers = {
293
295
  checkSanitizeDeprecation
294
296
  };
295
297
 
298
+ const { defaults: defaults$1 } = defaults;
299
+ const {
300
+ rtrim: rtrim$1,
301
+ splitCells: splitCells$1,
302
+ escape: escape$1,
303
+ findClosingBracket: findClosingBracket$1
304
+ } = helpers;
305
+
306
+ function outputLink(cap, link, raw) {
307
+ const href = link.href;
308
+ const title = link.title ? escape$1(link.title) : null;
309
+
310
+ if (cap[0].charAt(0) !== '!') {
311
+ return {
312
+ type: 'link',
313
+ raw,
314
+ href,
315
+ title,
316
+ text: cap[1]
317
+ };
318
+ } else {
319
+ return {
320
+ type: 'image',
321
+ raw,
322
+ text: escape$1(cap[1]),
323
+ href,
324
+ title
325
+ };
326
+ }
327
+ }
328
+
329
+ function indentCodeCompensation(raw, text) {
330
+ const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
331
+
332
+ if (matchIndentToCode === null) {
333
+ return text;
334
+ }
335
+
336
+ const indentToCode = matchIndentToCode[1];
337
+
338
+ return text
339
+ .split('\n')
340
+ .map(node => {
341
+ const matchIndentInNode = node.match(/^\s+/);
342
+ if (matchIndentInNode === null) {
343
+ return node;
344
+ }
345
+
346
+ const [indentInNode] = matchIndentInNode;
347
+
348
+ if (indentInNode.length >= indentToCode.length) {
349
+ return node.slice(indentToCode.length);
350
+ }
351
+
352
+ return node;
353
+ })
354
+ .join('\n');
355
+ }
356
+
357
+ /**
358
+ * Tokenizer
359
+ */
360
+ var Tokenizer_1 = class Tokenizer {
361
+ constructor(options) {
362
+ this.options = options || defaults$1;
363
+ }
364
+
365
+ space(src) {
366
+ const cap = this.rules.block.newline.exec(src);
367
+ if (cap) {
368
+ if (cap[0].length > 1) {
369
+ return {
370
+ type: 'space',
371
+ raw: cap[0]
372
+ };
373
+ }
374
+ return { raw: '\n' };
375
+ }
376
+ }
377
+
378
+ code(src, tokens) {
379
+ const cap = this.rules.block.code.exec(src);
380
+ if (cap) {
381
+ const lastToken = tokens[tokens.length - 1];
382
+ // An indented code block cannot interrupt a paragraph.
383
+ if (lastToken && lastToken.type === 'paragraph') {
384
+ return {
385
+ raw: cap[0],
386
+ text: cap[0].trimRight()
387
+ };
388
+ }
389
+
390
+ const text = cap[0].replace(/^ {4}/gm, '');
391
+ return {
392
+ type: 'code',
393
+ raw: cap[0],
394
+ codeBlockStyle: 'indented',
395
+ text: !this.options.pedantic
396
+ ? rtrim$1(text, '\n')
397
+ : text
398
+ };
399
+ }
400
+ }
401
+
402
+ fences(src) {
403
+ const cap = this.rules.block.fences.exec(src);
404
+ if (cap) {
405
+ const raw = cap[0];
406
+ const text = indentCodeCompensation(raw, cap[3] || '');
407
+
408
+ return {
409
+ type: 'code',
410
+ raw,
411
+ lang: cap[2] ? cap[2].trim() : cap[2],
412
+ text
413
+ };
414
+ }
415
+ }
416
+
417
+ heading(src) {
418
+ const cap = this.rules.block.heading.exec(src);
419
+ if (cap) {
420
+ return {
421
+ type: 'heading',
422
+ raw: cap[0],
423
+ depth: cap[1].length,
424
+ text: cap[2]
425
+ };
426
+ }
427
+ }
428
+
429
+ nptable(src) {
430
+ const cap = this.rules.block.nptable.exec(src);
431
+ if (cap) {
432
+ const item = {
433
+ type: 'table',
434
+ header: splitCells$1(cap[1].replace(/^ *| *\| *$/g, '')),
435
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
436
+ cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [],
437
+ raw: cap[0]
438
+ };
439
+
440
+ if (item.header.length === item.align.length) {
441
+ let l = item.align.length;
442
+ let i;
443
+ for (i = 0; i < l; i++) {
444
+ if (/^ *-+: *$/.test(item.align[i])) {
445
+ item.align[i] = 'right';
446
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
447
+ item.align[i] = 'center';
448
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
449
+ item.align[i] = 'left';
450
+ } else {
451
+ item.align[i] = null;
452
+ }
453
+ }
454
+
455
+ l = item.cells.length;
456
+ for (i = 0; i < l; i++) {
457
+ item.cells[i] = splitCells$1(item.cells[i], item.header.length);
458
+ }
459
+
460
+ return item;
461
+ }
462
+ }
463
+ }
464
+
465
+ hr(src) {
466
+ const cap = this.rules.block.hr.exec(src);
467
+ if (cap) {
468
+ return {
469
+ type: 'hr',
470
+ raw: cap[0]
471
+ };
472
+ }
473
+ }
474
+
475
+ blockquote(src) {
476
+ const cap = this.rules.block.blockquote.exec(src);
477
+ if (cap) {
478
+ const text = cap[0].replace(/^ *> ?/gm, '');
479
+
480
+ return {
481
+ type: 'blockquote',
482
+ raw: cap[0],
483
+ text
484
+ };
485
+ }
486
+ }
487
+
488
+ list(src) {
489
+ const cap = this.rules.block.list.exec(src);
490
+ if (cap) {
491
+ let raw = cap[0];
492
+ const bull = cap[2];
493
+ const isordered = bull.length > 1;
494
+
495
+ const list = {
496
+ type: 'list',
497
+ raw,
498
+ ordered: isordered,
499
+ start: isordered ? +bull : '',
500
+ loose: false,
501
+ items: []
502
+ };
503
+
504
+ // Get each top-level item.
505
+ const itemMatch = cap[0].match(this.rules.block.item);
506
+
507
+ let next = false,
508
+ item,
509
+ space,
510
+ b,
511
+ addBack,
512
+ loose,
513
+ istask,
514
+ ischecked;
515
+
516
+ const l = itemMatch.length;
517
+ for (let i = 0; i < l; i++) {
518
+ item = itemMatch[i];
519
+ raw = item;
520
+
521
+ // Remove the list item's bullet
522
+ // so it is seen as the next token.
523
+ space = item.length;
524
+ item = item.replace(/^ *([*+-]|\d+\.) */, '');
525
+
526
+ // Outdent whatever the
527
+ // list item contains. Hacky.
528
+ if (~item.indexOf('\n ')) {
529
+ space -= item.length;
530
+ item = !this.options.pedantic
531
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
532
+ : item.replace(/^ {1,4}/gm, '');
533
+ }
534
+
535
+ // Determine whether the next list item belongs here.
536
+ // Backpedal if it does not belong in this list.
537
+ if (i !== l - 1) {
538
+ b = this.rules.block.bullet.exec(itemMatch[i + 1])[0];
539
+ if (bull.length > 1 ? b.length === 1
540
+ : (b.length > 1 || (this.options.smartLists && b !== bull))) {
541
+ addBack = itemMatch.slice(i + 1).join('\n');
542
+ list.raw = list.raw.substring(0, list.raw.length - addBack.length);
543
+ i = l - 1;
544
+ }
545
+ }
546
+
547
+ // Determine whether item is loose or not.
548
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
549
+ // for discount behavior.
550
+ loose = next || /\n\n(?!\s*$)/.test(item);
551
+ if (i !== l - 1) {
552
+ next = item.charAt(item.length - 1) === '\n';
553
+ if (!loose) loose = next;
554
+ }
555
+
556
+ if (loose) {
557
+ list.loose = true;
558
+ }
559
+
560
+ // Check for task list items
561
+ istask = /^\[[ xX]\] /.test(item);
562
+ ischecked = undefined;
563
+ if (istask) {
564
+ ischecked = item[1] !== ' ';
565
+ item = item.replace(/^\[[ xX]\] +/, '');
566
+ }
567
+
568
+ list.items.push({
569
+ type: 'list_item',
570
+ raw,
571
+ task: istask,
572
+ checked: ischecked,
573
+ loose: loose,
574
+ text: item
575
+ });
576
+ }
577
+
578
+ return list;
579
+ }
580
+ }
581
+
582
+ html(src) {
583
+ const cap = this.rules.block.html.exec(src);
584
+ if (cap) {
585
+ return {
586
+ type: this.options.sanitize
587
+ ? 'paragraph'
588
+ : 'html',
589
+ raw: cap[0],
590
+ pre: !this.options.sanitizer
591
+ && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
592
+ text: this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape$1(cap[0])) : cap[0]
593
+ };
594
+ }
595
+ }
596
+
597
+ def(src) {
598
+ const cap = this.rules.block.def.exec(src);
599
+ if (cap) {
600
+ if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);
601
+ const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
602
+ return {
603
+ tag,
604
+ raw: cap[0],
605
+ href: cap[2],
606
+ title: cap[3]
607
+ };
608
+ }
609
+ }
610
+
611
+ table(src) {
612
+ const cap = this.rules.block.table.exec(src);
613
+ if (cap) {
614
+ const item = {
615
+ type: 'table',
616
+ header: splitCells$1(cap[1].replace(/^ *| *\| *$/g, '')),
617
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
618
+ cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
619
+ };
620
+
621
+ if (item.header.length === item.align.length) {
622
+ item.raw = cap[0];
623
+
624
+ let l = item.align.length;
625
+ let i;
626
+ for (i = 0; i < l; i++) {
627
+ if (/^ *-+: *$/.test(item.align[i])) {
628
+ item.align[i] = 'right';
629
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
630
+ item.align[i] = 'center';
631
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
632
+ item.align[i] = 'left';
633
+ } else {
634
+ item.align[i] = null;
635
+ }
636
+ }
637
+
638
+ l = item.cells.length;
639
+ for (i = 0; i < l; i++) {
640
+ item.cells[i] = splitCells$1(
641
+ item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
642
+ item.header.length);
643
+ }
644
+
645
+ return item;
646
+ }
647
+ }
648
+ }
649
+
650
+ lheading(src) {
651
+ const cap = this.rules.block.lheading.exec(src);
652
+ if (cap) {
653
+ return {
654
+ type: 'heading',
655
+ raw: cap[0],
656
+ depth: cap[2].charAt(0) === '=' ? 1 : 2,
657
+ text: cap[1]
658
+ };
659
+ }
660
+ }
661
+
662
+ paragraph(src) {
663
+ const cap = this.rules.block.paragraph.exec(src);
664
+ if (cap) {
665
+ return {
666
+ type: 'paragraph',
667
+ raw: cap[0],
668
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
669
+ ? cap[1].slice(0, -1)
670
+ : cap[1]
671
+ };
672
+ }
673
+ }
674
+
675
+ text(src, tokens) {
676
+ const cap = this.rules.block.text.exec(src);
677
+ if (cap) {
678
+ const lastToken = tokens[tokens.length - 1];
679
+ if (lastToken && lastToken.type === 'text') {
680
+ return {
681
+ raw: cap[0],
682
+ text: cap[0]
683
+ };
684
+ }
685
+
686
+ return {
687
+ type: 'text',
688
+ raw: cap[0],
689
+ text: cap[0]
690
+ };
691
+ }
692
+ }
693
+
694
+ escape(src) {
695
+ const cap = this.rules.inline.escape.exec(src);
696
+ if (cap) {
697
+ return {
698
+ type: 'escape',
699
+ raw: cap[0],
700
+ text: escape$1(cap[1])
701
+ };
702
+ }
703
+ }
704
+
705
+ tag(src, inLink, inRawBlock) {
706
+ const cap = this.rules.inline.tag.exec(src);
707
+ if (cap) {
708
+ if (!inLink && /^<a /i.test(cap[0])) {
709
+ inLink = true;
710
+ } else if (inLink && /^<\/a>/i.test(cap[0])) {
711
+ inLink = false;
712
+ }
713
+ if (!inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
714
+ inRawBlock = true;
715
+ } else if (inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
716
+ inRawBlock = false;
717
+ }
718
+
719
+ return {
720
+ type: this.options.sanitize
721
+ ? 'text'
722
+ : 'html',
723
+ raw: cap[0],
724
+ inLink,
725
+ inRawBlock,
726
+ text: this.options.sanitize
727
+ ? (this.options.sanitizer
728
+ ? this.options.sanitizer(cap[0])
729
+ : escape$1(cap[0]))
730
+ : cap[0]
731
+ };
732
+ }
733
+ }
734
+
735
+ link(src) {
736
+ const cap = this.rules.inline.link.exec(src);
737
+ if (cap) {
738
+ const lastParenIndex = findClosingBracket$1(cap[2], '()');
739
+ if (lastParenIndex > -1) {
740
+ const start = cap[0].indexOf('!') === 0 ? 5 : 4;
741
+ const linkLen = start + cap[1].length + lastParenIndex;
742
+ cap[2] = cap[2].substring(0, lastParenIndex);
743
+ cap[0] = cap[0].substring(0, linkLen).trim();
744
+ cap[3] = '';
745
+ }
746
+ let href = cap[2];
747
+ let title = '';
748
+ if (this.options.pedantic) {
749
+ const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
750
+
751
+ if (link) {
752
+ href = link[1];
753
+ title = link[3];
754
+ } else {
755
+ title = '';
756
+ }
757
+ } else {
758
+ title = cap[3] ? cap[3].slice(1, -1) : '';
759
+ }
760
+ href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
761
+ const token = outputLink(cap, {
762
+ href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
763
+ title: title ? title.replace(this.rules.inline._escapes, '$1') : title
764
+ }, cap[0]);
765
+ return token;
766
+ }
767
+ }
768
+
769
+ reflink(src, links) {
770
+ let cap;
771
+ if ((cap = this.rules.inline.reflink.exec(src))
772
+ || (cap = this.rules.inline.nolink.exec(src))) {
773
+ let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
774
+ link = links[link.toLowerCase()];
775
+ if (!link || !link.href) {
776
+ const text = cap[0].charAt(0);
777
+ return {
778
+ type: 'text',
779
+ raw: text,
780
+ text
781
+ };
782
+ }
783
+ const token = outputLink(cap, link, cap[0]);
784
+ return token;
785
+ }
786
+ }
787
+
788
+ strong(src) {
789
+ const cap = this.rules.inline.strong.exec(src);
790
+ if (cap) {
791
+ return {
792
+ type: 'strong',
793
+ raw: cap[0],
794
+ text: cap[4] || cap[3] || cap[2] || cap[1]
795
+ };
796
+ }
797
+ }
798
+
799
+ em(src) {
800
+ const cap = this.rules.inline.em.exec(src);
801
+ if (cap) {
802
+ return {
803
+ type: 'em',
804
+ raw: cap[0],
805
+ text: cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]
806
+ };
807
+ }
808
+ }
809
+
810
+ codespan(src) {
811
+ const cap = this.rules.inline.code.exec(src);
812
+ if (cap) {
813
+ let text = cap[2].replace(/\n/g, ' ');
814
+ const hasNonSpaceChars = /[^ ]/.test(text);
815
+ const hasSpaceCharsOnBothEnds = text.startsWith(' ') && text.endsWith(' ');
816
+ if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
817
+ text = text.substring(1, text.length - 1);
818
+ }
819
+ text = escape$1(text, true);
820
+ return {
821
+ type: 'codespan',
822
+ raw: cap[0],
823
+ text
824
+ };
825
+ }
826
+ }
827
+
828
+ br(src) {
829
+ const cap = this.rules.inline.br.exec(src);
830
+ if (cap) {
831
+ return {
832
+ type: 'br',
833
+ raw: cap[0]
834
+ };
835
+ }
836
+ }
837
+
838
+ del(src) {
839
+ const cap = this.rules.inline.del.exec(src);
840
+ if (cap) {
841
+ return {
842
+ type: 'del',
843
+ raw: cap[0],
844
+ text: cap[1]
845
+ };
846
+ }
847
+ }
848
+
849
+ autolink(src, mangle) {
850
+ const cap = this.rules.inline.autolink.exec(src);
851
+ if (cap) {
852
+ let text, href;
853
+ if (cap[2] === '@') {
854
+ text = escape$1(this.options.mangle ? mangle(cap[1]) : cap[1]);
855
+ href = 'mailto:' + text;
856
+ } else {
857
+ text = escape$1(cap[1]);
858
+ href = text;
859
+ }
860
+
861
+ return {
862
+ type: 'link',
863
+ raw: cap[0],
864
+ text,
865
+ href,
866
+ tokens: [
867
+ {
868
+ type: 'text',
869
+ raw: text,
870
+ text
871
+ }
872
+ ]
873
+ };
874
+ }
875
+ }
876
+
877
+ url(src, mangle) {
878
+ let cap;
879
+ if (cap = this.rules.inline.url.exec(src)) {
880
+ let text, href;
881
+ if (cap[2] === '@') {
882
+ text = escape$1(this.options.mangle ? mangle(cap[0]) : cap[0]);
883
+ href = 'mailto:' + text;
884
+ } else {
885
+ // do extended autolink path validation
886
+ let prevCapZero;
887
+ do {
888
+ prevCapZero = cap[0];
889
+ cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
890
+ } while (prevCapZero !== cap[0]);
891
+ text = escape$1(cap[0]);
892
+ if (cap[1] === 'www.') {
893
+ href = 'http://' + text;
894
+ } else {
895
+ href = text;
896
+ }
897
+ }
898
+ return {
899
+ type: 'link',
900
+ raw: cap[0],
901
+ text,
902
+ href,
903
+ tokens: [
904
+ {
905
+ type: 'text',
906
+ raw: text,
907
+ text
908
+ }
909
+ ]
910
+ };
911
+ }
912
+ }
913
+
914
+ inlineText(src, inRawBlock, smartypants) {
915
+ const cap = this.rules.inline.text.exec(src);
916
+ if (cap) {
917
+ let text;
918
+ if (inRawBlock) {
919
+ text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape$1(cap[0])) : cap[0];
920
+ } else {
921
+ text = escape$1(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
922
+ }
923
+ return {
924
+ type: 'text',
925
+ raw: cap[0],
926
+ text
927
+ };
928
+ }
929
+ }
930
+ };
931
+
296
932
  const {
297
933
  noopTest: noopTest$1,
298
934
  edit: edit$1,
@@ -305,7 +941,7 @@ const {
305
941
  const block = {
306
942
  newline: /^\n+/,
307
943
  code: /^( {4}[^\n]+\n*)+/,
308
- fences: /^ {0,3}(`{3,}|~{3,})([^`~\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,
944
+ fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,
309
945
  hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
310
946
  heading: /^ {0,3}(#{1,6}) +([^\n]*?)(?: +#+)? *(?:\n+|$)/,
311
947
  blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
@@ -364,10 +1000,10 @@ block.html = edit$1(block.html, 'i')
364
1000
 
365
1001
  block.paragraph = edit$1(block._paragraph)
366
1002
  .replace('hr', block.hr)
367
- .replace('heading', ' {0,3}#{1,6} +')
1003
+ .replace('heading', ' {0,3}#{1,6} ')
368
1004
  .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
369
1005
  .replace('blockquote', ' {0,3}>')
370
- .replace('fences', ' {0,3}(?:`{3,}|~{3,})[^`\\n]*\\n')
1006
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
371
1007
  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
372
1008
  .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
373
1009
  .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
@@ -388,10 +1024,36 @@ block.normal = merge$1({}, block);
388
1024
  */
389
1025
 
390
1026
  block.gfm = merge$1({}, block.normal, {
391
- nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
392
- table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
1027
+ nptable: '^ *([^|\\n ].*\\|.*)\\n' // Header
1028
+ + ' *([-:]+ *\\|[-| :]*)' // Align
1029
+ + '(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)', // Cells
1030
+ table: '^ *\\|(.+)\\n' // Header
1031
+ + ' *\\|?( *[-:]+[-| :]*)' // Align
1032
+ + '(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
393
1033
  });
394
1034
 
1035
+ block.gfm.nptable = edit$1(block.gfm.nptable)
1036
+ .replace('hr', block.hr)
1037
+ .replace('heading', ' {0,3}#{1,6} ')
1038
+ .replace('blockquote', ' {0,3}>')
1039
+ .replace('code', ' {4}[^\\n]')
1040
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1041
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1042
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
1043
+ .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
1044
+ .getRegex();
1045
+
1046
+ block.gfm.table = edit$1(block.gfm.table)
1047
+ .replace('hr', block.hr)
1048
+ .replace('heading', ' {0,3}#{1,6} ')
1049
+ .replace('blockquote', ' {0,3}>')
1050
+ .replace('code', ' {4}[^\\n]')
1051
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1052
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1053
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
1054
+ .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
1055
+ .getRegex();
1056
+
395
1057
  /**
396
1058
  * Pedantic grammar (original John Gruber's loose markdown specification)
397
1059
  */
@@ -438,7 +1100,7 @@ const inline = {
438
1100
  reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
439
1101
  nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
440
1102
  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])\*(?!\*)/,
1103
+ em: /^_([^\s_])_(?!_)|^_([^\s_<][\s\S]*?[^\s_])_(?!_|[^\s,punctuation])|^_([^\s_<][\s\S]*?[^\s])_(?!_|[^\s,punctuation])|^\*([^\s*<\[])\*(?!\*)|^\*([^\s<"][\s\S]*?[^\s\[\*])\*(?![\]`punctuation])|^\*([^\s*"<\[][\s\S]*[^\s])\*(?!\*)/,
442
1104
  code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
443
1105
  br: /^( {2,}|\\)\n(?!\s*$)/,
444
1106
  del: noopTest$1,
@@ -447,7 +1109,8 @@ const inline = {
447
1109
 
448
1110
  // list of punctuation marks from common mark spec
449
1111
  // without ` and ] to workaround Rule 17 (inline code blocks/links)
450
- inline._punctuation = '!"#$%&\'()*+,\\-./:;<=>?@\\[^_{|}~';
1112
+ // without , to work around example 393
1113
+ inline._punctuation = '!"#$%&\'()*+\\-./:;<=>?@\\[^_{|}~';
451
1114
  inline.em = edit$1(inline.em).replace(/punctuation/g, inline._punctuation).getRegex();
452
1115
 
453
1116
  inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
@@ -534,13 +1197,49 @@ var rules = {
534
1197
  inline
535
1198
  };
536
1199
 
537
- const { defaults: defaults$1 } = defaults;
538
- const { block: block$1 } = rules;
539
- const {
540
- rtrim: rtrim$1,
541
- splitCells: splitCells$1,
542
- escape: escape$1
543
- } = helpers;
1200
+ const { defaults: defaults$2 } = defaults;
1201
+ const { block: block$1, inline: inline$1 } = rules;
1202
+
1203
+ /**
1204
+ * smartypants text replacement
1205
+ */
1206
+ function smartypants(text) {
1207
+ return text
1208
+ // em-dashes
1209
+ .replace(/---/g, '\u2014')
1210
+ // en-dashes
1211
+ .replace(/--/g, '\u2013')
1212
+ // opening singles
1213
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
1214
+ // closing singles & apostrophes
1215
+ .replace(/'/g, '\u2019')
1216
+ // opening doubles
1217
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
1218
+ // closing doubles
1219
+ .replace(/"/g, '\u201d')
1220
+ // ellipses
1221
+ .replace(/\.{3}/g, '\u2026');
1222
+ }
1223
+
1224
+ /**
1225
+ * mangle email addresses
1226
+ */
1227
+ function mangle(text) {
1228
+ let out = '',
1229
+ i,
1230
+ ch;
1231
+
1232
+ const l = text.length;
1233
+ for (i = 0; i < l; i++) {
1234
+ ch = text.charCodeAt(i);
1235
+ if (Math.random() > 0.5) {
1236
+ ch = 'x' + ch.toString(16);
1237
+ }
1238
+ out += '&#' + ch + ';';
1239
+ }
1240
+
1241
+ return out;
1242
+ }
544
1243
 
545
1244
  /**
546
1245
  * Block Lexer
@@ -549,21 +1248,38 @@ var Lexer_1 = class Lexer {
549
1248
  constructor(options) {
550
1249
  this.tokens = [];
551
1250
  this.tokens.links = Object.create(null);
552
- this.options = options || defaults$1;
553
- this.rules = block$1.normal;
1251
+ this.options = options || defaults$2;
1252
+ this.options.tokenizer = this.options.tokenizer || new Tokenizer_1();
1253
+ this.tokenizer = this.options.tokenizer;
1254
+ this.tokenizer.options = this.options;
1255
+
1256
+ const rules = {
1257
+ block: block$1.normal,
1258
+ inline: inline$1.normal
1259
+ };
554
1260
 
555
1261
  if (this.options.pedantic) {
556
- this.rules = block$1.pedantic;
1262
+ rules.block = block$1.pedantic;
1263
+ rules.inline = inline$1.pedantic;
557
1264
  } else if (this.options.gfm) {
558
- this.rules = block$1.gfm;
1265
+ rules.block = block$1.gfm;
1266
+ if (this.options.breaks) {
1267
+ rules.inline = inline$1.breaks;
1268
+ } else {
1269
+ rules.inline = inline$1.gfm;
1270
+ }
559
1271
  }
1272
+ this.tokenizer.rules = rules;
560
1273
  }
561
1274
 
562
1275
  /**
563
- * Expose Block Rules
1276
+ * Expose Rules
564
1277
  */
565
1278
  static get rules() {
566
- return block$1;
1279
+ return {
1280
+ block: block$1,
1281
+ inline: inline$1
1282
+ };
567
1283
  }
568
1284
 
569
1285
  /**
@@ -572,7 +1288,7 @@ var Lexer_1 = class Lexer {
572
1288
  static lex(src, options) {
573
1289
  const lexer = new Lexer(options);
574
1290
  return lexer.lex(src);
575
- };
1291
+ }
576
1292
 
577
1293
  /**
578
1294
  * Preprocessing
@@ -582,362 +1298,337 @@ var Lexer_1 = class Lexer {
582
1298
  .replace(/\r\n|\r/g, '\n')
583
1299
  .replace(/\t/g, ' ');
584
1300
 
585
- return this.token(src, true);
586
- };
1301
+ this.blockTokens(src, this.tokens, true);
1302
+
1303
+ this.inline(this.tokens);
1304
+
1305
+ return this.tokens;
1306
+ }
587
1307
 
588
1308
  /**
589
1309
  * Lexing
590
1310
  */
591
- token(src, top) {
1311
+ blockTokens(src, tokens = [], top = true) {
592
1312
  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;
1313
+ let token, i, l, lastToken;
609
1314
 
610
1315
  while (src) {
611
1316
  // 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
- });
1317
+ if (token = this.tokenizer.space(src)) {
1318
+ src = src.substring(token.raw.length);
1319
+ if (token.type) {
1320
+ tokens.push(token);
618
1321
  }
1322
+ continue;
619
1323
  }
620
1324
 
621
1325
  // 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();
1326
+ if (token = this.tokenizer.code(src, tokens)) {
1327
+ src = src.substring(token.raw.length);
1328
+ if (token.type) {
1329
+ tokens.push(token);
628
1330
  } 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
- });
1331
+ lastToken = tokens[tokens.length - 1];
1332
+ lastToken.raw += '\n' + token.raw;
1333
+ lastToken.text += '\n' + token.text;
637
1334
  }
638
1335
  continue;
639
1336
  }
640
1337
 
641
1338
  // 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
- });
1339
+ if (token = this.tokenizer.fences(src)) {
1340
+ src = src.substring(token.raw.length);
1341
+ tokens.push(token);
649
1342
  continue;
650
1343
  }
651
1344
 
652
1345
  // 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
- });
1346
+ if (token = this.tokenizer.heading(src)) {
1347
+ src = src.substring(token.raw.length);
1348
+ tokens.push(token);
660
1349
  continue;
661
1350
  }
662
1351
 
663
1352
  // 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
- }
1353
+ if (token = this.tokenizer.nptable(src)) {
1354
+ src = src.substring(token.raw.length);
1355
+ tokens.push(token);
1356
+ continue;
695
1357
  }
696
1358
 
697
1359
  // hr
698
- if (cap = this.rules.hr.exec(src)) {
699
- src = src.substring(cap[0].length);
700
- this.tokens.push({
701
- type: 'hr'
702
- });
1360
+ if (token = this.tokenizer.hr(src)) {
1361
+ src = src.substring(token.raw.length);
1362
+ tokens.push(token);
703
1363
  continue;
704
1364
  }
705
1365
 
706
1366
  // 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
- });
1367
+ if (token = this.tokenizer.blockquote(src)) {
1368
+ src = src.substring(token.raw.length);
1369
+ token.tokens = this.blockTokens(token.text, [], top);
1370
+ tokens.push(token);
1371
+ continue;
1372
+ }
713
1373
 
714
- cap = cap[0].replace(/^ *> ?/gm, '');
1374
+ // list
1375
+ if (token = this.tokenizer.list(src)) {
1376
+ src = src.substring(token.raw.length);
1377
+ l = token.items.length;
1378
+ for (i = 0; i < l; i++) {
1379
+ token.items[i].tokens = this.blockTokens(token.items[i].text, [], false);
1380
+ }
1381
+ tokens.push(token);
1382
+ continue;
1383
+ }
715
1384
 
716
- // Pass `top` to keep the current
717
- // "toplevel" state. This is exactly
718
- // how markdown.pl works.
719
- this.token(cap, top);
1385
+ // html
1386
+ if (token = this.tokenizer.html(src)) {
1387
+ src = src.substring(token.raw.length);
1388
+ tokens.push(token);
1389
+ continue;
1390
+ }
720
1391
 
721
- this.tokens.push({
722
- type: 'blockquote_end'
723
- });
1392
+ // def
1393
+ if (top && (token = this.tokenizer.def(src))) {
1394
+ src = src.substring(token.raw.length);
1395
+ if (!this.tokens.links[token.tag]) {
1396
+ this.tokens.links[token.tag] = {
1397
+ href: token.href,
1398
+ title: token.title
1399
+ };
1400
+ }
1401
+ continue;
1402
+ }
724
1403
 
1404
+ // table (gfm)
1405
+ if (token = this.tokenizer.table(src)) {
1406
+ src = src.substring(token.raw.length);
1407
+ tokens.push(token);
725
1408
  continue;
726
1409
  }
727
1410
 
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
- };
1411
+ // lheading
1412
+ if (token = this.tokenizer.lheading(src)) {
1413
+ src = src.substring(token.raw.length);
1414
+ tokens.push(token);
1415
+ continue;
1416
+ }
740
1417
 
741
- this.tokens.push(listStart);
1418
+ // top-level paragraph
1419
+ if (top && (token = this.tokenizer.paragraph(src))) {
1420
+ src = src.substring(token.raw.length);
1421
+ tokens.push(token);
1422
+ continue;
1423
+ }
742
1424
 
743
- // Get each top-level item.
744
- cap = cap[0].match(this.rules.item);
1425
+ // text
1426
+ if (token = this.tokenizer.text(src, tokens)) {
1427
+ src = src.substring(token.raw.length);
1428
+ if (token.type) {
1429
+ tokens.push(token);
1430
+ } else {
1431
+ lastToken = tokens[tokens.length - 1];
1432
+ lastToken.raw += '\n' + token.raw;
1433
+ lastToken.text += '\n' + token.text;
1434
+ }
1435
+ continue;
1436
+ }
745
1437
 
746
- listItems = [];
747
- next = false;
748
- l = cap.length;
749
- i = 0;
1438
+ if (src) {
1439
+ const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1440
+ if (this.options.silent) {
1441
+ console.error(errMsg);
1442
+ break;
1443
+ } else {
1444
+ throw new Error(errMsg);
1445
+ }
1446
+ }
1447
+ }
750
1448
 
751
- for (; i < l; i++) {
752
- item = cap[i];
1449
+ return tokens;
1450
+ }
753
1451
 
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+\.) */, '');
1452
+ inline(tokens) {
1453
+ let i,
1454
+ j,
1455
+ k,
1456
+ l2,
1457
+ row,
1458
+ token;
1459
+
1460
+ const l = tokens.length;
1461
+ for (i = 0; i < l; i++) {
1462
+ token = tokens[i];
1463
+ switch (token.type) {
1464
+ case 'paragraph':
1465
+ case 'text':
1466
+ case 'heading': {
1467
+ token.tokens = [];
1468
+ this.inlineTokens(token.text, token.tokens);
1469
+ break;
1470
+ }
1471
+ case 'table': {
1472
+ token.tokens = {
1473
+ header: [],
1474
+ cells: []
1475
+ };
758
1476
 
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, '');
1477
+ // header
1478
+ l2 = token.header.length;
1479
+ for (j = 0; j < l2; j++) {
1480
+ token.tokens.header[j] = [];
1481
+ this.inlineTokens(token.header[j], token.tokens.header[j]);
766
1482
  }
767
1483
 
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;
1484
+ // cells
1485
+ l2 = token.cells.length;
1486
+ for (j = 0; j < l2; j++) {
1487
+ row = token.cells[j];
1488
+ token.tokens.cells[j] = [];
1489
+ for (k = 0; k < row.length; k++) {
1490
+ token.tokens.cells[j][k] = [];
1491
+ this.inlineTokens(row[k], token.tokens.cells[j][k]);
776
1492
  }
777
1493
  }
778
1494
 
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;
1495
+ break;
1496
+ }
1497
+ case 'blockquote': {
1498
+ this.inline(token.tokens);
1499
+ break;
1500
+ }
1501
+ case 'list': {
1502
+ l2 = token.items.length;
1503
+ for (j = 0; j < l2; j++) {
1504
+ this.inline(token.items[j].tokens);
790
1505
  }
1506
+ break;
1507
+ }
1508
+ }
1509
+ }
791
1510
 
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
- }
1511
+ return tokens;
1512
+ }
799
1513
 
800
- t = {
801
- type: 'list_item_start',
802
- task: istask,
803
- checked: ischecked,
804
- loose: loose
805
- };
1514
+ /**
1515
+ * Lexing/Compiling
1516
+ */
1517
+ inlineTokens(src, tokens = [], inLink = false, inRawBlock = false) {
1518
+ let token;
806
1519
 
807
- listItems.push(t);
808
- this.tokens.push(t);
1520
+ while (src) {
1521
+ // escape
1522
+ if (token = this.tokenizer.escape(src)) {
1523
+ src = src.substring(token.raw.length);
1524
+ tokens.push(token);
1525
+ continue;
1526
+ }
809
1527
 
810
- // Recurse.
811
- this.token(item, false);
1528
+ // tag
1529
+ if (token = this.tokenizer.tag(src, inLink, inRawBlock)) {
1530
+ src = src.substring(token.raw.length);
1531
+ inLink = token.inLink;
1532
+ inRawBlock = token.inRawBlock;
1533
+ tokens.push(token);
1534
+ continue;
1535
+ }
812
1536
 
813
- this.tokens.push({
814
- type: 'list_item_end'
815
- });
1537
+ // link
1538
+ if (token = this.tokenizer.link(src)) {
1539
+ src = src.substring(token.raw.length);
1540
+ if (token.type === 'link') {
1541
+ token.tokens = this.inlineTokens(token.text, [], true, inRawBlock);
816
1542
  }
1543
+ tokens.push(token);
1544
+ continue;
1545
+ }
817
1546
 
818
- if (listStart.loose) {
819
- l = listItems.length;
820
- i = 0;
821
- for (; i < l; i++) {
822
- listItems[i].loose = true;
823
- }
1547
+ // reflink, nolink
1548
+ if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1549
+ src = src.substring(token.raw.length);
1550
+ if (token.type === 'link') {
1551
+ token.tokens = this.inlineTokens(token.text, [], true, inRawBlock);
824
1552
  }
825
-
826
- this.tokens.push({
827
- type: 'list_end'
828
- });
829
-
1553
+ tokens.push(token);
830
1554
  continue;
831
1555
  }
832
1556
 
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
- });
1557
+ // strong
1558
+ if (token = this.tokenizer.strong(src)) {
1559
+ src = src.substring(token.raw.length);
1560
+ token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
1561
+ tokens.push(token);
844
1562
  continue;
845
1563
  }
846
1564
 
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
- }
1565
+ // em
1566
+ if (token = this.tokenizer.em(src)) {
1567
+ src = src.substring(token.raw.length);
1568
+ token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
1569
+ tokens.push(token);
858
1570
  continue;
859
1571
  }
860
1572
 
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
- }
1573
+ // code
1574
+ if (token = this.tokenizer.codespan(src)) {
1575
+ src = src.substring(token.raw.length);
1576
+ tokens.push(token);
1577
+ continue;
1578
+ }
890
1579
 
891
- this.tokens.push(item);
1580
+ // br
1581
+ if (token = this.tokenizer.br(src)) {
1582
+ src = src.substring(token.raw.length);
1583
+ tokens.push(token);
1584
+ continue;
1585
+ }
892
1586
 
893
- continue;
894
- }
1587
+ // del (gfm)
1588
+ if (token = this.tokenizer.del(src)) {
1589
+ src = src.substring(token.raw.length);
1590
+ token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
1591
+ tokens.push(token);
1592
+ continue;
895
1593
  }
896
1594
 
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
- });
1595
+ // autolink
1596
+ if (token = this.tokenizer.autolink(src, mangle)) {
1597
+ src = src.substring(token.raw.length);
1598
+ tokens.push(token);
905
1599
  continue;
906
1600
  }
907
1601
 
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
- });
1602
+ // url (gfm)
1603
+ if (!inLink && (token = this.tokenizer.url(src, mangle))) {
1604
+ src = src.substring(token.raw.length);
1605
+ tokens.push(token);
917
1606
  continue;
918
1607
  }
919
1608
 
920
1609
  // 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
- });
1610
+ if (token = this.tokenizer.inlineText(src, inRawBlock, smartypants)) {
1611
+ src = src.substring(token.raw.length);
1612
+ tokens.push(token);
928
1613
  continue;
929
1614
  }
930
1615
 
931
1616
  if (src) {
932
- throw new Error('Infinite loop on byte: ' + src.charCodeAt(0));
1617
+ const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1618
+ if (this.options.silent) {
1619
+ console.error(errMsg);
1620
+ break;
1621
+ } else {
1622
+ throw new Error(errMsg);
1623
+ }
933
1624
  }
934
1625
  }
935
1626
 
936
- return this.tokens;
937
- };
1627
+ return tokens;
1628
+ }
938
1629
  };
939
1630
 
940
- const { defaults: defaults$2 } = defaults;
1631
+ const { defaults: defaults$3 } = defaults;
941
1632
  const {
942
1633
  cleanUrl: cleanUrl$1,
943
1634
  escape: escape$2
@@ -948,7 +1639,7 @@ const {
948
1639
  */
949
1640
  var Renderer_1 = class Renderer {
950
1641
  constructor(options) {
951
- this.options = options || defaults$2;
1642
+ this.options = options || defaults$3;
952
1643
  }
953
1644
 
954
1645
  code(code, infostring, escaped) {
@@ -964,7 +1655,7 @@ var Renderer_1 = class Renderer {
964
1655
  if (!lang) {
965
1656
  return '<pre><code>'
966
1657
  + (escaped ? code : escape$2(code, true))
967
- + '</code></pre>';
1658
+ + '</code></pre>\n';
968
1659
  }
969
1660
 
970
1661
  return '<pre><code class="'
@@ -973,15 +1664,15 @@ var Renderer_1 = class Renderer {
973
1664
  + '">'
974
1665
  + (escaped ? code : escape$2(code, true))
975
1666
  + '</code></pre>\n';
976
- };
1667
+ }
977
1668
 
978
1669
  blockquote(quote) {
979
1670
  return '<blockquote>\n' + quote + '</blockquote>\n';
980
- };
1671
+ }
981
1672
 
982
1673
  html(html) {
983
1674
  return html;
984
- };
1675
+ }
985
1676
 
986
1677
  heading(text, level, raw, slugger) {
987
1678
  if (this.options.headerIds) {
@@ -998,21 +1689,21 @@ var Renderer_1 = class Renderer {
998
1689
  }
999
1690
  // ignore IDs
1000
1691
  return '<h' + level + '>' + text + '</h' + level + '>\n';
1001
- };
1692
+ }
1002
1693
 
1003
1694
  hr() {
1004
1695
  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
1005
- };
1696
+ }
1006
1697
 
1007
1698
  list(body, ordered, start) {
1008
1699
  const type = ordered ? 'ol' : 'ul',
1009
1700
  startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1010
1701
  return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
1011
- };
1702
+ }
1012
1703
 
1013
1704
  listitem(text) {
1014
1705
  return '<li>' + text + '</li>\n';
1015
- };
1706
+ }
1016
1707
 
1017
1708
  checkbox(checked) {
1018
1709
  return '<input '
@@ -1020,11 +1711,11 @@ var Renderer_1 = class Renderer {
1020
1711
  + 'disabled="" type="checkbox"'
1021
1712
  + (this.options.xhtml ? ' /' : '')
1022
1713
  + '> ';
1023
- };
1714
+ }
1024
1715
 
1025
1716
  paragraph(text) {
1026
1717
  return '<p>' + text + '</p>\n';
1027
- };
1718
+ }
1028
1719
 
1029
1720
  table(header, body) {
1030
1721
  if (body) body = '<tbody>' + body + '</tbody>';
@@ -1035,11 +1726,11 @@ var Renderer_1 = class Renderer {
1035
1726
  + '</thead>\n'
1036
1727
  + body
1037
1728
  + '</table>\n';
1038
- };
1729
+ }
1039
1730
 
1040
1731
  tablerow(content) {
1041
1732
  return '<tr>\n' + content + '</tr>\n';
1042
- };
1733
+ }
1043
1734
 
1044
1735
  tablecell(content, flags) {
1045
1736
  const type = flags.header ? 'th' : 'td';
@@ -1047,28 +1738,28 @@ var Renderer_1 = class Renderer {
1047
1738
  ? '<' + type + ' align="' + flags.align + '">'
1048
1739
  : '<' + type + '>';
1049
1740
  return tag + content + '</' + type + '>\n';
1050
- };
1741
+ }
1051
1742
 
1052
1743
  // span level renderer
1053
1744
  strong(text) {
1054
1745
  return '<strong>' + text + '</strong>';
1055
- };
1746
+ }
1056
1747
 
1057
1748
  em(text) {
1058
1749
  return '<em>' + text + '</em>';
1059
- };
1750
+ }
1060
1751
 
1061
1752
  codespan(text) {
1062
1753
  return '<code>' + text + '</code>';
1063
- };
1754
+ }
1064
1755
 
1065
1756
  br() {
1066
1757
  return this.options.xhtml ? '<br/>' : '<br>';
1067
- };
1758
+ }
1068
1759
 
1069
1760
  del(text) {
1070
1761
  return '<del>' + text + '</del>';
1071
- };
1762
+ }
1072
1763
 
1073
1764
  link(href, title, text) {
1074
1765
  href = cleanUrl$1(this.options.sanitize, this.options.baseUrl, href);
@@ -1081,7 +1772,7 @@ var Renderer_1 = class Renderer {
1081
1772
  }
1082
1773
  out += '>' + text + '</a>';
1083
1774
  return out;
1084
- };
1775
+ }
1085
1776
 
1086
1777
  image(href, title, text) {
1087
1778
  href = cleanUrl$1(this.options.sanitize, this.options.baseUrl, href);
@@ -1095,334 +1786,10 @@ var Renderer_1 = class Renderer {
1095
1786
  }
1096
1787
  out += this.options.xhtml ? '/>' : '>';
1097
1788
  return out;
1098
- };
1789
+ }
1099
1790
 
1100
1791
  text(text) {
1101
1792
  return text;
1102
- };
1103
- };
1104
-
1105
- /**
1106
- * Slugger generates header id
1107
- */
1108
- var 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
-
1136
- const { defaults: defaults$3 } = defaults;
1137
- const { inline: inline$1 } = rules;
1138
- const {
1139
- findClosingBracket: findClosingBracket$1,
1140
- escape: escape$3
1141
- } = helpers;
1142
-
1143
- /**
1144
- * Inline Lexer & Compiler
1145
- */
1146
- var 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
1793
  }
1427
1794
  };
1428
1795
 
@@ -1448,6 +1815,10 @@ var TextRenderer_1 = class TextRenderer {
1448
1815
  return text;
1449
1816
  }
1450
1817
 
1818
+ html(text) {
1819
+ return text;
1820
+ }
1821
+
1451
1822
  text(text) {
1452
1823
  return text;
1453
1824
  }
@@ -1465,9 +1836,42 @@ var TextRenderer_1 = class TextRenderer {
1465
1836
  }
1466
1837
  };
1467
1838
 
1839
+ /**
1840
+ * Slugger generates header id
1841
+ */
1842
+ var Slugger_1 = class Slugger {
1843
+ constructor() {
1844
+ this.seen = {};
1845
+ }
1846
+
1847
+ /**
1848
+ * Convert string to unique id
1849
+ */
1850
+ slug(value) {
1851
+ let slug = value
1852
+ .toLowerCase()
1853
+ .trim()
1854
+ // remove html tags
1855
+ .replace(/<[!\/a-z].*?>/ig, '')
1856
+ // remove unwanted chars
1857
+ .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
1858
+ .replace(/\s/g, '-');
1859
+
1860
+ if (this.seen.hasOwnProperty(slug)) {
1861
+ const originalSlug = slug;
1862
+ do {
1863
+ this.seen[originalSlug]++;
1864
+ slug = originalSlug + '-' + this.seen[originalSlug];
1865
+ } while (this.seen.hasOwnProperty(slug));
1866
+ }
1867
+ this.seen[slug] = 0;
1868
+
1869
+ return slug;
1870
+ }
1871
+ };
1872
+
1468
1873
  const { defaults: defaults$4 } = defaults;
1469
1874
  const {
1470
- merge: merge$2,
1471
1875
  unescape: unescape$1
1472
1876
  } = helpers;
1473
1877
 
@@ -1476,12 +1880,11 @@ const {
1476
1880
  */
1477
1881
  var Parser_1 = class Parser {
1478
1882
  constructor(options) {
1479
- this.tokens = [];
1480
- this.token = null;
1481
1883
  this.options = options || defaults$4;
1482
1884
  this.options.renderer = this.options.renderer || new Renderer_1();
1483
1885
  this.renderer = this.options.renderer;
1484
1886
  this.renderer.options = this.options;
1887
+ this.textRenderer = new TextRenderer_1();
1485
1888
  this.slugger = new Slugger_1();
1486
1889
  }
1487
1890
 
@@ -1491,187 +1894,239 @@ var Parser_1 = class Parser {
1491
1894
  static parse(tokens, options) {
1492
1895
  const parser = new Parser(options);
1493
1896
  return parser.parse(tokens);
1494
- };
1897
+ }
1495
1898
 
1496
1899
  /**
1497
1900
  * Parse Loop
1498
1901
  */
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
- );
1902
+ parse(tokens, top = true) {
1903
+ let out = '',
1904
+ i,
1905
+ j,
1906
+ k,
1907
+ l2,
1908
+ l3,
1909
+ row,
1910
+ cell,
1911
+ header,
1912
+ body,
1913
+ token,
1914
+ ordered,
1915
+ start,
1916
+ loose,
1917
+ itemBody,
1918
+ item,
1919
+ checked,
1920
+ task,
1921
+ checkbox;
1922
+
1923
+ const l = tokens.length;
1924
+ for (i = 0; i < l; i++) {
1925
+ token = tokens[i];
1926
+ switch (token.type) {
1927
+ case 'space': {
1928
+ continue;
1582
1929
  }
1583
- header += this.renderer.tablerow(cell);
1584
-
1585
- for (i = 0; i < this.token.cells.length; i++) {
1586
- row = this.token.cells[i];
1930
+ case 'hr': {
1931
+ out += this.renderer.hr();
1932
+ continue;
1933
+ }
1934
+ case 'heading': {
1935
+ out += this.renderer.heading(
1936
+ this.parseInline(token.tokens),
1937
+ token.depth,
1938
+ unescape$1(this.parseInline(token.tokens, this.textRenderer)),
1939
+ this.slugger);
1940
+ continue;
1941
+ }
1942
+ case 'code': {
1943
+ out += this.renderer.code(token.text,
1944
+ token.lang,
1945
+ token.escaped);
1946
+ continue;
1947
+ }
1948
+ case 'table': {
1949
+ header = '';
1587
1950
 
1951
+ // header
1588
1952
  cell = '';
1589
- for (j = 0; j < row.length; j++) {
1953
+ l2 = token.header.length;
1954
+ for (j = 0; j < l2; j++) {
1590
1955
  cell += this.renderer.tablecell(
1591
- this.inline.output(row[j]),
1592
- { header: false, align: this.token.align[j] }
1956
+ this.parseInline(token.tokens.header[j]),
1957
+ { header: true, align: token.align[j] }
1593
1958
  );
1594
1959
  }
1960
+ header += this.renderer.tablerow(cell);
1961
+
1962
+ body = '';
1963
+ l2 = token.cells.length;
1964
+ for (j = 0; j < l2; j++) {
1965
+ row = token.tokens.cells[j];
1966
+
1967
+ cell = '';
1968
+ l3 = row.length;
1969
+ for (k = 0; k < l3; k++) {
1970
+ cell += this.renderer.tablecell(
1971
+ this.parseInline(row[k]),
1972
+ { header: false, align: token.align[k] }
1973
+ );
1974
+ }
1595
1975
 
1596
- body += this.renderer.tablerow(cell);
1976
+ body += this.renderer.tablerow(cell);
1977
+ }
1978
+ out += this.renderer.table(header, body);
1979
+ continue;
1597
1980
  }
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();
1981
+ case 'blockquote': {
1982
+ body = this.parse(token.tokens);
1983
+ out += this.renderer.blockquote(body);
1984
+ continue;
1605
1985
  }
1986
+ case 'list': {
1987
+ ordered = token.ordered;
1988
+ start = token.start;
1989
+ loose = token.loose;
1990
+ l2 = token.items.length;
1991
+
1992
+ body = '';
1993
+ for (j = 0; j < l2; j++) {
1994
+ item = token.items[j];
1995
+ checked = item.checked;
1996
+ task = item.task;
1997
+
1998
+ itemBody = '';
1999
+ if (item.task) {
2000
+ checkbox = this.renderer.checkbox(checked);
2001
+ if (loose) {
2002
+ if (item.tokens.length > 0 && item.tokens[0].type === 'text') {
2003
+ item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
2004
+ if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
2005
+ item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
2006
+ }
2007
+ } else {
2008
+ item.tokens.unshift({
2009
+ type: 'text',
2010
+ text: checkbox
2011
+ });
2012
+ }
2013
+ } else {
2014
+ itemBody += checkbox;
2015
+ }
2016
+ }
1606
2017
 
1607
- return this.renderer.blockquote(body);
1608
- }
1609
- case 'list_start': {
1610
- body = '';
1611
- const ordered = this.token.ordered,
1612
- start = this.token.start;
2018
+ itemBody += this.parse(item.tokens, loose);
2019
+ body += this.renderer.listitem(itemBody, task, checked);
2020
+ }
1613
2021
 
1614
- while (this.next().type !== 'list_end') {
1615
- body += this.tok();
2022
+ out += this.renderer.list(body, ordered, start);
2023
+ continue;
1616
2024
  }
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
- }
2025
+ case 'html': {
2026
+ // TODO parse inline content if parameter markdown=1
2027
+ out += this.renderer.html(token.text);
2028
+ continue;
2029
+ }
2030
+ case 'paragraph': {
2031
+ out += this.renderer.paragraph(this.parseInline(token.tokens));
2032
+ continue;
2033
+ }
2034
+ case 'text': {
2035
+ body = token.tokens ? this.parseInline(token.tokens) : token.text;
2036
+ while (i + 1 < l && tokens[i + 1].type === 'text') {
2037
+ token = tokens[++i];
2038
+ body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
2039
+ }
2040
+ out += top ? this.renderer.paragraph(body) : body;
2041
+ continue;
2042
+ }
2043
+ default: {
2044
+ const errMsg = 'Token with "' + token.type + '" type was not found.';
2045
+ if (this.options.silent) {
2046
+ console.error(errMsg);
2047
+ return;
1637
2048
  } else {
1638
- body += this.renderer.checkbox(checked);
2049
+ throw new Error(errMsg);
1639
2050
  }
1640
2051
  }
2052
+ }
2053
+ }
2054
+
2055
+ return out;
2056
+ }
1641
2057
 
1642
- while (this.next().type !== 'list_item_end') {
1643
- body += !loose && this.token.type === 'text'
1644
- ? this.parseText()
1645
- : this.tok();
2058
+ /**
2059
+ * Parse Inline Tokens
2060
+ */
2061
+ parseInline(tokens, renderer) {
2062
+ renderer = renderer || this.renderer;
2063
+ let out = '',
2064
+ i,
2065
+ token;
2066
+
2067
+ const l = tokens.length;
2068
+ for (i = 0; i < l; i++) {
2069
+ token = tokens[i];
2070
+ switch (token.type) {
2071
+ case 'escape': {
2072
+ out += renderer.text(token.text);
2073
+ break;
1646
2074
  }
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);
2075
+ case 'html': {
2076
+ out += renderer.html(token.text);
2077
+ break;
2078
+ }
2079
+ case 'link': {
2080
+ out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
2081
+ break;
2082
+ }
2083
+ case 'image': {
2084
+ out += renderer.image(token.href, token.title, token.text);
2085
+ break;
2086
+ }
2087
+ case 'strong': {
2088
+ out += renderer.strong(this.parseInline(token.tokens, renderer));
2089
+ break;
2090
+ }
2091
+ case 'em': {
2092
+ out += renderer.em(this.parseInline(token.tokens, renderer));
2093
+ break;
2094
+ }
2095
+ case 'codespan': {
2096
+ out += renderer.codespan(token.text);
2097
+ break;
2098
+ }
2099
+ case 'br': {
2100
+ out += renderer.br();
2101
+ break;
2102
+ }
2103
+ case 'del': {
2104
+ out += renderer.del(this.parseInline(token.tokens, renderer));
2105
+ break;
2106
+ }
2107
+ case 'text': {
2108
+ out += renderer.text(token.text);
2109
+ break;
2110
+ }
2111
+ default: {
2112
+ const errMsg = 'Token with "' + token.type + '" type was not found.';
2113
+ if (this.options.silent) {
2114
+ console.error(errMsg);
2115
+ return;
2116
+ } else {
2117
+ throw new Error(errMsg);
2118
+ }
1665
2119
  }
1666
2120
  }
1667
2121
  }
1668
- };
2122
+ return out;
2123
+ }
1669
2124
  };
1670
2125
 
1671
2126
  const {
1672
- merge: merge$3,
2127
+ merge: merge$2,
1673
2128
  checkSanitizeDeprecation: checkSanitizeDeprecation$1,
1674
- escape: escape$4
2129
+ escape: escape$3
1675
2130
  } = helpers;
1676
2131
  const {
1677
2132
  getDefaults,
@@ -1692,18 +2147,17 @@ function marked(src, opt, callback) {
1692
2147
  + Object.prototype.toString.call(src) + ', string expected');
1693
2148
  }
1694
2149
 
1695
- if (callback || typeof opt === 'function') {
1696
- if (!callback) {
1697
- callback = opt;
1698
- opt = null;
1699
- }
2150
+ if (typeof opt === 'function') {
2151
+ callback = opt;
2152
+ opt = null;
2153
+ }
2154
+
2155
+ opt = merge$2({}, marked.defaults, opt || {});
2156
+ checkSanitizeDeprecation$1(opt);
1700
2157
 
1701
- opt = merge$3({}, marked.defaults, opt || {});
1702
- checkSanitizeDeprecation$1(opt);
2158
+ if (callback) {
1703
2159
  const highlight = opt.highlight;
1704
- let tokens,
1705
- pending,
1706
- i = 0;
2160
+ let tokens;
1707
2161
 
1708
2162
  try {
1709
2163
  tokens = Lexer_1.lex(src, opt);
@@ -1711,20 +2165,15 @@ function marked(src, opt, callback) {
1711
2165
  return callback(e);
1712
2166
  }
1713
2167
 
1714
- pending = tokens.length;
1715
-
1716
2168
  const done = function(err) {
1717
- if (err) {
1718
- opt.highlight = highlight;
1719
- return callback(err);
1720
- }
1721
-
1722
2169
  let out;
1723
2170
 
1724
- try {
1725
- out = Parser_1.parse(tokens, opt);
1726
- } catch (e) {
1727
- err = e;
2171
+ if (!err) {
2172
+ try {
2173
+ out = Parser_1.parse(tokens, opt);
2174
+ } catch (e) {
2175
+ err = e;
2176
+ }
1728
2177
  }
1729
2178
 
1730
2179
  opt.highlight = highlight;
@@ -1740,36 +2189,47 @@ function marked(src, opt, callback) {
1740
2189
 
1741
2190
  delete opt.highlight;
1742
2191
 
1743
- if (!pending) return done();
2192
+ if (!tokens.length) return done();
1744
2193
 
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();
2194
+ let pending = 0;
2195
+ marked.walkTokens(tokens, function(token) {
2196
+ if (token.type === 'code') {
2197
+ pending++;
2198
+ highlight(token.text, token.lang, function(err, code) {
2199
+ if (err) {
2200
+ return done(err);
2201
+ }
2202
+ if (code != null && code !== token.text) {
2203
+ token.text = code;
2204
+ token.escaped = true;
2205
+ }
2206
+
2207
+ pending--;
2208
+ if (pending === 0) {
2209
+ done();
1754
2210
  }
1755
- token.text = code;
1756
- token.escaped = true;
1757
- --pending || done();
1758
2211
  });
1759
- })(tokens[i]);
2212
+ }
2213
+ });
2214
+
2215
+ if (pending === 0) {
2216
+ done();
1760
2217
  }
1761
2218
 
1762
2219
  return;
1763
2220
  }
2221
+
1764
2222
  try {
1765
- opt = merge$3({}, marked.defaults, opt || {});
1766
- checkSanitizeDeprecation$1(opt);
1767
- return Parser_1.parse(Lexer_1.lex(src, opt), opt);
2223
+ const tokens = Lexer_1.lex(src, opt);
2224
+ if (opt.walkTokens) {
2225
+ marked.walkTokens(tokens, opt.walkTokens);
2226
+ }
2227
+ return Parser_1.parse(tokens, opt);
1768
2228
  } catch (e) {
1769
2229
  e.message += '\nPlease report this to https://github.com/markedjs/marked.';
1770
- if ((opt || marked.defaults).silent) {
2230
+ if (opt.silent) {
1771
2231
  return '<p>An error occurred:</p><pre>'
1772
- + escape$4(e.message + '', true)
2232
+ + escape$3(e.message + '', true)
1773
2233
  + '</pre>';
1774
2234
  }
1775
2235
  throw e;
@@ -1782,7 +2242,7 @@ function marked(src, opt, callback) {
1782
2242
 
1783
2243
  marked.options =
1784
2244
  marked.setOptions = function(opt) {
1785
- merge$3(marked.defaults, opt);
2245
+ merge$2(marked.defaults, opt);
1786
2246
  changeDefaults(marked.defaults);
1787
2247
  return marked;
1788
2248
  };
@@ -1791,6 +2251,84 @@ marked.getDefaults = getDefaults;
1791
2251
 
1792
2252
  marked.defaults = defaults$5;
1793
2253
 
2254
+ /**
2255
+ * Use Extension
2256
+ */
2257
+
2258
+ marked.use = function(extension) {
2259
+ const opts = merge$2({}, extension);
2260
+ if (extension.renderer) {
2261
+ const renderer = marked.defaults.renderer || new Renderer_1();
2262
+ for (const prop in extension.renderer) {
2263
+ const prevRenderer = renderer[prop];
2264
+ renderer[prop] = (...args) => {
2265
+ let ret = extension.renderer[prop].apply(renderer, args);
2266
+ if (ret === false) {
2267
+ ret = prevRenderer.apply(renderer, args);
2268
+ }
2269
+ return ret;
2270
+ };
2271
+ }
2272
+ opts.renderer = renderer;
2273
+ }
2274
+ if (extension.tokenizer) {
2275
+ const tokenizer = marked.defaults.tokenizer || new Tokenizer_1();
2276
+ for (const prop in extension.tokenizer) {
2277
+ const prevTokenizer = tokenizer[prop];
2278
+ tokenizer[prop] = (...args) => {
2279
+ let ret = extension.tokenizer[prop].apply(tokenizer, args);
2280
+ if (ret === false) {
2281
+ ret = prevTokenizer.apply(tokenizer, args);
2282
+ }
2283
+ return ret;
2284
+ };
2285
+ }
2286
+ opts.tokenizer = tokenizer;
2287
+ }
2288
+ if (extension.walkTokens) {
2289
+ const walkTokens = marked.defaults.walkTokens;
2290
+ opts.walkTokens = (token) => {
2291
+ extension.walkTokens(token);
2292
+ if (walkTokens) {
2293
+ walkTokens(token);
2294
+ }
2295
+ };
2296
+ }
2297
+ marked.setOptions(opts);
2298
+ };
2299
+
2300
+ /**
2301
+ * Run callback for every token
2302
+ */
2303
+
2304
+ marked.walkTokens = function(tokens, callback) {
2305
+ for (const token of tokens) {
2306
+ callback(token);
2307
+ switch (token.type) {
2308
+ case 'table': {
2309
+ for (const cell of token.tokens.header) {
2310
+ marked.walkTokens(cell, callback);
2311
+ }
2312
+ for (const row of token.tokens.cells) {
2313
+ for (const cell of row) {
2314
+ marked.walkTokens(cell, callback);
2315
+ }
2316
+ }
2317
+ break;
2318
+ }
2319
+ case 'list': {
2320
+ marked.walkTokens(token.items, callback);
2321
+ break;
2322
+ }
2323
+ default: {
2324
+ if (token.tokens) {
2325
+ marked.walkTokens(token.tokens, callback);
2326
+ }
2327
+ }
2328
+ }
2329
+ }
2330
+ };
2331
+
1794
2332
  /**
1795
2333
  * Expose
1796
2334
  */
@@ -1804,8 +2342,7 @@ marked.TextRenderer = TextRenderer_1;
1804
2342
  marked.Lexer = Lexer_1;
1805
2343
  marked.lexer = Lexer_1.lex;
1806
2344
 
1807
- marked.InlineLexer = InlineLexer_1;
1808
- marked.inlineLexer = InlineLexer_1.output;
2345
+ marked.Tokenizer = Tokenizer_1;
1809
2346
 
1810
2347
  marked.Slugger = Slugger_1;
1811
2348