marked 10.0.0 → 11.0.1

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.umd.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * marked v10.0.0 - a markdown parser
2
+ * marked v11.0.1 - a markdown parser
3
3
  * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
4
4
  * https://github.com/markedjs/marked
5
5
  */
@@ -52,7 +52,7 @@
52
52
  "'": '''
53
53
  };
54
54
  const getEscapeReplacement = (ch) => escapeReplacements[ch];
55
- function escape(html, encode) {
55
+ function escape$1(html, encode) {
56
56
  if (encode) {
57
57
  if (escapeTest.test(html)) {
58
58
  return html.replace(escapeReplace, getEscapeReplacement);
@@ -82,17 +82,17 @@
82
82
  }
83
83
  const caret = /(^|[^\[])\^/g;
84
84
  function edit(regex, opt) {
85
- regex = typeof regex === 'string' ? regex : regex.source;
85
+ let source = typeof regex === 'string' ? regex : regex.source;
86
86
  opt = opt || '';
87
87
  const obj = {
88
88
  replace: (name, val) => {
89
- val = typeof val === 'object' && 'source' in val ? val.source : val;
90
- val = val.replace(caret, '$1');
91
- regex = regex.replace(name, val);
89
+ let valSource = typeof val === 'string' ? val : val.source;
90
+ valSource = valSource.replace(caret, '$1');
91
+ source = source.replace(name, valSource);
92
92
  return obj;
93
93
  },
94
94
  getRegex: () => {
95
- return new RegExp(regex, opt);
95
+ return new RegExp(source, opt);
96
96
  }
97
97
  };
98
98
  return obj;
@@ -202,7 +202,7 @@
202
202
 
203
203
  function outputLink(cap, link, raw, lexer) {
204
204
  const href = link.href;
205
- const title = link.title ? escape(link.title) : null;
205
+ const title = link.title ? escape$1(link.title) : null;
206
206
  const text = cap[1].replace(/\\([\[\]])/g, '$1');
207
207
  if (cap[0].charAt(0) !== '!') {
208
208
  lexer.state.inLink = true;
@@ -222,7 +222,7 @@
222
222
  raw,
223
223
  href,
224
224
  title,
225
- text: escape(text)
225
+ text: escape$1(text)
226
226
  };
227
227
  }
228
228
  function indentCodeCompensation(raw, text) {
@@ -251,9 +251,8 @@
251
251
  */
252
252
  class _Tokenizer {
253
253
  options;
254
- // TODO: Fix this rules type
255
- rules;
256
- lexer;
254
+ rules; // set by the lexer
255
+ lexer; // set by the lexer
257
256
  constructor(options) {
258
257
  this.options = options || exports.defaults;
259
258
  }
@@ -288,7 +287,7 @@
288
287
  return {
289
288
  type: 'code',
290
289
  raw,
291
- lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
290
+ lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],
292
291
  text
293
292
  };
294
293
  }
@@ -486,7 +485,7 @@
486
485
  }
487
486
  // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
488
487
  list.items[list.items.length - 1].raw = raw.trimEnd();
489
- list.items[list.items.length - 1].text = itemContents.trimEnd();
488
+ (list.items[list.items.length - 1]).text = itemContents.trimEnd();
490
489
  list.raw = list.raw.trimEnd();
491
490
  // Item child tokens handled here at end because we needed to have the final item to trim it first
492
491
  for (let i = 0; i < list.items.length; i++) {
@@ -525,8 +524,8 @@
525
524
  const cap = this.rules.block.def.exec(src);
526
525
  if (cap) {
527
526
  const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
528
- const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
529
- const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
527
+ const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';
528
+ const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];
530
529
  return {
531
530
  type: 'def',
532
531
  tag,
@@ -538,63 +537,56 @@
538
537
  }
539
538
  table(src) {
540
539
  const cap = this.rules.block.table.exec(src);
541
- if (cap) {
542
- if (!/[:|]/.test(cap[2])) {
543
- // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
544
- return;
540
+ if (!cap) {
541
+ return;
542
+ }
543
+ if (!/[:|]/.test(cap[2])) {
544
+ // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
545
+ return;
546
+ }
547
+ const headers = splitCells(cap[1]);
548
+ const aligns = cap[2].replace(/^\||\| *$/g, '').split('|');
549
+ const rows = cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [];
550
+ const item = {
551
+ type: 'table',
552
+ raw: cap[0],
553
+ header: [],
554
+ align: [],
555
+ rows: []
556
+ };
557
+ if (headers.length !== aligns.length) {
558
+ // header and align columns must be equal, rows can be different.
559
+ return;
560
+ }
561
+ for (const align of aligns) {
562
+ if (/^ *-+: *$/.test(align)) {
563
+ item.align.push('right');
545
564
  }
546
- const item = {
547
- type: 'table',
548
- raw: cap[0],
549
- header: splitCells(cap[1]).map(c => {
550
- return { text: c, tokens: [] };
551
- }),
552
- align: cap[2].replace(/^\||\| *$/g, '').split('|'),
553
- rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
554
- };
555
- if (item.header.length === item.align.length) {
556
- let l = item.align.length;
557
- let i, j, k, row;
558
- for (i = 0; i < l; i++) {
559
- const align = item.align[i];
560
- if (align) {
561
- if (/^ *-+: *$/.test(align)) {
562
- item.align[i] = 'right';
563
- }
564
- else if (/^ *:-+: *$/.test(align)) {
565
- item.align[i] = 'center';
566
- }
567
- else if (/^ *:-+ *$/.test(align)) {
568
- item.align[i] = 'left';
569
- }
570
- else {
571
- item.align[i] = null;
572
- }
573
- }
574
- }
575
- l = item.rows.length;
576
- for (i = 0; i < l; i++) {
577
- item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
578
- return { text: c, tokens: [] };
579
- });
580
- }
581
- // parse child tokens inside headers and cells
582
- // header child tokens
583
- l = item.header.length;
584
- for (j = 0; j < l; j++) {
585
- item.header[j].tokens = this.lexer.inline(item.header[j].text);
586
- }
587
- // cell child tokens
588
- l = item.rows.length;
589
- for (j = 0; j < l; j++) {
590
- row = item.rows[j];
591
- for (k = 0; k < row.length; k++) {
592
- row[k].tokens = this.lexer.inline(row[k].text);
593
- }
594
- }
595
- return item;
565
+ else if (/^ *:-+: *$/.test(align)) {
566
+ item.align.push('center');
567
+ }
568
+ else if (/^ *:-+ *$/.test(align)) {
569
+ item.align.push('left');
596
570
  }
571
+ else {
572
+ item.align.push(null);
573
+ }
574
+ }
575
+ for (const header of headers) {
576
+ item.header.push({
577
+ text: header,
578
+ tokens: this.lexer.inline(header)
579
+ });
597
580
  }
581
+ for (const row of rows) {
582
+ item.rows.push(splitCells(row, item.header.length).map(cell => {
583
+ return {
584
+ text: cell,
585
+ tokens: this.lexer.inline(cell)
586
+ };
587
+ }));
588
+ }
589
+ return item;
598
590
  }
599
591
  lheading(src) {
600
592
  const cap = this.rules.block.lheading.exec(src);
@@ -639,7 +631,7 @@
639
631
  return {
640
632
  type: 'escape',
641
633
  raw: cap[0],
642
- text: escape(cap[1])
634
+ text: escape$1(cap[1])
643
635
  };
644
636
  }
645
637
  }
@@ -718,8 +710,8 @@
718
710
  }
719
711
  }
720
712
  return outputLink(cap, {
721
- href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
722
- title: title ? title.replace(this.rules.inline._escapes, '$1') : title
713
+ href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,
714
+ title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title
723
715
  }, cap[0], this.lexer);
724
716
  }
725
717
  }
@@ -727,8 +719,8 @@
727
719
  let cap;
728
720
  if ((cap = this.rules.inline.reflink.exec(src))
729
721
  || (cap = this.rules.inline.nolink.exec(src))) {
730
- let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
731
- link = links[link.toLowerCase()];
722
+ const linkString = (cap[2] || cap[1]).replace(/\s+/g, ' ');
723
+ const link = links[linkString.toLowerCase()];
732
724
  if (!link) {
733
725
  const text = cap[0].charAt(0);
734
726
  return {
@@ -741,7 +733,7 @@
741
733
  }
742
734
  }
743
735
  emStrong(src, maskedSrc, prevChar = '') {
744
- let match = this.rules.inline.emStrong.lDelim.exec(src);
736
+ let match = this.rules.inline.emStrongLDelim.exec(src);
745
737
  if (!match)
746
738
  return;
747
739
  // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
@@ -752,7 +744,7 @@
752
744
  // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
753
745
  const lLength = [...match[0]].length - 1;
754
746
  let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
755
- const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
747
+ const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
756
748
  endReg.lastIndex = 0;
757
749
  // Clip maskedSrc to same section of string as src (move to lexer?)
758
750
  maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
@@ -809,7 +801,7 @@
809
801
  if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
810
802
  text = text.substring(1, text.length - 1);
811
803
  }
812
- text = escape(text, true);
804
+ text = escape$1(text, true);
813
805
  return {
814
806
  type: 'codespan',
815
807
  raw: cap[0],
@@ -842,11 +834,11 @@
842
834
  if (cap) {
843
835
  let text, href;
844
836
  if (cap[2] === '@') {
845
- text = escape(cap[1]);
837
+ text = escape$1(cap[1]);
846
838
  href = 'mailto:' + text;
847
839
  }
848
840
  else {
849
- text = escape(cap[1]);
841
+ text = escape$1(cap[1]);
850
842
  href = text;
851
843
  }
852
844
  return {
@@ -869,7 +861,7 @@
869
861
  if (cap = this.rules.inline.url.exec(src)) {
870
862
  let text, href;
871
863
  if (cap[2] === '@') {
872
- text = escape(cap[0]);
864
+ text = escape$1(cap[0]);
873
865
  href = 'mailto:' + text;
874
866
  }
875
867
  else {
@@ -877,9 +869,9 @@
877
869
  let prevCapZero;
878
870
  do {
879
871
  prevCapZero = cap[0];
880
- cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
872
+ cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';
881
873
  } while (prevCapZero !== cap[0]);
882
- text = escape(cap[0]);
874
+ text = escape$1(cap[0]);
883
875
  if (cap[1] === 'www.') {
884
876
  href = 'http://' + cap[0];
885
877
  }
@@ -910,7 +902,7 @@
910
902
  text = cap[0];
911
903
  }
912
904
  else {
913
- text = escape(cap[0]);
905
+ text = escape$1(cap[0]);
914
906
  }
915
907
  return {
916
908
  type: 'text',
@@ -924,66 +916,48 @@
924
916
  /**
925
917
  * Block-Level Grammar
926
918
  */
927
- // Not all rules are defined in the object literal
928
- // @ts-expect-error
929
- const block = {
930
- newline: /^(?: *(?:\n|$))+/,
931
- code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
932
- fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
933
- hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
934
- heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
935
- blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
936
- list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
937
- html: '^ {0,3}(?:' // optional indentation
938
- + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
939
- + '|comment[^\\n]*(\\n+|$)' // (2)
940
- + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
941
- + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
942
- + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
943
- + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
944
- + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
945
- + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
946
- + ')',
947
- def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
948
- table: noopTest,
949
- lheading: /^(?!bull )((?:.|\n(?!\s*?\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
950
- // regex template, placeholders will be replaced according to different paragraph
951
- // interruption rules of commonmark and the original markdown spec:
952
- _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
953
- text: /^[^\n]+/
954
- };
955
- block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
956
- block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
957
- block.def = edit(block.def)
958
- .replace('label', block._label)
959
- .replace('title', block._title)
919
+ const newline = /^(?: *(?:\n|$))+/;
920
+ const blockCode = /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/;
921
+ const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
922
+ const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
923
+ const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
924
+ const bullet = /(?:[*+-]|\d{1,9}[.)])/;
925
+ const lheading = edit(/^(?!bull )((?:.|\n(?!\s*?\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/)
926
+ .replace(/bull/g, bullet) // lists can interrupt
960
927
  .getRegex();
961
- block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
962
- block.listItemStart = edit(/^( *)(bull) */)
963
- .replace('bull', block.bullet)
928
+ const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
929
+ const blockText = /^[^\n]+/;
930
+ const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
931
+ const def = edit(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/)
932
+ .replace('label', _blockLabel)
933
+ .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/)
964
934
  .getRegex();
965
- block.list = edit(block.list)
966
- .replace(/bull/g, block.bullet)
967
- .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
968
- .replace('def', '\\n+(?=' + block.def.source + ')')
935
+ const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/)
936
+ .replace(/bull/g, bullet)
969
937
  .getRegex();
970
- block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
938
+ const _tag = 'address|article|aside|base|basefont|blockquote|body|caption'
971
939
  + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
972
940
  + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
973
941
  + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
974
942
  + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
975
943
  + '|track|ul';
976
- block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
977
- block.html = edit(block.html, 'i')
978
- .replace('comment', block._comment)
979
- .replace('tag', block._tag)
944
+ const _comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
945
+ const html = edit('^ {0,3}(?:' // optional indentation
946
+ + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
947
+ + '|comment[^\\n]*(\\n+|$)' // (2)
948
+ + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
949
+ + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
950
+ + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
951
+ + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
952
+ + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
953
+ + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
954
+ + ')', 'i')
955
+ .replace('comment', _comment)
956
+ .replace('tag', _tag)
980
957
  .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
981
958
  .getRegex();
982
- block.lheading = edit(block.lheading)
983
- .replace(/bull/g, block.bullet) // lists can interrupt
984
- .getRegex();
985
- block.paragraph = edit(block._paragraph)
986
- .replace('hr', block.hr)
959
+ const paragraph = edit(_paragraph)
960
+ .replace('hr', hr)
987
961
  .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
988
962
  .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
989
963
  .replace('|table', '')
@@ -991,54 +965,68 @@
991
965
  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
992
966
  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
993
967
  .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
994
- .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
968
+ .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
995
969
  .getRegex();
996
- block.blockquote = edit(block.blockquote)
997
- .replace('paragraph', block.paragraph)
970
+ const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/)
971
+ .replace('paragraph', paragraph)
998
972
  .getRegex();
999
973
  /**
1000
974
  * Normal Block Grammar
1001
975
  */
1002
- block.normal = { ...block };
976
+ const blockNormal = {
977
+ blockquote,
978
+ code: blockCode,
979
+ def,
980
+ fences,
981
+ heading,
982
+ hr,
983
+ html,
984
+ lheading,
985
+ list,
986
+ newline,
987
+ paragraph,
988
+ table: noopTest,
989
+ text: blockText
990
+ };
1003
991
  /**
1004
992
  * GFM Block Grammar
1005
993
  */
1006
- block.gfm = {
1007
- ...block.normal,
1008
- table: '^ *([^\\n ].*)\\n' // Header
1009
- + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
1010
- + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
1011
- };
1012
- block.gfm.table = edit(block.gfm.table)
1013
- .replace('hr', block.hr)
994
+ const gfmTable = edit('^ *([^\\n ].*)\\n' // Header
995
+ + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
996
+ + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells
997
+ .replace('hr', hr)
1014
998
  .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1015
999
  .replace('blockquote', ' {0,3}>')
1016
1000
  .replace('code', ' {4}[^\\n]')
1017
1001
  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1018
1002
  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1019
1003
  .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
1020
- .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
1021
- .getRegex();
1022
- block.gfm.paragraph = edit(block._paragraph)
1023
- .replace('hr', block.hr)
1024
- .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1025
- .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
1026
- .replace('table', block.gfm.table) // interrupt paragraphs with table
1027
- .replace('blockquote', ' {0,3}>')
1028
- .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1029
- .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1030
- .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
1031
- .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
1004
+ .replace('tag', _tag) // tables can be interrupted by type (6) html blocks
1032
1005
  .getRegex();
1006
+ const blockGfm = {
1007
+ ...blockNormal,
1008
+ table: gfmTable,
1009
+ paragraph: edit(_paragraph)
1010
+ .replace('hr', hr)
1011
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1012
+ .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
1013
+ .replace('table', gfmTable) // interrupt paragraphs with table
1014
+ .replace('blockquote', ' {0,3}>')
1015
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1016
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1017
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
1018
+ .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
1019
+ .getRegex()
1020
+ };
1033
1021
  /**
1034
1022
  * Pedantic grammar (original John Gruber's loose markdown specification)
1035
1023
  */
1036
- block.pedantic = {
1037
- ...block.normal,
1024
+ const blockPedantic = {
1025
+ ...blockNormal,
1038
1026
  html: edit('^ *(?:comment *(?:\\n|\\s*$)'
1039
1027
  + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
1040
1028
  + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
1041
- .replace('comment', block._comment)
1029
+ .replace('comment', _comment)
1042
1030
  .replace(/tag/g, '(?!(?:'
1043
1031
  + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
1044
1032
  + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
@@ -1046,157 +1034,164 @@
1046
1034
  .getRegex(),
1047
1035
  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
1048
1036
  heading: /^(#{1,6})(.*)(?:\n+|$)/,
1049
- fences: noopTest,
1037
+ fences: noopTest, // fences not supported
1050
1038
  lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
1051
- paragraph: edit(block.normal._paragraph)
1052
- .replace('hr', block.hr)
1039
+ paragraph: edit(_paragraph)
1040
+ .replace('hr', hr)
1053
1041
  .replace('heading', ' *#{1,6} *[^\n]')
1054
- .replace('lheading', block.lheading)
1042
+ .replace('lheading', lheading)
1043
+ .replace('|table', '')
1055
1044
  .replace('blockquote', ' {0,3}>')
1056
1045
  .replace('|fences', '')
1057
1046
  .replace('|list', '')
1058
1047
  .replace('|html', '')
1048
+ .replace('|tag', '')
1059
1049
  .getRegex()
1060
1050
  };
1061
1051
  /**
1062
1052
  * Inline-Level Grammar
1063
1053
  */
1064
- // Not all rules are defined in the object literal
1065
- // @ts-expect-error
1066
- const inline = {
1067
- escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
1068
- autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
1069
- url: noopTest,
1070
- tag: '^comment'
1071
- + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
1072
- + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
1073
- + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
1074
- + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
1075
- + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
1076
- link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
1077
- reflink: /^!?\[(label)\]\[(ref)\]/,
1078
- nolink: /^!?\[(ref)\](?:\[\])?/,
1079
- reflinkSearch: 'reflink|nolink(?!\\()',
1080
- emStrong: {
1081
- lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
1082
- // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
1083
- // | Skip orphan inside strong | Consume to delim | (1) #*** | (2) a***#, a*** | (3) #***a, ***a | (4) ***# | (5) #***# | (6) a***a
1084
- rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
1085
- rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ // ^- Not allowed for _
1086
- },
1087
- code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
1088
- br: /^( {2,}|\\)\n(?!\s*$)/,
1089
- del: noopTest,
1090
- text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
1091
- punctuation: /^((?![*_])[\spunctuation])/
1092
- };
1054
+ const escape = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
1055
+ const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
1056
+ const br = /^( {2,}|\\)\n(?!\s*$)/;
1057
+ const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
1093
1058
  // list of unicode punctuation marks, plus any missing characters from CommonMark spec
1094
- inline._punctuation = '\\p{P}$+<=>`^|~';
1095
- inline.punctuation = edit(inline.punctuation, 'u').replace(/punctuation/g, inline._punctuation).getRegex();
1059
+ const _punctuation = '\\p{P}$+<=>`^|~';
1060
+ const punctuation = edit(/^((?![*_])[\spunctuation])/, 'u')
1061
+ .replace(/punctuation/g, _punctuation).getRegex();
1096
1062
  // sequences em should skip over [title](link), `code`, <html>
1097
- inline.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
1098
- inline.anyPunctuation = /\\[punct]/g;
1099
- inline._escapes = /\\([punct])/g;
1100
- inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
1101
- inline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')
1102
- .replace(/punct/g, inline._punctuation)
1103
- .getRegex();
1104
- inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')
1105
- .replace(/punct/g, inline._punctuation)
1063
+ const blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
1064
+ const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, 'u')
1065
+ .replace(/punct/g, _punctuation)
1106
1066
  .getRegex();
1107
- inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'gu')
1108
- .replace(/punct/g, inline._punctuation)
1067
+ const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
1068
+ + '|[^*]+(?=[^*])' // Consume to delim
1069
+ + '|(?!\\*)[punct](\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
1070
+ + '|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)' // (2) a***#, a*** can only be a Right Delimiter
1071
+ + '|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])' // (3) #***a, ***a can only be Left Delimiter
1072
+ + '|[\\s](\\*+)(?!\\*)(?=[punct])' // (4) ***# can only be Left Delimiter
1073
+ + '|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])' // (5) #***# can be either Left or Right Delimiter
1074
+ + '|[^punct\\s](\\*+)(?=[^punct\\s])', 'gu') // (6) a***a can be either Left or Right Delimiter
1075
+ .replace(/punct/g, _punctuation)
1109
1076
  .getRegex();
1110
- inline.anyPunctuation = edit(inline.anyPunctuation, 'gu')
1111
- .replace(/punct/g, inline._punctuation)
1077
+ // (6) Not allowed for _
1078
+ const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
1079
+ + '|[^_]+(?=[^_])' // Consume to delim
1080
+ + '|(?!_)[punct](_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter
1081
+ + '|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)' // (2) a___#, a___ can only be a Right Delimiter
1082
+ + '|(?!_)[punct\\s](_+)(?=[^punct\\s])' // (3) #___a, ___a can only be Left Delimiter
1083
+ + '|[\\s](_+)(?!_)(?=[punct])' // (4) ___# can only be Left Delimiter
1084
+ + '|(?!_)[punct](_+)(?!_)(?=[punct])', 'gu') // (5) #___# can be either Left or Right Delimiter
1085
+ .replace(/punct/g, _punctuation)
1112
1086
  .getRegex();
1113
- inline._escapes = edit(inline._escapes, 'gu')
1114
- .replace(/punct/g, inline._punctuation)
1087
+ const anyPunctuation = edit(/\\([punct])/, 'gu')
1088
+ .replace(/punct/g, _punctuation)
1115
1089
  .getRegex();
1116
- inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
1117
- inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
1118
- inline.autolink = edit(inline.autolink)
1119
- .replace('scheme', inline._scheme)
1120
- .replace('email', inline._email)
1090
+ const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/)
1091
+ .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)
1092
+ .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)
1121
1093
  .getRegex();
1122
- inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
1123
- inline.tag = edit(inline.tag)
1124
- .replace('comment', inline._comment)
1125
- .replace('attribute', inline._attribute)
1094
+ const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();
1095
+ const tag = edit('^comment'
1096
+ + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
1097
+ + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
1098
+ + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
1099
+ + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
1100
+ + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section
1101
+ .replace('comment', _inlineComment)
1102
+ .replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/)
1126
1103
  .getRegex();
1127
- inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
1128
- inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
1129
- inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
1130
- inline.link = edit(inline.link)
1131
- .replace('label', inline._label)
1132
- .replace('href', inline._href)
1133
- .replace('title', inline._title)
1104
+ const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
1105
+ const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/)
1106
+ .replace('label', _inlineLabel)
1107
+ .replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/)
1108
+ .replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/)
1134
1109
  .getRegex();
1135
- inline.reflink = edit(inline.reflink)
1136
- .replace('label', inline._label)
1137
- .replace('ref', block._label)
1110
+ const reflink = edit(/^!?\[(label)\]\[(ref)\]/)
1111
+ .replace('label', _inlineLabel)
1112
+ .replace('ref', _blockLabel)
1138
1113
  .getRegex();
1139
- inline.nolink = edit(inline.nolink)
1140
- .replace('ref', block._label)
1114
+ const nolink = edit(/^!?\[(ref)\](?:\[\])?/)
1115
+ .replace('ref', _blockLabel)
1141
1116
  .getRegex();
1142
- inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
1143
- .replace('reflink', inline.reflink)
1144
- .replace('nolink', inline.nolink)
1117
+ const reflinkSearch = edit('reflink|nolink(?!\\()', 'g')
1118
+ .replace('reflink', reflink)
1119
+ .replace('nolink', nolink)
1145
1120
  .getRegex();
1146
1121
  /**
1147
1122
  * Normal Inline Grammar
1148
1123
  */
1149
- inline.normal = { ...inline };
1124
+ const inlineNormal = {
1125
+ _backpedal: noopTest, // only used for GFM url
1126
+ anyPunctuation,
1127
+ autolink,
1128
+ blockSkip,
1129
+ br,
1130
+ code: inlineCode,
1131
+ del: noopTest,
1132
+ emStrongLDelim,
1133
+ emStrongRDelimAst,
1134
+ emStrongRDelimUnd,
1135
+ escape,
1136
+ link,
1137
+ nolink,
1138
+ punctuation,
1139
+ reflink,
1140
+ reflinkSearch,
1141
+ tag,
1142
+ text: inlineText,
1143
+ url: noopTest
1144
+ };
1150
1145
  /**
1151
1146
  * Pedantic Inline Grammar
1152
1147
  */
1153
- inline.pedantic = {
1154
- ...inline.normal,
1155
- strong: {
1156
- start: /^__|\*\*/,
1157
- middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
1158
- endAst: /\*\*(?!\*)/g,
1159
- endUnd: /__(?!_)/g
1160
- },
1161
- em: {
1162
- start: /^_|\*/,
1163
- middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
1164
- endAst: /\*(?!\*)/g,
1165
- endUnd: /_(?!_)/g
1166
- },
1148
+ const inlinePedantic = {
1149
+ ...inlineNormal,
1167
1150
  link: edit(/^!?\[(label)\]\((.*?)\)/)
1168
- .replace('label', inline._label)
1151
+ .replace('label', _inlineLabel)
1169
1152
  .getRegex(),
1170
1153
  reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
1171
- .replace('label', inline._label)
1154
+ .replace('label', _inlineLabel)
1172
1155
  .getRegex()
1173
1156
  };
1174
1157
  /**
1175
1158
  * GFM Inline Grammar
1176
1159
  */
1177
- inline.gfm = {
1178
- ...inline.normal,
1179
- escape: edit(inline.escape).replace('])', '~|])').getRegex(),
1180
- _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
1181
- url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
1160
+ const inlineGfm = {
1161
+ ...inlineNormal,
1162
+ escape: edit(escape).replace('])', '~|])').getRegex(),
1163
+ url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i')
1164
+ .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)
1165
+ .getRegex(),
1182
1166
  _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
1183
1167
  del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
1184
1168
  text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
1185
1169
  };
1186
- inline.gfm.url = edit(inline.gfm.url, 'i')
1187
- .replace('email', inline.gfm._extended_email)
1188
- .getRegex();
1189
1170
  /**
1190
1171
  * GFM + Line Breaks Inline Grammar
1191
1172
  */
1192
- inline.breaks = {
1193
- ...inline.gfm,
1194
- br: edit(inline.br).replace('{2,}', '*').getRegex(),
1195
- text: edit(inline.gfm.text)
1173
+ const inlineBreaks = {
1174
+ ...inlineGfm,
1175
+ br: edit(br).replace('{2,}', '*').getRegex(),
1176
+ text: edit(inlineGfm.text)
1196
1177
  .replace('\\b_', '\\b_| {2,}\\n')
1197
1178
  .replace(/\{2,\}/g, '*')
1198
1179
  .getRegex()
1199
1180
  };
1181
+ /**
1182
+ * exports
1183
+ */
1184
+ const block = {
1185
+ normal: blockNormal,
1186
+ gfm: blockGfm,
1187
+ pedantic: blockPedantic
1188
+ };
1189
+ const inline = {
1190
+ normal: inlineNormal,
1191
+ gfm: inlineGfm,
1192
+ breaks: inlineBreaks,
1193
+ pedantic: inlinePedantic
1194
+ };
1200
1195
 
1201
1196
  /**
1202
1197
  * Block Lexer
@@ -1209,7 +1204,6 @@
1209
1204
  inlineQueue;
1210
1205
  constructor(options) {
1211
1206
  // TokenList cannot be created in one go
1212
- // @ts-expect-error
1213
1207
  this.tokens = [];
1214
1208
  this.tokens.links = Object.create(null);
1215
1209
  this.options = options || exports.defaults;
@@ -1643,13 +1637,13 @@
1643
1637
  code = code.replace(/\n$/, '') + '\n';
1644
1638
  if (!lang) {
1645
1639
  return '<pre><code>'
1646
- + (escaped ? code : escape(code, true))
1640
+ + (escaped ? code : escape$1(code, true))
1647
1641
  + '</code></pre>\n';
1648
1642
  }
1649
1643
  return '<pre><code class="language-'
1650
- + escape(lang)
1644
+ + escape$1(lang)
1651
1645
  + '">'
1652
- + (escaped ? code : escape(code, true))
1646
+ + (escaped ? code : escape$1(code, true))
1653
1647
  + '</code></pre>\n';
1654
1648
  }
1655
1649
  blockquote(quote) {
@@ -2173,11 +2167,18 @@
2173
2167
  if (pack.renderer) {
2174
2168
  const renderer = this.defaults.renderer || new _Renderer(this.defaults);
2175
2169
  for (const prop in pack.renderer) {
2176
- const rendererFunc = pack.renderer[prop];
2177
- const rendererKey = prop;
2178
- const prevRenderer = renderer[rendererKey];
2170
+ if (!(prop in renderer)) {
2171
+ throw new Error(`renderer '${prop}' does not exist`);
2172
+ }
2173
+ if (prop === 'options') {
2174
+ // ignore options property
2175
+ continue;
2176
+ }
2177
+ const rendererProp = prop;
2178
+ const rendererFunc = pack.renderer[rendererProp];
2179
+ const prevRenderer = renderer[rendererProp];
2179
2180
  // Replace renderer with func to run extension, but fall back if false
2180
- renderer[rendererKey] = (...args) => {
2181
+ renderer[rendererProp] = (...args) => {
2181
2182
  let ret = rendererFunc.apply(renderer, args);
2182
2183
  if (ret === false) {
2183
2184
  ret = prevRenderer.apply(renderer, args);
@@ -2190,11 +2191,19 @@
2190
2191
  if (pack.tokenizer) {
2191
2192
  const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
2192
2193
  for (const prop in pack.tokenizer) {
2193
- const tokenizerFunc = pack.tokenizer[prop];
2194
- const tokenizerKey = prop;
2195
- const prevTokenizer = tokenizer[tokenizerKey];
2194
+ if (!(prop in tokenizer)) {
2195
+ throw new Error(`tokenizer '${prop}' does not exist`);
2196
+ }
2197
+ if (['options', 'rules', 'lexer'].includes(prop)) {
2198
+ // ignore options, rules, and lexer properties
2199
+ continue;
2200
+ }
2201
+ const tokenizerProp = prop;
2202
+ const tokenizerFunc = pack.tokenizer[tokenizerProp];
2203
+ const prevTokenizer = tokenizer[tokenizerProp];
2196
2204
  // Replace tokenizer with func to run extension, but fall back if false
2197
- tokenizer[tokenizerKey] = (...args) => {
2205
+ // @ts-expect-error cannot type tokenizer function dynamically
2206
+ tokenizer[tokenizerProp] = (...args) => {
2198
2207
  let ret = tokenizerFunc.apply(tokenizer, args);
2199
2208
  if (ret === false) {
2200
2209
  ret = prevTokenizer.apply(tokenizer, args);
@@ -2208,11 +2217,18 @@
2208
2217
  if (pack.hooks) {
2209
2218
  const hooks = this.defaults.hooks || new _Hooks();
2210
2219
  for (const prop in pack.hooks) {
2211
- const hooksFunc = pack.hooks[prop];
2212
- const hooksKey = prop;
2213
- const prevHook = hooks[hooksKey];
2220
+ if (!(prop in hooks)) {
2221
+ throw new Error(`hook '${prop}' does not exist`);
2222
+ }
2223
+ if (prop === 'options') {
2224
+ // ignore options property
2225
+ continue;
2226
+ }
2227
+ const hooksProp = prop;
2228
+ const hooksFunc = pack.hooks[hooksProp];
2229
+ const prevHook = hooks[hooksProp];
2214
2230
  if (_Hooks.passThroughHooks.has(prop)) {
2215
- hooks[hooksKey] = (arg) => {
2231
+ hooks[hooksProp] = (arg) => {
2216
2232
  if (this.defaults.async) {
2217
2233
  return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
2218
2234
  return prevHook.call(hooks, ret);
@@ -2223,7 +2239,7 @@
2223
2239
  };
2224
2240
  }
2225
2241
  else {
2226
- hooks[hooksKey] = (...args) => {
2242
+ hooks[hooksProp] = (...args) => {
2227
2243
  let ret = hooksFunc.apply(hooks, args);
2228
2244
  if (ret === false) {
2229
2245
  ret = prevHook.apply(hooks, args);
@@ -2316,7 +2332,7 @@
2316
2332
  e.message += '\nPlease report this to https://github.com/markedjs/marked.';
2317
2333
  if (silent) {
2318
2334
  const msg = '<p>An error occurred:</p><pre>'
2319
- + escape(e.message + '', true)
2335
+ + escape$1(e.message + '', true)
2320
2336
  + '</pre>';
2321
2337
  if (async) {
2322
2338
  return Promise.resolve(msg);