marked 7.0.3 → 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.3 - 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
@@ -1313,13 +1322,11 @@
1313
1322
  * mangle email addresses
1314
1323
  */
1315
1324
  function mangle(text) {
1316
- let out = '', i, ch;
1317
- const l = text.length;
1318
- for (i = 0; i < l; i++) {
1319
- ch = text.charCodeAt(i);
1320
- if (Math.random() > 0.5) {
1321
- ch = 'x' + ch.toString(16);
1322
- }
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();
1323
1330
  out += '&#' + ch + ';';
1324
1331
  }
1325
1332
  return out;
@@ -1765,7 +1772,7 @@
1765
1772
  this.options = options || exports.defaults;
1766
1773
  }
1767
1774
  code(code, infostring, escaped) {
1768
- const lang = (infostring || '').match(/\S*/)[0];
1775
+ const lang = (infostring || '').match(/^\S*/)?.[0];
1769
1776
  if (this.options.highlight) {
1770
1777
  const out = this.options.highlight(code, lang);
1771
1778
  if (out != null && out !== code) {
@@ -1804,7 +1811,8 @@
1804
1811
  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
1805
1812
  }
1806
1813
  list(body, ordered, start) {
1807
- 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 + '"') : '';
1808
1816
  return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
1809
1817
  }
1810
1818
  listitem(text, task, checked) {
@@ -1859,10 +1867,11 @@
1859
1867
  return `<del>${text}</del>`;
1860
1868
  }
1861
1869
  link(href, title, text) {
1862
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1863
- if (href === null) {
1870
+ const cleanHref = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1871
+ if (cleanHref === null) {
1864
1872
  return text;
1865
1873
  }
1874
+ href = cleanHref;
1866
1875
  let out = '<a href="' + href + '"';
1867
1876
  if (title) {
1868
1877
  out += ' title="' + title + '"';
@@ -1871,10 +1880,11 @@
1871
1880
  return out;
1872
1881
  }
1873
1882
  image(href, title, text) {
1874
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1875
- if (href === null) {
1883
+ const cleanHref = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
1884
+ if (cleanHref === null) {
1876
1885
  return text;
1877
1886
  }
1887
+ href = cleanHref;
1878
1888
  let out = `<img src="${href}" alt="${text}"`;
1879
1889
  if (title) {
1880
1890
  out += ` title="${title}"`;
@@ -2002,14 +2012,14 @@
2002
2012
  * Parse Loop
2003
2013
  */
2004
2014
  parse(tokens, top = true) {
2005
- let out = '', i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
2006
- const l = tokens.length;
2007
- for (i = 0; i < l; i++) {
2008
- token = tokens[i];
2015
+ let out = '';
2016
+ for (let i = 0; i < tokens.length; i++) {
2017
+ const token = tokens[i];
2009
2018
  // Run any renderer extensions
2010
2019
  if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2011
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2012
- 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)) {
2013
2023
  out += ret || '';
2014
2024
  continue;
2015
2025
  }
@@ -2023,30 +2033,30 @@
2023
2033
  continue;
2024
2034
  }
2025
2035
  case 'heading': {
2026
- 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);
2027
2038
  continue;
2028
2039
  }
2029
2040
  case 'code': {
2030
- 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);
2031
2043
  continue;
2032
2044
  }
2033
2045
  case 'table': {
2034
- header = '';
2046
+ const tableToken = token;
2047
+ let header = '';
2035
2048
  // header
2036
- cell = '';
2037
- l2 = token.header.length;
2038
- for (j = 0; j < l2; j++) {
2039
- 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] });
2040
2052
  }
2041
2053
  header += this.renderer.tablerow(cell);
2042
- body = '';
2043
- l2 = token.rows.length;
2044
- for (j = 0; j < l2; j++) {
2045
- row = token.rows[j];
2054
+ let body = '';
2055
+ for (let j = 0; j < tableToken.rows.length; j++) {
2056
+ const row = tableToken.rows[j];
2046
2057
  cell = '';
2047
- l3 = row.length;
2048
- for (k = 0; k < l3; k++) {
2049
- 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] });
2050
2060
  }
2051
2061
  body += this.renderer.tablerow(cell);
2052
2062
  }
@@ -2054,23 +2064,24 @@
2054
2064
  continue;
2055
2065
  }
