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.umd.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
  */
@@ -174,7 +174,8 @@
174
174
  // ensure that every cell-delimiting pipe has a space
175
175
  // before it to distinguish it from an escaped pipe
176
176
  const row = tableRow.replace(/\|/g, (match, offset, str) => {
177
- let escaped = false, curr = offset;
177
+ let escaped = false;
178
+ let curr = offset;
178
179
  while (--curr >= 0 && str[curr] === '\\')
179
180
  escaped = !escaped;
180
181
  if (escaped) {
@@ -244,9 +245,8 @@
244
245
  if (str.indexOf(b[1]) === -1) {
245
246
  return -1;
246
247
  }
247
- const l = str.length;
248
- let level = 0, i = 0;
249
- for (; i < l; i++) {
248
+ let level = 0;
249
+ for (let i = 0; i < str.length; i++) {
250
250
  if (str[i] === '\\') {
251
251
  i++;
252
252
  }
@@ -343,6 +343,7 @@
343
343
  */
344
344
  class _Tokenizer {
345
345
  options;
346
+ // TODO: Fix this rules type
346
347
  rules;
347
348
  lexer;
348
349
  constructor(options) {
@@ -436,7 +437,6 @@
436
437
  list(src) {
437
438
  let cap = this.rules.block.list.exec(src);
438
439
  if (cap) {
439
- let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
440
440
  let bull = cap[1].trim();
441
441
  const isordered = bull.length > 1;
442
442
  const list = {
@@ -453,9 +453,12 @@
453
453
  }
454
454
  // Get next list item
455
455
  const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
456
+ let raw = '';
457
+ let itemContents = '';
458
+ let endsWithBlankLine = false;
456
459
  // Check if current bullet point can start a new List Item
457
460
  while (src) {
458
- endEarly = false;
461
+ let endEarly = false;
459
462
  if (!(cap = itemRegex.exec(src))) {
460
463
  break;
461
464
  }
@@ -464,8 +467,9 @@
464
467
  }
465
468
  raw = cap[0];
466
469
  src = src.substring(raw.length);
467
- line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
468
- nextLine = src.split('\n', 1)[0];
470
+ let line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
471
+ let nextLine = src.split('\n', 1)[0];
472
+ let indent = 0;
469
473
  if (this.options.pedantic) {
470
474
  indent = 2;
471
475
  itemContents = line.trimLeft();
@@ -476,7 +480,7 @@
476
480
  itemContents = line.slice(indent);
477
481
  indent += cap[1].length;
478
482
  }
479
- blankLine = false;
483
+ let blankLine = false;
480
484
  if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
481
485
  raw += nextLine + '\n';
482
486
  src = src.substring(nextLine.length + 1);
@@ -489,7 +493,7 @@
489
493
  const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
490
494
  // Check if following lines should be included in List Item
491
495
  while (src) {
492
- rawLine = src.split('\n', 1)[0];
496
+ const rawLine = src.split('\n', 1)[0];
493
497
  nextLine = rawLine;
494
498
  // Re-align to follow commonmark nesting rules
495
499
  if (this.options.pedantic) {
@@ -551,6 +555,8 @@
551
555
  endsWithBlankLine = true;
552
556
  }
553
557
  }
558
+ let istask = null;
559
+ let ischecked;
554
560
  // Check for task list items
555
561
  if (this.options.gfm) {
556
562
  istask = /^\[[ xX]\] /.exec(itemContents);
@@ -565,7 +571,8 @@
565
571
  task: !!istask,
566
572
  checked: ischecked,
567
573
  loose: false,
568
- text: itemContents
574
+ text: itemContents,
575
+ tokens: []
569
576
  });
570
577
  list.raw += raw;
571
578
  }
@@ -573,9 +580,8 @@
573
580
  list.items[list.items.length - 1].raw = raw.trimRight();
574
581
  list.items[list.items.length - 1].text = itemContents.trimRight();
575
582
  list.raw = list.raw.trimRight();
576
- const l = list.items.length;
577
583
  // Item child tokens handled here at end because we needed to have the final item to trim it first
578
- for (i = 0; i < l; i++) {
584
+ for (let i = 0; i < list.items.length; i++) {
579
585
  this.lexer.state.top = false;
580
586
  list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
581
587
  if (!list.loose) {
@@ -587,7 +593,7 @@
587
593
  }
588
594
  // Set all items to loose if list is loose
589
595
  if (list.loose) {
590
- for (i = 0; i < l; i++) {
596
+ for (let i = 0; i < list.items.length; i++) {
591
597
  list.items[i].loose = true;
592
598
  }
593
599
  }
@@ -637,7 +643,7 @@
637
643
  type: 'table',
638
644
  raw: cap[0],
639
645
  header: splitCells(cap[1]).map(c => {
640
- return { text: c };
646
+ return { text: c, tokens: [] };
641
647
  }),
642
648
  align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
643
649
  rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
@@ -646,23 +652,26 @@
646
652
  let l = item.align.length;
647
653
  let i, j, k, row;
648
654
  for (i = 0; i < l; i++) {
649
- if (/^ *-+: *$/.test(item.align[i])) {
650
- item.align[i] = 'right';
651
- }
652
- else if (/^ *:-+: *$/.test(item.align[i])) {
653
- item.align[i] = 'center';
654
- }
655
- else if (/^ *:-+ *$/.test(item.align[i])) {
656
- item.align[i] = 'left';
657
- }
658
- else {
659
- item.align[i] = null;
655
+ const align = item.align[i];
656
+ if (align) {
657
+ if (/^ *-+: *$/.test(align)) {
658
+ item.align[i] = 'right';
659
+ }
660
+ else if (/^ *:-+: *$/.test(align)) {
661
+ item.align[i] = 'center';
662
+ }
663
+ else if (/^ *:-+ *$/.test(align)) {
664
+ item.align[i] = 'left';
665
+ }
666
+ else {
667
+ item.align[i] = null;
668
+ }
660
669
  }
661
670
  }
662
671
  l = item.rows.length;
663
672
  for (i = 0; i < l; i++) {
664
673
  item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
665
- return { text: c };
674
+ return { text: c, tokens: [] };
666
675
  });
667
676
  }
668
677
  // parse child tokens inside headers and cells
@@ -842,7 +851,8 @@
842
851
  return;
843
852
  const nextChar = match[1] || match[2] || '';
844
853
  if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
845
- const lLength = match[0].length - 1;
854
+ // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
855
+ const lLength = [...match[0]].length - 1;
846
856
  let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
847
857
  const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
848
858
  endReg.lastIndex = 0;
@@ -852,7 +862,7 @@
852
862
  rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
853
863
  if (!rDelim)
854
864
  continue; // skip single * in __abc*abc__
855
- rLength = rDelim.length;
865
+ rLength = [...rDelim].length;
856
866
  if (match[3] || match[4]) { // found another Left Delim
857
867
  delimTotal += rLength;
858
868
  continue;
@@ -868,7 +878,7 @@
868
878
  continue; // Haven't found enough closing delimiters
869
879
  // Remove extra characters. *a*** -> *a*
870
880
  rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
871
- const raw = src.slice(0, lLength + match.index + rLength + 1);
881
+ const raw = [...src].slice(0, lLength + match.index + rLength + 1).join('');
872
882
  // Create `em` if smallest delimiter has odd char count. *a***
873
883
  if (Math.min(lLength, rLength) % 2) {
874
884
  const text = raw.slice(1, -1);
@@ -1312,13 +1322,11 @@
1312
1322
  * mangle email addresses
1313
1323
  */
1314
1324
  function mangle(text) {
1315
- let out = '', i, ch;
1316
- const l = text.length;
1317
- for (i = 0; i < l; i++) {
1318
- ch = text.charCodeAt(i);
1319
- if (Math.random() > 0.5) {
1320
- ch = 'x' + ch.toString(16);
1321
- }
1325
+ let out = '';
1326
+ for (let i = 0; i < text.length; i++) {
1327
+ const ch = Math.random() > 0.5
1328
+ ? 'x' + text.charCodeAt(i).toString(16)
1329
+ : text.charCodeAt(i).toString();
1322
1330
  out += '&#' + ch + ';';
1323
1331
  }
1324
1332
  return out;
@@ -1764,7 +1772,7 @@
1764
1772
  this.options = options || exports.defaults;
1765
1773
  }
1766
1774
  code(code, infostring, escaped) {
1767
- const lang = (infostring || '').match(/\S*/)[0];
1775
+ const lang = (infostring || '').match(/^\S*/)?.[0];
1768
1776
  if (this.options.highlight) {
1769
1777
  const out = this.options.highlight(code, lang);
1770
1778
  if (out != null && out !== code) {
@@ -1803,7 +1811,8 @@
1803
1811
  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
1804
1812
  }
1805
1813
  list(body, ordered, start) {
1806
- const type = ordered ? 'ol' : 'ul', startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1814
+ const type = ordered ? 'ol' : 'ul';
1815
+ const startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1807
1816
  return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
1808
1817
  }
1809
1818
  listitem(text, task, checked) {
@@ -1858,10 +1867,11 @@
1858
1867
  return `<del>${text}</del>`;
1859
1868
  }
1860
1869
  link(href, title, text) {
1861
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1862
- if (href === null) {
1870
+ const cleanHref = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1871
+ if (cleanHref === null) {
1863
1872
  return text;
1864
1873
  }
1874
+ href = cleanHref;
1865
1875
  let out = '<a href="' + href + '"';
1866
1876
  if (title) {
1867
1877
  out += ' title="' + title + '"';
@@ -1870,10 +1880,11 @@
1870
1880
  return out;
1871
1881
  }
1872
1882
  image(href, title, text) {
1873
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1874
- if (href === null) {
1883
+ const cleanHref = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1884
+ if (cleanHref === null) {
1875
1885
  return text;
1876
1886
  }
1887
+ href = cleanHref;
1877
1888
  let out = `<img src="${href}" alt="${text}"`;
1878
1889
  if (title) {
1879
1890
  out += ` title="${title}"`;
@@ -2001,14 +2012,14 @@
2001
2012
  * Parse Loop
2002
2013
  */
2003
2014
  parse(tokens, top = true) {
2004
- let out = '', i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
2005
- const l = tokens.length;
2006
- for (i = 0; i < l; i++) {
2007
- token = tokens[i];
2015
+ let out = '';
2016
+ for (let i = 0; i < tokens.length; i++) {
2017
+ const token = tokens[i];
2008
2018
  // Run any renderer extensions
2009
2019
  if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2010
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2011
- if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
2020
+ const genericToken = token;
2021
+ const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
2022
+ if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
2012
2023
  out += ret || '';
2013
2024
  continue;
2014
2025
  }
@@ -2022,30 +2033,30 @@
2022
2033
  continue;
2023
2034
  }
2024
2035
  case 'heading': {
2025
- out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
2036
+ const headingToken = token;
2037
+ out += this.renderer.heading(this.parseInline(headingToken.tokens), headingToken.depth, unescape(this.parseInline(headingToken.tokens, this.textRenderer)), this.slugger);
2026
2038
  continue;
2027
2039
  }
2028
2040
  case 'code': {
2029
- out += this.renderer.code(token.text, token.lang, !!token.escaped);
2041
+ const codeToken = token;
2042
+ out += this.renderer.code(codeToken.text, codeToken.lang, !!codeToken.escaped);
2030
2043
  continue;
2031
2044
  }
2032
2045
  case 'table': {
2033
- header = '';
2046
+ const tableToken = token;
2047
+ let header = '';
2034
2048
  // header
2035
- cell = '';
2036
- l2 = token.header.length;
2037
- for (j = 0; j < l2; j++) {
2038
- cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { header: true, align: token.align[j] });
2049
+ let cell = '';
2050
+ for (let j = 0; j < tableToken.header.length; j++) {
2051
+ cell += this.renderer.tablecell(this.parseInline(tableToken.header[j].tokens), { header: true, align: tableToken.align[j] });
2039
2052
  }
2040
2053
  header += this.renderer.tablerow(cell);
2041
- body = '';
2042
- l2 = token.rows.length;
2043
- for (j = 0; j < l2; j++) {
2044
- row = token.rows[j];
2054
+ let body = '';
2055
+ for (let j = 0; j < tableToken.rows.length; j++) {
2056
+ const row = tableToken.rows[j];
2045
2057
  cell = '';
2046
- l3 = row.length;
2047
- for (k = 0; k < l3; k++) {
2048
- cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: token.align[k] });
2058
+ for (let k = 0; k < row.length; k++) {
2059
+ cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: tableToken.align[k] });
2049
2060
  }
2050
2061
  body += this.renderer.tablerow(cell);
2051
2062
  }
@@ -2053,23 +2064,24 @@
2053
2064
  continue;
2054
2065
  }
2055
2066
  case 'blockquote': {
2056
- body = this.parse(token.tokens);
2067
+ const blockquoteToken = token;
2068
+ const body = this.parse(blockquoteToken.tokens);
2057
2069
  out += this.renderer.blockquote(body);
2058
2070
  continue;
2059
2071
  }
2060
2072
  case 'list': {
2061
- ordered = token.ordered;
2062
- start = token.start;
2063
- loose = token.loose;
2064
- l2 = token.items.length;
2065
- body = '';
2066
- for (j = 0; j < l2; j++) {
2067
- item = token.items[j];
2068
- checked = item.checked;
2069
- task = item.task;
2070
- itemBody = '';
2073
+ const listToken = token;
2074
+ const ordered = listToken.ordered;
2075
+ const start = listToken.start;
2076
+ const loose = listToken.loose;
2077
+ let body = '';
2078
+ for (let j = 0; j < listToken.items.length; j++) {
2079
+ const item = listToken.items[j];
2080
+ const checked = item.checked;
2081
+ const task = item.task;
2082
+ let itemBody = '';
2071
2083
  if (item.task) {
2072
- checkbox = this.renderer.checkbox(!!checked);
2084
+ const checkbox = this.renderer.checkbox(!!checked);
2073
2085
  if (loose) {
2074
2086
  if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
2075
2087
  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
@@ -2095,18 +2107,21 @@
2095
2107
  continue;
2096
2108
  }
2097
2109
  case 'html': {
2098
- out += this.renderer.html(token.text, token.block);
2110
+ const htmlToken = token;
2111
+ out += this.renderer.html(htmlToken.text, htmlToken.block);
2099
2112
  continue;
2100
2113
  }
2101
2114
  case 'paragraph': {
2102
- out += this.renderer.paragraph(this.parseInline(token.tokens));
2115
+ const paragraphToken = token;
2116
+ out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens));
2103
2117
  continue;
2104
2118
  }
2105
2119
  case 'text': {
2106
- body = token.tokens ? this.parseInline(token.tokens) : token.text;
2107
- while (i + 1 < l && tokens[i + 1].type === 'text') {
2108
- token = tokens[++i];
2109
- body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
2120
+ let textToken = token;
2121
+ let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text;
2122
+ while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
2123
+ textToken = tokens[++i];
2124
+ body += '\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text);
2110
2125
  }
2111
2126
  out += top ? this.renderer.paragraph(body) : body;
2112
2127
  continue;
@@ -2130,13 +2145,12 @@
2130
2145
  */
2131
2146
  parseInline(tokens, renderer) {
2132
2147
  renderer = renderer || this.renderer;
2133
- let out = '', i, token, ret;
2134
- const l = tokens.length;
2135
- for (i = 0; i < l; i++) {
2136
- token = tokens[i];
2148
+ let out = '';
2149
+ for (let i = 0; i < tokens.length; i++) {
2150
+ const token = tokens[i];
2137
2151
  // Run any renderer extensions
2138
2152
  if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2139
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2153
+ const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2140
2154
  if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
2141
2155
  out += ret || '';
2142
2156
  continue;
@@ -2144,31 +2158,38 @@
2144
2158
  }
2145
2159
  switch (token.type) {
2146
2160
  case 'escape': {
2147
- out += renderer.text(token.text);
2161
+ const escapeToken = token;
2162
+ out += renderer.text(escapeToken.text);
2148
2163
  break;
2149
2164
  }
2150
2165
  case 'html': {
2151
- out += renderer.html(token.text);
2166
+ const tagToken = token;
2167
+ out += renderer.html(tagToken.text);
2152
2168
  break;
2153
2169
  }
2154
2170
  case 'link': {
2155
- out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
2171
+ const linkToken = token;
2172
+ out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer));
2156
2173
  break;
2157
2174
  }
2158
2175
  case 'image': {
2159
- out += renderer.image(token.href, token.title, token.text);
2176
+ const imageToken = token;
2177
+ out += renderer.image(imageToken.href, imageToken.title, imageToken.text);
2160
2178
  break;
2161
2179
  }
2162
2180
  case 'strong': {
2163
- out += renderer.strong(this.parseInline(token.tokens, renderer));
2181
+ const strongToken = token;
2182
+ out += renderer.strong(this.parseInline(strongToken.tokens, renderer));
2164
2183
  break;
2165
2184
  }
2166
2185
  case 'em': {
2167
- out += renderer.em(this.parseInline(token.tokens, renderer));
2186
+ const emToken = token;
2187
+ out += renderer.em(this.parseInline(emToken.tokens, renderer));
2168
2188
  break;
2169
2189
  }
2170
2190
  case 'codespan': {
2171
- out += renderer.codespan(token.text);
2191
+ const codespanToken = token;
2192
+ out += renderer.codespan(codespanToken.text);
2172
2193
  break;
2173
2194
  }
2174
2195
  case 'br': {
@@ -2176,11 +2197,13 @@
2176
2197
  break;
2177
2198
  }
2178
2199
  case 'del': {
2179
- out += renderer.del(this.parseInline(token.tokens, renderer));
2200
+ const delToken = token;
2201
+ out += renderer.del(this.parseInline(delToken.tokens, renderer));
2180
2202
  break;
2181
2203
  }
2182
2204
  case 'text': {
2183
- out += renderer.text(token.text);
2205
+ const textToken = token;
2206
+ out += renderer.text(textToken.text);
2184
2207
  break;
2185
2208
  }
2186
2209
  default: {
@@ -2248,10 +2271,11 @@
2248
2271
  values = values.concat(callback.call(this, token));
2249
2272
  switch (token.type) {
2250
2273
  case 'table': {
2251
- for (const cell of token.header) {
2274
+ const tableToken = token;
2275
+ for (const cell of tableToken.header) {
2252
2276
  values = values.concat(this.walkTokens(cell.tokens, callback));
2253
2277
  }
2254
- for (const row of token.rows) {
2278
+ for (const row of tableToken.rows) {
2255
2279
  for (const cell of row) {
2256
2280
  values = values.concat(this.walkTokens(cell.tokens, callback));
2257
2281
  }
@@ -2259,18 +2283,19 @@
2259
2283
  break;
2260
2284
  }
2261
2285
  case 'list': {
2262
- values = values.concat(this.walkTokens(token.items, callback));
2286
+ const listToken = token;
2287
+ values = values.concat(this.walkTokens(listToken.items, callback));
2263
2288
  break;
2264
2289
  }
2265
2290
  default: {
2266
- if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { // Walk any extensions
2267
- this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
2268
- // @ts-expect-error we assume token[childToken] is an array of tokens but we can't be sure
2269
- values = values.concat(this.walkTokens(token[childTokens], callback));
2291
+ const genericToken = token;
2292
+ if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
2293
+ this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
2294
+ values = values.concat(this.walkTokens(genericToken[childTokens], callback));
2270
2295
  });
2271
2296
  }
2272
- else if (token.tokens) {
2273
- values = values.concat(this.walkTokens(token.tokens, callback));
2297
+ else if (genericToken.tokens) {
2298
+ values = values.concat(this.walkTokens(genericToken.tokens, callback));
2274
2299
  }
2275
2300
  }
2276
2301
  }
@@ -2310,8 +2335,9 @@
2310
2335
  if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
2311
2336
  throw new Error("extension level must be 'block' or 'inline'");
2312
2337
  }
2313
- if (extensions[ext.level]) {
2314
- extensions[ext.level].unshift(ext.tokenizer);
2338
+ const extLevel = extensions[ext.level];
2339
+ if (extLevel) {
2340
+ extLevel.unshift(ext.tokenizer);
2315
2341
  }
2316
2342
  else {
2317
2343
  extensions[ext.level] = [ext.tokenizer];
@@ -2409,9 +2435,10 @@
2409
2435
  // ==-- Parse WalkTokens extensions --== //
2410
2436
  if (pack.walkTokens) {
2411
2437
  const walkTokens = this.defaults.walkTokens;
2438
+ const packWalktokens = pack.walkTokens;
2412
2439
  opts.walkTokens = function (token) {
2413
2440
  let values = [];
2414
- values.push(pack.walkTokens.call(this, token));
2441
+ values.push(packWalktokens.call(this, token));
2415
2442
  if (walkTokens) {
2416
2443
  values = values.concat(walkTokens.call(this, token));
2417
2444
  }
@@ -2434,6 +2461,13 @@
2434
2461
  }
2435
2462
  const origOpt = { ...optOrCallback };
2436
2463
  const opt = { ...this.defaults, ...origOpt };
2464
+ // Show warning if an extension set async to true but the parse was called with async: false
2465
+ if (this.defaults.async === true && origOpt.async === false) {
2466
+ if (!opt.silent) {
2467
+ console.warn('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.');
2468
+ }
2469
+ opt.async = true;
2470
+ }
2437
2471
  const throwError = this.#onError(!!opt.silent, !!opt.async, callback);
2438
2472
  // throw error in case of non string input
2439
2473
  if (typeof src === 'undefined' || src === null) {
@@ -2448,6 +2482,7 @@
2448
2482
  opt.hooks.options = opt;
2449
2483
  }
2450
2484
  if (callback) {
2485
+ const resultCallback = callback;
2451
2486
  const highlight = opt.highlight;
2452
2487
  let tokens;
2453
2488
  try {
@@ -2478,7 +2513,7 @@
2478
2513
  opt.highlight = highlight;
2479
2514
  return err
2480
2515
  ? throwError(err)
2481
- : callback(null, out);
2516
+ : resultCallback(null, out);
2482
2517
  };
2483
2518
  if (!highlight || highlight.length < 3) {
2484
2519
  return done();