marked 7.0.2 → 7.0.4

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,5 +1,5 @@
1
1
  /**
2
- * marked v7.0.2 - a markdown parser
2
+ * marked v7.0.4 - a markdown parser
3
3
  * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
4
4
  * https://github.com/markedjs/marked
5
5
  */
@@ -168,7 +168,8 @@ function splitCells(tableRow, count) {
168
168
  // ensure that every cell-delimiting pipe has a space
169
169
  // before it to distinguish it from an escaped pipe
170
170
  const row = tableRow.replace(/\|/g, (match, offset, str) => {
171
- let escaped = false, curr = offset;
171
+ let escaped = false;
172
+ let curr = offset;
172
173
  while (--curr >= 0 && str[curr] === '\\')
173
174
  escaped = !escaped;
174
175
  if (escaped) {
@@ -238,9 +239,8 @@ function findClosingBracket(str, b) {
238
239
  if (str.indexOf(b[1]) === -1) {
239
240
  return -1;
240
241
  }
241
- const l = str.length;
242
- let level = 0, i = 0;
243
- for (; i < l; i++) {
242
+ let level = 0;
243
+ for (let i = 0; i < str.length; i++) {
244
244
  if (str[i] === '\\') {
245
245
  i++;
246
246
  }
@@ -337,6 +337,7 @@ function indentCodeCompensation(raw, text) {
337
337
  */
338
338
  class _Tokenizer {
339
339
  options;
340
+ // TODO: Fix this rules type
340
341
  rules;
341
342
  lexer;
342
343
  constructor(options) {
@@ -430,7 +431,6 @@ class _Tokenizer {
430
431
  list(src) {
431
432
  let cap = this.rules.block.list.exec(src);
432
433
  if (cap) {
433
- let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
434
434
  let bull = cap[1].trim();
435
435
  const isordered = bull.length > 1;
436
436
  const list = {
@@ -447,9 +447,12 @@ class _Tokenizer {
447
447
  }
448
448
  // Get next list item
449
449
  const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
450
+ let raw = '';
451
+ let itemContents = '';
452
+ let endsWithBlankLine = false;
450
453
  // Check if current bullet point can start a new List Item
451
454
  while (src) {
452
- endEarly = false;
455
+ let endEarly = false;
453
456
  if (!(cap = itemRegex.exec(src))) {
454
457
  break;
455
458
  }
@@ -458,8 +461,9 @@ class _Tokenizer {
458
461
  }
459
462
  raw = cap[0];
460
463
  src = src.substring(raw.length);
461
- line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
462
- nextLine = src.split('\n', 1)[0];
464
+ let line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
465
+ let nextLine = src.split('\n', 1)[0];
466
+ let indent = 0;
463
467
  if (this.options.pedantic) {
464
468
  indent = 2;
465
469
  itemContents = line.trimLeft();
@@ -470,7 +474,7 @@ class _Tokenizer {
470
474
  itemContents = line.slice(indent);
471
475
  indent += cap[1].length;
472
476
  }
473
- blankLine = false;
477
+ let blankLine = false;
474
478
  if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
475
479
  raw += nextLine + '\n';
476
480
  src = src.substring(nextLine.length + 1);
@@ -483,7 +487,7 @@ class _Tokenizer {
483
487
  const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
484
488
  // Check if following lines should be included in List Item
485
489
  while (src) {
486
- rawLine = src.split('\n', 1)[0];
490
+ const rawLine = src.split('\n', 1)[0];
487
491
  nextLine = rawLine;
488
492
  // Re-align to follow commonmark nesting rules
489
493
  if (this.options.pedantic) {
@@ -545,6 +549,8 @@ class _Tokenizer {
545
549
  endsWithBlankLine = true;
546
550
  }
547
551
  }
552
+ let istask = null;
553
+ let ischecked;
548
554
  // Check for task list items
549
555
  if (this.options.gfm) {
550
556
  istask = /^\[[ xX]\] /.exec(itemContents);
@@ -559,7 +565,8 @@ class _Tokenizer {
559
565
  task: !!istask,
560
566
  checked: ischecked,
561
567
  loose: false,
562
- text: itemContents
568
+ text: itemContents,
569
+ tokens: []
563
570
  });
564
571
  list.raw += raw;
565
572
  }
@@ -567,9 +574,8 @@ class _Tokenizer {
567
574
  list.items[list.items.length - 1].raw = raw.trimRight();
568
575
  list.items[list.items.length - 1].text = itemContents.trimRight();
569
576
  list.raw = list.raw.trimRight();
570
- const l = list.items.length;
571
577
  // Item child tokens handled here at end because we needed to have the final item to trim it first
572
- for (i = 0; i < l; i++) {
578
+ for (let i = 0; i < list.items.length; i++) {
573
579
  this.lexer.state.top = false;
574
580
  list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
575
581
  if (!list.loose) {
@@ -581,7 +587,7 @@ class _Tokenizer {
581
587
  }
582
588
  // Set all items to loose if list is loose
583
589
  if (list.loose) {
584
- for (i = 0; i < l; i++) {
590
+ for (let i = 0; i < list.items.length; i++) {
585
591
  list.items[i].loose = true;
586
592
  }
587
593
  }
@@ -631,7 +637,7 @@ class _Tokenizer {
631
637
  type: 'table',
632
638
  raw: cap[0],
633
639
  header: splitCells(cap[1]).map(c => {
634
- return { text: c };
640
+ return { text: c, tokens: [] };
635
641
  }),
636
642
  align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
637
643
  rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
@@ -640,23 +646,26 @@ class _Tokenizer {
640
646
  let l = item.align.length;
641
647
  let i, j, k, row;
642
648
  for (i = 0; i < l; i++) {
643
- if (/^ *-+: *$/.test(item.align[i])) {
644
- item.align[i] = 'right';
645
- }
646
- else if (/^ *:-+: *$/.test(item.align[i])) {
647
- item.align[i] = 'center';
648
- }
649
- else if (/^ *:-+ *$/.test(item.align[i])) {
650
- item.align[i] = 'left';
651
- }
652
- else {
653
- item.align[i] = null;
649
+ const align = item.align[i];
650
+ if (align) {
651
+ if (/^ *-+: *$/.test(align)) {
652
+ item.align[i] = 'right';
653
+ }
654
+ else if (/^ *:-+: *$/.test(align)) {
655
+ item.align[i] = 'center';
656
+ }
657
+ else if (/^ *:-+ *$/.test(align)) {
658
+ item.align[i] = 'left';
659
+ }
660
+ else {
661
+ item.align[i] = null;
662
+ }
654
663
  }
655
664
  }
656
665
  l = item.rows.length;
657
666
  for (i = 0; i < l; i++) {
658
667
  item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
659
- return { text: c };
668
+ return { text: c, tokens: [] };
660
669
  });
661
670
  }
662
671
  // parse child tokens inside headers and cells
@@ -836,7 +845,8 @@ class _Tokenizer {
836
845
  return;
837
846
  const nextChar = match[1] || match[2] || '';
838
847
  if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
839
- const lLength = match[0].length - 1;
848
+ // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
849
+ const lLength = [...match[0]].length - 1;
840
850
  let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
841
851
  const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
842
852
  endReg.lastIndex = 0;
@@ -846,7 +856,7 @@ class _Tokenizer {
846
856
  rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
847
857
  if (!rDelim)
848
858
  continue; // skip single * in __abc*abc__
849
- rLength = rDelim.length;
859
+ rLength = [...rDelim].length;
850
860
  if (match[3] || match[4]) { // found another Left Delim
851
861
  delimTotal += rLength;
852
862
  continue;
@@ -862,7 +872,7 @@ class _Tokenizer {
862
872
  continue; // Haven't found enough closing delimiters
863
873
  // Remove extra characters. *a*** -> *a*
864
874
  rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
865
- const raw = src.slice(0, lLength + match.index + rLength + 1);
875
+ const raw = [...src].slice(0, lLength + match.index + rLength + 1).join('');
866
876
  // Create `em` if smallest delimiter has odd char count. *a***
867
877
  if (Math.min(lLength, rLength) % 2) {
868
878
  const text = raw.slice(1, -1);
@@ -1306,13 +1316,11 @@ function smartypants(text) {
1306
1316
  * mangle email addresses
1307
1317
  */
1308
1318
  function mangle(text) {
1309
- let out = '', i, ch;
1310
- const l = text.length;
1311
- for (i = 0; i < l; i++) {
1312
- ch = text.charCodeAt(i);
1313
- if (Math.random() > 0.5) {
1314
- ch = 'x' + ch.toString(16);
1315
- }
1319
+ let out = '';
1320
+ for (let i = 0; i < text.length; i++) {
1321
+ const ch = Math.random() > 0.5
1322
+ ? 'x' + text.charCodeAt(i).toString(16)
1323
+ : text.charCodeAt(i).toString();
1316
1324
  out += '&#' + ch + ';';
1317
1325
  }
1318
1326
  return out;
@@ -1758,7 +1766,7 @@ class _Renderer {
1758
1766
  this.options = options || _defaults;
1759
1767
  }
1760
1768
  code(code, infostring, escaped) {
1761
- const lang = (infostring || '').match(/\S*/)[0];
1769
+ const lang = (infostring || '').match(/^\S*/)?.[0];
1762
1770
  if (this.options.highlight) {
1763
1771
  const out = this.options.highlight(code, lang);
1764
1772
  if (out != null && out !== code) {
@@ -1797,7 +1805,8 @@ class _Renderer {
1797
1805
  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
1798
1806
  }
1799
1807
  list(body, ordered, start) {
1800
- const type = ordered ? 'ol' : 'ul', startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1808
+ const type = ordered ? 'ol' : 'ul';
1809
+ const startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1801
1810
  return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
1802
1811
  }
1803
1812
  listitem(text, task, checked) {
@@ -1852,10 +1861,11 @@ class _Renderer {
1852
1861
  return `<del>${text}</del>`;
1853
1862
  }
1854
1863
  link(href, title, text) {
1855
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1856
- if (href === null) {
1864
+ const cleanHref = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1865
+ if (cleanHref === null) {
1857
1866
  return text;
1858
1867
  }
1868
+ href = cleanHref;
1859
1869
  let out = '<a href="' + href + '"';
1860
1870
  if (title) {
1861
1871
  out += ' title="' + title + '"';
@@ -1864,10 +1874,11 @@ class _Renderer {
1864
1874
  return out;
1865
1875
  }
1866
1876
  image(href, title, text) {
1867
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1868
- if (href === null) {
1877
+ const cleanHref = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1878
+ if (cleanHref === null) {
1869
1879
  return text;
1870
1880
  }
1881
+ href = cleanHref;
1871
1882
  let out = `<img src="${href}" alt="${text}"`;
1872
1883
  if (title) {
1873
1884
  out += ` title="${title}"`;
@@ -1995,14 +2006,14 @@ class _Parser {
1995
2006
  * Parse Loop
1996
2007
  */
1997
2008
  parse(tokens, top = true) {
1998
- let out = '', i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
1999
- const l = tokens.length;
2000
- for (i = 0; i < l; i++) {
2001
- token = tokens[i];
2009
+ let out = '';
2010
+ for (let i = 0; i < tokens.length; i++) {
2011
+ const token = tokens[i];
2002
2012
  // Run any renderer extensions
2003
2013
  if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2004
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2005
- if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
2014
+ const genericToken = token;
2015
+ const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
2016
+ if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
2006
2017
  out += ret || '';
2007
2018
  continue;
2008
2019
  }
@@ -2016,30 +2027,30 @@ class _Parser {
2016
2027
  continue;
2017
2028
  }
2018
2029
  case 'heading': {
2019
- out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
2030
+ const headingToken = token;
2031
+ out += this.renderer.heading(this.parseInline(headingToken.tokens), headingToken.depth, unescape(this.parseInline(headingToken.tokens, this.textRenderer)), this.slugger);
2020
2032
  continue;
2021
2033
  }
2022
2034
  case 'code': {
2023
- out += this.renderer.code(token.text, token.lang, !!token.escaped);
2035
+ const codeToken = token;
2036
+ out += this.renderer.code(codeToken.text, codeToken.lang, !!codeToken.escaped);
2024
2037
  continue;
2025
2038
  }
2026
2039
  case 'table': {
2027
- header = '';
2040
+ const tableToken = token;
2041
+ let header = '';
2028
2042
  // header
2029
- cell = '';
2030
- l2 = token.header.length;
2031
- for (j = 0; j < l2; j++) {
2032
- cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { header: true, align: token.align[j] });
2043
+ let cell = '';
2044
+ for (let j = 0; j < tableToken.header.length; j++) {
2045
+ cell += this.renderer.tablecell(this.parseInline(tableToken.header[j].tokens), { header: true, align: tableToken.align[j] });
2033
2046
  }
2034
2047
  header += this.renderer.tablerow(cell);
2035
- body = '';
2036
- l2 = token.rows.length;
2037
- for (j = 0; j < l2; j++) {
2038
- row = token.rows[j];
2048
+ let body = '';
2049
+ for (let j = 0; j < tableToken.rows.length; j++) {
2050
+ const row = tableToken.rows[j];
2039
2051
  cell = '';
2040
- l3 = row.length;
2041
- for (k = 0; k < l3; k++) {
2042
- cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: token.align[k] });
2052
+ for (let k = 0; k < row.length; k++) {
2053
+ cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: tableToken.align[k] });
2043
2054
  }
2044
2055
  body += this.renderer.tablerow(cell);
2045
2056
  }
@@ -2047,23 +2058,24 @@ class _Parser {
2047
2058
  continue;
2048
2059
  }
2049
2060
  case 'blockquote': {
2050
- body = this.parse(token.tokens);
2061
+ const blockquoteToken = token;
2062
+ const body = this.parse(blockquoteToken.tokens);
2051
2063
  out += this.renderer.blockquote(body);
2052
2064
  continue;
2053
2065
  }
2054
2066
  case 'list': {
2055
- ordered = token.ordered;
2056
- start = token.start;
2057
- loose = token.loose;
2058
- l2 = token.items.length;
2059
- body = '';
2060
- for (j = 0; j < l2; j++) {
2061
- item = token.items[j];
2062
- checked = item.checked;
2063
- task = item.task;
2064
- itemBody = '';
2067
+ const listToken = token;
2068
+ const ordered = listToken.ordered;
2069
+ const start = listToken.start;
2070
+ const loose = listToken.loose;
2071
+ let body = '';
2072
+ for (let j = 0; j < listToken.items.length; j++) {
2073
+ const item = listToken.items[j];
2074
+ const checked = item.checked;
2075
+ const task = item.task;
2076
+ let itemBody = '';
2065
2077
  if (item.task) {
2066
- checkbox = this.renderer.checkbox(!!checked);
2078
+ const checkbox = this.renderer.checkbox(!!checked);
2067
2079
  if (loose) {
2068
2080
  if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
2069
2081
  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
@@ -2089,18 +2101,21 @@ class _Parser {
2089
2101
  continue;
2090
2102
  }
2091
2103
  case 'html': {
2092
- out += this.renderer.html(token.text, token.block);
2104
+ const htmlToken = token;
2105
+ out += this.renderer.html(htmlToken.text, htmlToken.block);
2093
2106
  continue;
2094
2107
  }
2095
2108
  case 'paragraph': {
2096
- out += this.renderer.paragraph(this.parseInline(token.tokens));
2109
+ const paragraphToken = token;
2110
+ out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens));
2097
2111
  continue;
2098
2112
  }
2099
2113
  case 'text': {
2100
- body = token.tokens ? this.parseInline(token.tokens) : token.text;
2101
- while (i + 1 < l && tokens[i + 1].type === 'text') {
2102
- token = tokens[++i];
2103
- body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
2114
+ let textToken = token;
2115
+ let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text;
2116
+ while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
2117
+ textToken = tokens[++i];
2118
+ body += '\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text);
2104
2119
  }
2105
2120
  out += top ? this.renderer.paragraph(body) : body;
2106
2121
  continue;
@@ -2124,13 +2139,12 @@ class _Parser {
2124
2139
  */
2125
2140
  parseInline(tokens, renderer) {
2126
2141
  renderer = renderer || this.renderer;
2127
- let out = '', i, token, ret;
2128
- const l = tokens.length;
2129
- for (i = 0; i < l; i++) {
2130
- token = tokens[i];
2142
+ let out = '';
2143
+ for (let i = 0; i < tokens.length; i++) {
2144
+ const token = tokens[i];
2131
2145
  // Run any renderer extensions
2132
2146
  if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2133
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2147
+ const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2134
2148
  if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
2135
2149
  out += ret || '';
2136
2150
  continue;
@@ -2138,31 +2152,38 @@ class _Parser {
2138
2152
  }
2139
2153
  switch (token.type) {
2140
2154
  case 'escape': {
2141
- out += renderer.text(token.text);
2155
+ const escapeToken = token;
2156
+ out += renderer.text(escapeToken.text);
2142
2157
  break;
2143
2158
  }
2144
2159
  case 'html': {
2145
- out += renderer.html(token.text);
2160
+ const tagToken = token;
2161
+ out += renderer.html(tagToken.text);
2146
2162
  break;
2147
2163
  }
2148
2164
  case 'link': {
2149
- out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
2165
+ const linkToken = token;
2166
+ out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer));
2150
2167
  break;
2151
2168
  }
2152
2169
  case 'image': {
2153
- out += renderer.image(token.href, token.title, token.text);
2170
+ const imageToken = token;
2171
+ out += renderer.image(imageToken.href, imageToken.title, imageToken.text);
2154
2172
  break;
2155
2173
  }
2156
2174
  case 'strong': {
2157
- out += renderer.strong(this.parseInline(token.tokens, renderer));
2175
+ const strongToken = token;
2176
+ out += renderer.strong(this.parseInline(strongToken.tokens, renderer));
2158
2177
  break;
2159
2178
  }
2160
2179
  case 'em': {
2161
- out += renderer.em(this.parseInline(token.tokens, renderer));
2180
+ const emToken = token;
2181
+ out += renderer.em(this.parseInline(emToken.tokens, renderer));
2162
2182
  break;
2163
2183
  }
2164
2184
  case 'codespan': {
2165
- out += renderer.codespan(token.text);
2185
+ const codespanToken = token;
2186
+ out += renderer.codespan(codespanToken.text);
2166
2187
  break;
2167
2188
  }
2168
2189
  case 'br': {
@@ -2170,11 +2191,13 @@ class _Parser {
2170
2191
  break;
2171
2192
  }
2172
2193
  case 'del': {
2173
- out += renderer.del(this.parseInline(token.tokens, renderer));
2194
+ const delToken = token;
2195
+ out += renderer.del(this.parseInline(delToken.tokens, renderer));
2174
2196
  break;
2175
2197
  }
2176
2198
  case 'text': {
2177
- out += renderer.text(token.text);
2199
+ const textToken = token;
2200
+ out += renderer.text(textToken.text);
2178
2201
  break;
2179
2202
  }
2180
2203
  default: {
@@ -2242,10 +2265,11 @@ class Marked {
2242
2265
  values = values.concat(callback.call(this, token));
2243
2266
  switch (token.type) {
2244
2267
  case 'table': {
2245
- for (const cell of token.header) {
2268
+ const tableToken = token;
2269
+ for (const cell of tableToken.header) {
2246
2270
  values = values.concat(this.walkTokens(cell.tokens, callback));
2247
2271
  }
2248
- for (const row of token.rows) {
2272
+ for (const row of tableToken.rows) {
2249
2273
  for (const cell of row) {
2250
2274
  values = values.concat(this.walkTokens(cell.tokens, callback));
2251
2275
  }
@@ -2253,18 +2277,19 @@ class Marked {
2253
2277
  break;
2254
2278
  }
2255
2279
  case 'list': {
2256
- values = values.concat(this.walkTokens(token.items, callback));
2280
+ const listToken = token;
2281
+ values = values.concat(this.walkTokens(listToken.items, callback));
2257
2282
  break;
2258
2283
  }
2259
2284
  default: {
2260
- if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { // Walk any extensions
2261
- this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
2262
- // @ts-expect-error we assume token[childToken] is an array of tokens but we can't be sure
2263
- values = values.concat(this.walkTokens(token[childTokens], callback));
2285
+ const genericToken = token;
2286
+ if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
2287
+ this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
2288
+ values = values.concat(this.walkTokens(genericToken[childTokens], callback));
2264
2289
  });
2265
2290
  }
2266
- else if (token.tokens) {
2267
- values = values.concat(this.walkTokens(token.tokens, callback));
2291
+ else if (genericToken.tokens) {
2292
+ values = values.concat(this.walkTokens(genericToken.tokens, callback));
2268
2293
  }
2269
2294
  }
2270
2295
  }
@@ -2304,8 +2329,9 @@ class Marked {
2304
2329
  if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
2305
2330
  throw new Error("extension level must be 'block' or 'inline'");
2306
2331
  }
2307
- if (extensions[ext.level]) {
2308
- extensions[ext.level].unshift(ext.tokenizer);
2332
+ const extLevel = extensions[ext.level];
2333
+ if (extLevel) {
2334
+ extLevel.unshift(ext.tokenizer);
2309
2335
  }
2310
2336
  else {
2311
2337
  extensions[ext.level] = [ext.tokenizer];
@@ -2403,9 +2429,10 @@ class Marked {
2403
2429
  // ==-- Parse WalkTokens extensions --== //
2404
2430
  if (pack.walkTokens) {
2405
2431
  const walkTokens = this.defaults.walkTokens;
2432
+ const packWalktokens = pack.walkTokens;
2406
2433
  opts.walkTokens = function (token) {
2407
2434
  let values = [];
2408
- values.push(pack.walkTokens.call(this, token));
2435
+ values.push(packWalktokens.call(this, token));
2409
2436
  if (walkTokens) {
2410
2437
  values = values.concat(walkTokens.call(this, token));
2411
2438
  }
@@ -2428,6 +2455,13 @@ class Marked {
2428
2455
  }
2429
2456
  const origOpt = { ...optOrCallback };
2430
2457
  const opt = { ...this.defaults, ...origOpt };
2458
+ // Show warning if an extension set async to true but the parse was called with async: false
2459
+ if (this.defaults.async === true && origOpt.async === false) {
2460
+ if (!opt.silent) {
2461
+ console.warn('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.');
2462
+ }
2463
+ opt.async = true;
2464
+ }
2431
2465
  const throwError = this.#onError(!!opt.silent, !!opt.async, callback);
2432
2466
  // throw error in case of non string input
2433
2467
  if (typeof src === 'undefined' || src === null) {
@@ -2442,6 +2476,7 @@ class Marked {
2442
2476
  opt.hooks.options = opt;
2443
2477
  }
2444
2478
  if (callback) {
2479
+ const resultCallback = callback;
2445
2480
  const highlight = opt.highlight;
2446
2481
  let tokens;
2447
2482
  try {
@@ -2472,7 +2507,7 @@ class Marked {
2472
2507
  opt.highlight = highlight;
2473
2508
  return err
2474
2509
  ? throwError(err)
2475
- : callback(null, out);
2510
+ : resultCallback(null, out);
2476
2511
  };
2477
2512
  if (!highlight || highlight.length < 3) {
2478
2513
  return done();