2056
2066
  case 'blockquote': {
2057
- body = this.parse(token.tokens);
2067
+ const blockquoteToken = token;
2068
+ const body = this.parse(blockquoteToken.tokens);
2058
2069
  out += this.renderer.blockquote(body);
2059
2070
  continue;
2060
2071
  }
2061
2072
  case 'list': {
2062
- ordered = token.ordered;
2063
- start = token.start;
2064
- loose = token.loose;
2065
- l2 = token.items.length;
2066
- body = '';
2067
- for (j = 0; j < l2; j++) {
2068
- item = token.items[j];
2069
- checked = item.checked;
2070
- task = item.task;
2071
- 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 = '';
2072
2083
  if (item.task) {
2073
- checkbox = this.renderer.checkbox(!!checked);
2084
+ const checkbox = this.renderer.checkbox(!!checked);
2074
2085
  if (loose) {
2075
2086
  if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
2076
2087
  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
@@ -2096,18 +2107,21 @@
2096
2107
  continue;
2097
2108
  }
2098
2109
  case 'html': {
2099
- out += this.renderer.html(token.text, token.block);
2110
+ const htmlToken = token;
2111
+ out += this.renderer.html(htmlToken.text, htmlToken.block);
2100
2112
  continue;
2101
2113
  }
2102
2114
  case 'paragraph': {
2103
- out += this.renderer.paragraph(this.parseInline(token.tokens));
2115
+ const paragraphToken = token;
2116
+ out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens));
2104
2117
  continue;
2105
2118
  }
2106
2119
  case 'text': {
2107
- body = token.tokens ? this.parseInline(token.tokens) : token.text;
2108
- while (i + 1 < l && tokens[i + 1].type === 'text') {
2109
- token = tokens[++i];
2110
- 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);
2111
2125
  }
2112
2126
  out += top ? this.renderer.paragraph(body) : body;
2113
2127
  continue;
@@ -2131,13 +2145,12 @@
2131
2145
  */
2132
2146
  parseInline(tokens, renderer) {
2133
2147
  renderer = renderer || this.renderer;
2134
- let out = '', i, token, ret;
2135
- const l = tokens.length;
2136
- for (i = 0; i < l; i++) {
2137
- token = tokens[i];
2148
+ let out = '';
2149
+ for (let i = 0; i < tokens.length; i++) {
2150
+ const token = tokens[i];
2138
2151
  // Run any renderer extensions
2139
2152
  if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
2140
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2153
+ const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
2141
2154
  if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
2142
2155
  out += ret || '';
2143
2156
  continue;
@@ -2145,31 +2158,38 @@
2145
2158
  }
2146
2159
  switch (token.type) {
2147
2160
  case 'escape': {
2148
- out += renderer.text(token.text);
2161
+ const escapeToken = token;
2162
+ out += renderer.text(escapeToken.text);
2149
2163
  break;
2150
2164
  }
2151
2165
  case 'html': {
2152
- out += renderer.html(token.text);
2166
+ const tagToken = token;
2167
+ out += renderer.html(tagToken.text);
2153
2168
  break;
2154
2169
  }
2155
2170
  case 'link': {
2156
- 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));
2157
2173
  break;
2158
2174
  }
2159
2175
  case 'image': {
2160
- out += renderer.image(token.href, token.title, token.text);
2176
+ const imageToken = token;
2177
+ out += renderer.image(imageToken.href, imageToken.title, imageToken.text);
2161
2178
  break;
2162
2179
  }
2163
2180
  case 'strong': {
2164
- out += renderer.strong(this.parseInline(token.tokens, renderer));
2181
+ const strongToken = token;
2182
+ out += renderer.strong(this.parseInline(strongToken.tokens, renderer));
2165
2183
  break;
2166
2184
  }
2167
2185
  case 'em': {
2168
- out += renderer.em(this.parseInline(token.tokens, renderer));
2186
+ const emToken = token;
2187
+ out += renderer.em(this.parseInline(emToken.tokens, renderer));
2169
2188
  break;
2170
2189
  }
2171
2190
  case 'codespan': {
2172
- out += renderer.codespan(token.text);
2191
+ const codespanToken = token;
2192
+ out += renderer.codespan(codespanToken.text);
2173
2193
  break;
2174
2194
  }
2175
2195
  case 'br': {
@@ -2177,11 +2197,13 @@
2177
2197
  break;
2178
2198
  }
2179
2199
  case 'del': {
2180
- out += renderer.del(this.parseInline(token.tokens, renderer));
2200
+ const delToken = token;
2201
+ out += renderer.del(this.parseInline(delToken.tokens, renderer));
2181
2202
  break;
2182
2203
  }
2183
2204
  case 'text': {
2184
- out += renderer.text(token.text);
2205
+ const textToken = token;
2206
+ out += renderer.text(textToken.text);
2185
2207
  break;
2186
2208
  }
2187
2209
  default: {
@@ -2249,10 +2271,11 @@
2249
2271
  values = values.concat(callback.call(this, token));
2250
2272
  switch (token.type) {
2251
2273
  case 'table': {
2252
- for (const cell of token.header) {
2274
+ const tableToken = token;
2275
+ for (const cell of tableToken.header) {
2253
2276
  values = values.concat(this.walkTokens(cell.tokens, callback));
2254
2277
  }
2255
- for (const row of token.rows) {
2278
+ for (const row of tableToken.rows) {
2256
2279
  for (const cell of row) {
2257
2280
  values = values.concat(this.walkTokens(cell.tokens, callback));
2258
2281
  }
@@ -2260,18 +2283,19 @@
2260
2283
  break;
2261
2284
  }
2262
2285
  case 'list': {
2263
- values = values.concat(this.walkTokens(token.items, callback));
2286
+ const listToken = token;
2287
+ values = values.concat(this.walkTokens(listToken.items, callback));
2264
2288
  break;
2265
2289
  }
2266
2290
  default: {
2267
- if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { // Walk any extensions
2268
- this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
2269
- // @ts-expect-error we assume token[childToken] is an array of tokens but we can't be sure
2270
- 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));
2271
2295
  });
2272
2296
  }
2273
- else if (token.tokens) {
2274
- values = values.concat(this.walkTokens(token.tokens, callback));
2297
+ else if (genericToken.tokens) {
2298
+ values = values.concat(this.walkTokens(genericToken.tokens, callback));
2275
2299
  }
2276
2300
  }
2277
2301
  }
@@ -2311,8 +2335,9 @@
2311
2335
  if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
2312
2336
  throw new Error("extension level must be 'block' or 'inline'");
2313
2337
  }
2314
- if (extensions[ext.level]) {
2315
- extensions[ext.level].unshift(ext.tokenizer);
2338
+ const extLevel = extensions[ext.level];
2339
+ if (extLevel) {
2340
+ extLevel.unshift(ext.tokenizer);
2316
2341
  }
2317
2342
  else {
2318
2343
  extensions[ext.level] = [ext.tokenizer];
@@ -2410,9 +2435,10 @@
2410
2435
  // ==-- Parse WalkTokens extensions --== //
2411
2436
  if (pack.walkTokens) {
2412
2437
  const walkTokens = this.defaults.walkTokens;
2438
+ const packWalktokens = pack.walkTokens;
2413
2439
  opts.walkTokens = function (token) {
2414
2440
  let values = [];
2415
- values.push(pack.walkTokens.call(this, token));
2441
+ values.push(packWalktokens.call(this, token));
2416
2442
  if (walkTokens) {
2417
2443
  values = values.concat(walkTokens.call(this, token));
2418
2444
  }
@@ -2435,6 +2461,13 @@
2435
2461
  }
2436
2462
  const origOpt = { ...optOrCallback };
2437
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
+ }
2438
2471
  const throwError = this.#onError(!!opt.silent, !!opt.async, callback);
2439
2472
  // throw error in case of non string input
2440
2473
  if (typeof src === 'undefined' || src === null) {
@@ -2449,6 +2482,7 @@
2449
2482
  opt.hooks.options = opt;
2450
2483
  }
2451
2484
  if (callback) {
2485
+ const resultCallback = callback;
2452
2486
  const highlight = opt.highlight;
2453
2487
  let tokens;
2454
2488
  try {
@@ -2479,7 +2513,7 @@
2479
2513
  opt.highlight = highlight;
2480
2514
  return err
2481
2515
  ? throwError(err)
2482
- : callback(null, out);
2516
+ : resultCallback(null, out);
2483
2517
  };
2484
2518
  if (!highlight || highlight.length < 3) {
2485
2519
  return done();