marked 12.0.1 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/marked.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * marked v12.0.1 - a markdown parser
2
+ * marked v13.0.0 - a markdown parser
3
3
  * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
4
4
  * https://github.com/markedjs/marked
5
5
  */
@@ -315,21 +315,82 @@ class _Tokenizer {
315
315
  if (cap) {
316
316
  return {
317
317
  type: 'hr',
318
- raw: cap[0]
318
+ raw: rtrim(cap[0], '\n')
319
319
  };
320
320
  }
321
321
  }
322
322
  blockquote(src) {
323
323
  const cap = this.rules.block.blockquote.exec(src);
324
324
  if (cap) {
325
- const text = rtrim(cap[0].replace(/^ *>[ \t]?/gm, ''), '\n');
326
- const top = this.lexer.state.top;
327
- this.lexer.state.top = true;
328
- const tokens = this.lexer.blockTokens(text);
329
- this.lexer.state.top = top;
325
+ let lines = rtrim(cap[0], '\n').split('\n');
326
+ let raw = '';
327
+ let text = '';
328
+ const tokens = [];
329
+ while (lines.length > 0) {
330
+ let inBlockquote = false;
331
+ const currentLines = [];
332
+ let i;
333
+ for (i = 0; i < lines.length; i++) {
334
+ // get lines up to a continuation
335
+ if (/^ {0,3}>/.test(lines[i])) {
336
+ currentLines.push(lines[i]);
337
+ inBlockquote = true;
338
+ }
339
+ else if (!inBlockquote) {
340
+ currentLines.push(lines[i]);
341
+ }
342
+ else {
343
+ break;
344
+ }
345
+ }
346
+ lines = lines.slice(i);
347
+ const currentRaw = currentLines.join('\n');
348
+ const currentText = currentRaw
349
+ // precede setext continuation with 4 spaces so it isn't a setext
350
+ .replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g, '\n $1')
351
+ .replace(/^ {0,3}>[ \t]?/gm, '');
352
+ raw = raw ? `${raw}\n${currentRaw}` : currentRaw;
353
+ text = text ? `${text}\n${currentText}` : currentText;
354
+ // parse blockquote lines as top level tokens
355
+ // merge paragraphs if this is a continuation
356
+ const top = this.lexer.state.top;
357
+ this.lexer.state.top = true;
358
+ this.lexer.blockTokens(currentText, tokens, true);
359
+ this.lexer.state.top = top;
360
+ // if there is no continuation then we are done
361
+ if (lines.length === 0) {
362
+ break;
363
+ }
364
+ const lastToken = tokens[tokens.length - 1];
365
+ if (lastToken?.type === 'code') {
366
+ // blockquote continuation cannot be preceded by a code block
367
+ break;
368
+ }
369
+ else if (lastToken?.type === 'blockquote') {
370
+ // include continuation in nested blockquote
371
+ const oldToken = lastToken;
372
+ const newText = oldToken.raw + '\n' + lines.join('\n');
373
+ const newToken = this.blockquote(newText);
374
+ tokens[tokens.length - 1] = newToken;
375
+ raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;
376
+ text = text.substring(0, text.length - oldToken.text.length) + newToken.text;
377
+ break;
378
+ }
379
+ else if (lastToken?.type === 'list') {
380
+ // include continuation in nested list
381
+ const oldToken = lastToken;
382
+ const newText = oldToken.raw + '\n' + lines.join('\n');
383
+ const newToken = this.list(newText);
384
+ tokens[tokens.length - 1] = newToken;
385
+ raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
386
+ text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
387
+ lines = newText.substring(tokens[tokens.length - 1].raw.length).split('\n');
388
+ continue;
389
+ }
390
+ }
330
391
  return {
331
392
  type: 'blockquote',
332
- raw: cap[0],
393
+ raw,
333
394
  tokens,
334
395
  text
335
396
  };
@@ -566,17 +627,21 @@ class _Tokenizer {
566
627
  item.align.push(null);
567
628
  }
568
629
  }
569
- for (const header of headers) {
630
+ for (let i = 0; i < headers.length; i++) {
570
631
  item.header.push({
571
- text: header,
572
- tokens: this.lexer.inline(header)
632
+ text: headers[i],
633
+ tokens: this.lexer.inline(headers[i]),
634
+ header: true,
635
+ align: item.align[i]
573
636
  });
574
637
  }
575
638
  for (const row of rows) {
576
- item.rows.push(splitCells(row, item.header.length).map(cell => {
639
+ item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
577
640
  return {
578
641
  text: cell,
579
- tokens: this.lexer.inline(cell)
642
+ tokens: this.lexer.inline(cell),
643
+ header: false,
644
+ align: item.align[i]
580
645
  };
581
646
  }));
582
647
  }
@@ -958,7 +1023,7 @@ const html = edit('^ {0,3}(?:' // optional indentation
958
1023
  const paragraph = edit(_paragraph)
959
1024
  .replace('hr', hr)
960
1025
  .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
961
- .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
1026
+ .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
962
1027
  .replace('|table', '')
963
1028
  .replace('blockquote', ' {0,3}>')
964
1029
  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
@@ -1008,7 +1073,7 @@ const blockGfm = {
1008
1073
  paragraph: edit(_paragraph)
1009
1074
  .replace('hr', hr)
1010
1075
  .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1011
- .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
1076
+ .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
1012
1077
  .replace('table', gfmTable) // interrupt paragraphs with table
1013
1078
  .replace('blockquote', ' {0,3}>')
1014
1079
  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
@@ -1272,7 +1337,7 @@ class _Lexer {
1272
1337
  this.inlineQueue = [];
1273
1338
  return this.tokens;
1274
1339
  }
1275
- blockTokens(src, tokens = []) {
1340
+ blockTokens(src, tokens = [], lastParagraphClipped = false) {
1276
1341
  if (this.options.pedantic) {
1277
1342
  src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
1278
1343
  }
@@ -1284,7 +1349,6 @@ class _Lexer {
1284
1349
  let token;
1285
1350
  let lastToken;
1286
1351
  let cutSrc;
1287
- let lastParagraphClipped;
1288
1352
  while (src) {
1289
1353
  if (this.options.extensions
1290
1354
  && this.options.extensions.block
@@ -1410,7 +1474,7 @@ class _Lexer {
1410
1474
  }
1411
1475
  if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1412
1476
  lastToken = tokens[tokens.length - 1];
1413
- if (lastParagraphClipped && lastToken.type === 'paragraph') {
1477
+ if (lastParagraphClipped && lastToken?.type === 'paragraph') {
1414
1478
  lastToken.raw += '\n' + token.raw;
1415
1479
  lastToken.text += '\n' + token.text;
1416
1480
  this.inlineQueue.pop();
@@ -1629,53 +1693,103 @@ class _Lexer {
1629
1693
  */
1630
1694
  class _Renderer {
1631
1695
  options;
1696
+ parser; // set by the parser
1632
1697
  constructor(options) {
1633
1698
  this.options = options || _defaults;
1634
1699
  }
1635
- code(code, infostring, escaped) {
1636
- const lang = (infostring || '').match(/^\S*/)?.[0];
1637
- code = code.replace(/\n$/, '') + '\n';
1638
- if (!lang) {
1700
+ space(token) {
1701
+ return '';
1702
+ }
1703
+ code({ text, lang, escaped }) {
1704
+ const langString = (lang || '').match(/^\S*/)?.[0];
1705
+ const code = text.replace(/\n$/, '') + '\n';
1706
+ if (!langString) {
1639
1707
  return '<pre><code>'
1640
1708
  + (escaped ? code : escape$1(code, true))
1641
1709
  + '</code></pre>\n';
1642
1710
  }
1643
1711
  return '<pre><code class="language-'
1644
- + escape$1(lang)
1712
+ + escape$1(langString)
1645
1713
  + '">'
1646
1714
  + (escaped ? code : escape$1(code, true))
1647
1715
  + '</code></pre>\n';
1648
1716
  }
1649
- blockquote(quote) {
1650
- return `<blockquote>\n${quote}</blockquote>\n`;
1717
+ blockquote({ tokens }) {
1718
+ const body = this.parser.parse(tokens);
1719
+ return `<blockquote>\n${body}</blockquote>\n`;
1651
1720
  }
1652
- html(html, block) {
1653
- return html;
1721
+ html({ text }) {
1722
+ return text;
1654
1723
  }
1655
- heading(text, level, raw) {
1656
- // ignore IDs
1657
- return `<h${level}>${text}</h${level}>\n`;
1724
+ heading({ tokens, depth }) {
1725
+ return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\n`;
1658
1726
  }
1659
- hr() {
1727
+ hr(token) {
1660
1728
  return '<hr>\n';
1661
1729
  }
1662
- list(body, ordered, start) {
1730
+ list(token) {
1731
+ const ordered = token.ordered;
1732
+ const start = token.start;
1733
+ let body = '';
1734
+ for (let j = 0; j < token.items.length; j++) {
1735
+ const item = token.items[j];
1736
+ body += this.listitem(item);
1737
+ }
1663
1738
  const type = ordered ? 'ol' : 'ul';
1664
- const startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1665
- return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
1666
- }
1667
- listitem(text, task, checked) {
1668
- return `<li>${text}</li>\n`;
1739
+ const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1740
+ return '<' + type + startAttr + '>\n' + body + '</' + type + '>\n';
1741
+ }
1742
+ listitem(item) {
1743
+ let itemBody = '';
1744
+ if (item.task) {
1745
+ const checkbox = this.checkbox({ checked: !!item.checked });
1746
+ if (item.loose) {
1747
+ if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
1748
+ item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1749
+ if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1750
+ item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
1751
+ }
1752
+ }
1753
+ else {
1754
+ item.tokens.unshift({
1755
+ type: 'text',
1756
+ raw: checkbox + ' ',
1757
+ text: checkbox + ' '
1758
+ });
1759
+ }
1760
+ }
1761
+ else {
1762
+ itemBody += checkbox + ' ';
1763
+ }
1764
+ }
1765
+ itemBody += this.parser.parse(item.tokens, !!item.loose);
1766
+ return `<li>${itemBody}</li>\n`;
1669
1767
  }
1670
- checkbox(checked) {
1768
+ checkbox({ checked }) {
1671
1769
  return '<input '
1672
1770
  + (checked ? 'checked="" ' : '')
1673
1771
  + 'disabled="" type="checkbox">';
1674
1772
  }
1675
- paragraph(text) {
1676
- return `<p>${text}</p>\n`;
1773
+ paragraph({ tokens }) {
1774
+ return `<p>${this.parser.parseInline(tokens)}</p>\n`;
1677
1775
  }
1678
- table(header, body) {
1776
+ table(token) {
1777
+ let header = '';
1778
+ // header
1779
+ let cell = '';
1780
+ for (let j = 0; j < token.header.length; j++) {
1781
+ cell += this.tablecell(token.header[j]);
1782
+ }
1783
+ header += this.tablerow({ text: cell });
1784
+ let body = '';
1785
+ for (let j = 0; j < token.rows.length; j++) {
1786
+ const row = token.rows[j];
1787
+ cell = '';
1788
+ for (let k = 0; k < row.length; k++) {
1789
+ cell += this.tablecell(row[k]);
1790
+ }
1791
+ body += this.tablerow({ text: cell });
1792
+ }
1679
1793
  if (body)
1680
1794
  body = `<tbody>${body}</tbody>`;
1681
1795
  return '<table>\n'
@@ -1685,35 +1799,37 @@ class _Renderer {
1685
1799
  + body
1686
1800
  + '</table>\n';
1687
1801
  }
1688
- tablerow(content) {
1689
- return `<tr>\n${content}</tr>\n`;
1802
+ tablerow({ text }) {
1803
+ return `<tr>\n${text}</tr>\n`;
1690
1804
  }
1691
- tablecell(content, flags) {
1692
- const type = flags.header ? 'th' : 'td';
1693
- const tag = flags.align
1694
- ? `<${type} align="${flags.align}">`
1805
+ tablecell(token) {
1806
+ const content = this.parser.parseInline(token.tokens);
1807
+ const type = token.header ? 'th' : 'td';
1808
+ const tag = token.align
1809
+ ? `<${type} align="${token.align}">`
1695
1810
  : `<${type}>`;
1696
1811
  return tag + content + `</${type}>\n`;
1697
1812
  }
1698
1813
  /**
1699
1814
  * span level renderer
1700
1815
  */
1701
- strong(text) {
1702
- return `<strong>${text}</strong>`;
1816
+ strong({ tokens }) {
1817
+ return `<strong>${this.parser.parseInline(tokens)}</strong>`;
1703
1818
  }
1704
- em(text) {
1705
- return `<em>${text}</em>`;
1819
+ em({ tokens }) {
1820
+ return `<em>${this.parser.parseInline(tokens)}</em>`;
1706
1821
  }
1707
- codespan(text) {
1822
+ codespan({ text }) {
1708
1823
  return `<code>${text}</code>`;
1709
1824
  }
1710
- br() {
1825
+ br(token) {
1711
1826
  return '<br>';
1712
1827
  }
1713
- del(text) {
1714
- return `<del>${text}</del>`;
1828
+ del({ tokens }) {
1829
+ return `<del>${this.parser.parseInline(tokens)}</del>`;
1715
1830
  }
1716
- link(href, title, text) {
1831
+ link({ href, title, tokens }) {
1832
+ const text = this.parser.parseInline(tokens);
1717
1833
  const cleanHref = cleanUrl(href);
1718
1834
  if (cleanHref === null) {
1719
1835
  return text;
@@ -1726,7 +1842,7 @@ class _Renderer {
1726
1842
  out += '>' + text + '</a>';
1727
1843
  return out;
1728
1844
  }
1729
- image(href, title, text) {
1845
+ image({ href, title, text }) {
1730
1846
  const cleanHref = cleanUrl(href);
1731
1847
  if (cleanHref === null) {
1732
1848
  return text;
@@ -1739,8 +1855,8 @@ class _Renderer {
1739
1855
  out += '>';
1740
1856
  return out;
1741
1857
  }
1742
- text(text) {
1743
- return text;
1858
+ text(token) {
1859
+ return 'tokens' in token && token.tokens ? this.parser.parseInline(token.tokens) : token.text;
1744
1860
  }
1745
1861
  }
1746
1862
 
@@ -1750,28 +1866,28 @@ class _Renderer {
1750
1866
  */
1751
1867
  class _TextRenderer {
1752
1868
  // no need for block level renderers
1753
- strong(text) {
1869
+ strong({ text }) {
1754
1870
  return text;
1755
1871
  }
1756
- em(text) {
1872
+ em({ text }) {
1757
1873
  return text;
1758
1874
  }
1759
- codespan(text) {
1875
+ codespan({ text }) {
1760
1876
  return text;
1761
1877
  }
1762
- del(text) {
1878
+ del({ text }) {
1763
1879
  return text;
1764
1880
  }
1765
- html(text) {
1881
+ html({ text }) {
1766
1882
  return text;
1767
1883
  }
1768
- text(text) {
1884
+ text({ text }) {
1769
1885
  return text;
1770
1886
  }
1771
- link(href, title, text) {
1887
+ link({ text }) {
1772
1888
  return '' + text;
1773
1889
  }
1774
- image(href, title, text) {
1890
+ image({ text }) {
1775
1891
  return '' + text;
1776
1892
  }
1777
1893
  br() {
@@ -1791,6 +1907,7 @@ class _Parser {
1791
1907
  this.options.renderer = this.options.renderer || new _Renderer();
1792
1908
  this.renderer = this.options.renderer;
1793
1909
  this.renderer.options = this.options;
1910
+ this.renderer.parser = this;
1794
1911
  this.textRenderer = new _TextRenderer();
1795
1912
  }
1796
1913
  /**
@@ -1813,116 +1930,72 @@ class _Parser {
1813
1930
  parse(tokens, top = true) {
1814
1931
  let out = '';
1815
1932
  for (let i = 0; i < tokens.length; i++) {
1816
- const token = tokens[i];
1933
+ const anyToken = tokens[i];
1817
1934
  // Run any renderer extensions
1818
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
1819
- const genericToken = token;
1935
+ if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
1936
+ const genericToken = anyToken;
1820
1937
  const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
1821
1938
  if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
1822
1939
  out += ret || '';
1823
1940
  continue;
1824
1941
  }
1825
1942
  }
1943
+ const token = anyToken;
1826
1944
  switch (token.type) {
1827
1945
  case 'space': {
1946
+ out += this.renderer.space(token);
1828
1947
  continue;
1829
1948
  }
1830
1949
  case 'hr': {
1831
- out += this.renderer.hr();
1950
+ out += this.renderer.hr(token);
1832
1951
  continue;
1833
1952
  }
1834
1953
  case 'heading': {
1835
- const headingToken = token;
1836
- out += this.renderer.heading(this.parseInline(headingToken.tokens), headingToken.depth, unescape(this.parseInline(headingToken.tokens, this.textRenderer)));
1954
+ out += this.renderer.heading(token);
1837
1955
  continue;
1838
1956
  }
1839
1957
  case 'code': {
1840
- const codeToken = token;
1841
- out += this.renderer.code(codeToken.text, codeToken.lang, !!codeToken.escaped);
1958
+ out += this.renderer.code(token);
1842
1959
  continue;
1843
1960
  }
1844
1961
  case 'table': {
1845
- const tableToken = token;
1846
- let header = '';
1847
- // header
1848
- let cell = '';
1849
- for (let j = 0; j < tableToken.header.length; j++) {
1850
- cell += this.renderer.tablecell(this.parseInline(tableToken.header[j].tokens), { header: true, align: tableToken.align[j] });
1851
- }
1852
- header += this.renderer.tablerow(cell);
1853
- let body = '';
1854
- for (let j = 0; j < tableToken.rows.length; j++) {
1855
- const row = tableToken.rows[j];
1856
- cell = '';
1857
- for (let k = 0; k < row.length; k++) {
1858
- cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: tableToken.align[k] });
1859
- }
1860
- body += this.renderer.tablerow(cell);
1861
- }
1862
- out += this.renderer.table(header, body);
1962
+ out += this.renderer.table(token);
1863
1963
  continue;
1864
1964
  }
1865
1965
  case 'blockquote': {
1866
- const blockquoteToken = token;
1867
- const body = this.parse(blockquoteToken.tokens);
1868
- out += this.renderer.blockquote(body);
1966
+ out += this.renderer.blockquote(token);
1869
1967
  continue;
1870
1968
  }
1871
1969
  case 'list': {
1872
- const listToken = token;
1873
- const ordered = listToken.ordered;
1874
- const start = listToken.start;
1875
- const loose = listToken.loose;
1876
- let body = '';
1877
- for (let j = 0; j < listToken.items.length; j++) {
1878
- const item = listToken.items[j];
1879
- const checked = item.checked;
1880
- const task = item.task;
1881
- let itemBody = '';
1882
- if (item.task) {
1883
- const checkbox = this.renderer.checkbox(!!checked);
1884
- if (loose) {
1885
- if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
1886
- item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1887
- if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1888
- item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
1889
- }
1890
- }
1891
- else {
1892
- item.tokens.unshift({
1893
- type: 'text',
1894
- text: checkbox + ' '
1895
- });
1896
- }
1897
- }
1898
- else {
1899
- itemBody += checkbox + ' ';
1900
- }
1901
- }
1902
- itemBody += this.parse(item.tokens, loose);
1903
- body += this.renderer.listitem(itemBody, task, !!checked);
1904
- }
1905
- out += this.renderer.list(body, ordered, start);
1970
+ out += this.renderer.list(token);
1906
1971
  continue;
1907
1972
  }
1908
1973
  case 'html': {
1909
- const htmlToken = token;
1910
- out += this.renderer.html(htmlToken.text, htmlToken.block);
1974
+ out += this.renderer.html(token);
1911
1975
  continue;
1912
1976
  }
1913
1977
  case 'paragraph': {
1914
- const paragraphToken = token;
1915
- out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens));
1978
+ out += this.renderer.paragraph(token);
1916
1979
  continue;
1917
1980
  }
1918
1981
  case 'text': {
1919
1982
  let textToken = token;
1920
- let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text;
1983
+ let body = this.renderer.text(textToken);
1921
1984
  while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
1922
1985
  textToken = tokens[++i];
1923
- body += '\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text);
1986
+ body += '\n' + this.renderer.text(textToken);
1987
+ }
1988
+ if (top) {
1989
+ out += this.renderer.paragraph({
1990
+ type: 'paragraph',
1991
+ raw: body,
1992
+ text: body,
1993
+ tokens: [{ type: 'text', raw: body, text: body }]
1994
+ });
1995
+ }
1996
+ else {
1997
+ out += body;
1924
1998
  }
1925
- out += top ? this.renderer.paragraph(body) : body;
1926
1999
  continue;
1927
2000
  }
1928
2001
  default: {
@@ -1946,63 +2019,55 @@ class _Parser {
1946
2019
  renderer = renderer || this.renderer;
1947
2020
  let out = '';
1948
2021
  for (let i = 0; i < tokens.length; i++) {
1949
- const token = tokens[i];
2022
+ const anyToken = tokens[i];
1950
2023
  // Run any renderer extensions
1951
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
1952
- const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
1953
- if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
2024
+ if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
2025
+ const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
2026
+ if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
1954
2027
  out += ret || '';
1955
2028
  continue;
1956
2029
  }
1957
2030
  }
2031
+ const token = anyToken;
1958
2032
  switch (token.type) {
1959
2033
  case 'escape': {
1960
- const escapeToken = token;
1961
- out += renderer.text(escapeToken.text);
2034
+ out += renderer.text(token);
1962
2035
  break;
1963
2036
  }
1964
2037
  case 'html': {
1965
- const tagToken = token;
1966
- out += renderer.html(tagToken.text);
2038
+ out += renderer.html(token);
1967
2039
  break;
1968
2040
  }
1969
2041
  case 'link': {
1970
- const linkToken = token;
1971
- out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer));
2042
+ out += renderer.link(token);
1972
2043
  break;
1973
2044
  }
1974
2045
  case 'image': {
1975
- const imageToken = token;
1976
- out += renderer.image(imageToken.href, imageToken.title, imageToken.text);
2046
+ out += renderer.image(token);
1977
2047
  break;
1978
2048
  }
1979
2049
  case 'strong': {
1980
- const strongToken = token;
1981
- out += renderer.strong(this.parseInline(strongToken.tokens, renderer));
2050
+ out += renderer.strong(token);
1982
2051
  break;
1983
2052
  }
1984
2053
  case 'em': {
1985
- const emToken = token;
1986
- out += renderer.em(this.parseInline(emToken.tokens, renderer));
2054
+ out += renderer.em(token);
1987
2055
  break;
1988
2056
  }
1989
2057
  case 'codespan': {
1990
- const codespanToken = token;
1991
- out += renderer.codespan(codespanToken.text);
2058
+ out += renderer.codespan(token);
1992
2059
  break;
1993
2060
  }
1994
2061
  case 'br': {
1995
- out += renderer.br();
2062
+ out += renderer.br(token);
1996
2063
  break;
1997
2064
  }
1998
2065
  case 'del': {
1999
- const delToken = token;
2000
- out += renderer.del(this.parseInline(delToken.tokens, renderer));
2066
+ out += renderer.del(token);
2001
2067
  break;
2002
2068
  }
2003
2069
  case 'text': {
2004
- const textToken = token;
2005
- out += renderer.text(textToken.text);
2070
+ out += renderer.text(token);
2006
2071
  break;
2007
2072
  }
2008
2073
  default: {
@@ -2178,15 +2243,19 @@ class Marked {
2178
2243
  if (!(prop in renderer)) {
2179
2244
  throw new Error(`renderer '${prop}' does not exist`);
2180
2245
  }
2181
- if (prop === 'options') {
2246
+ if (['options', 'parser'].includes(prop)) {
2182
2247
  // ignore options property
2183
2248
  continue;
2184
2249
  }
2185
2250
  const rendererProp = prop;
2186
- const rendererFunc = pack.renderer[rendererProp];
2251
+ let rendererFunc = pack.renderer[rendererProp];
2187
2252
  const prevRenderer = renderer[rendererProp];
2188
2253
  // Replace renderer with func to run extension, but fall back if false
2189
2254
  renderer[rendererProp] = (...args) => {
2255
+ if (!pack.useNewRenderer) {
2256
+ // TODO: Remove this in next major version
2257
+ rendererFunc = this.#convertRendererFunction(rendererFunc, rendererProp, renderer);
2258
+ }
2190
2259
  let ret = rendererFunc.apply(renderer, args);
2191
2260
  if (ret === false) {
2192
2261
  ret = prevRenderer.apply(renderer, args);
@@ -2277,6 +2346,215 @@ class Marked {
2277
2346
  });
2278
2347
  return this;
2279
2348
  }
2349
+ // TODO: Remove this in next major release
2350
+ #convertRendererFunction(func, prop, renderer) {
2351
+ switch (prop) {
2352
+ case 'heading':
2353
+ return function (token) {
2354
+ if (!token.type || token.type !== prop) {
2355
+ // @ts-ignore
2356
+ // eslint-disable-next-line prefer-rest-params
2357
+ return func.apply(this, arguments);
2358
+ }
2359
+ return func(renderer.parser.parseInline(token.tokens), token.depth, unescape(renderer.parser.parseInline(token.tokens, renderer.parser.textRenderer)));
2360
+ };
2361
+ case 'code':
2362
+ return function (token) {
2363
+ if (!token.type || token.type !== prop) {
2364
+ // @ts-ignore
2365
+ // eslint-disable-next-line prefer-rest-params
2366
+ return func.apply(this, arguments);
2367
+ }
2368
+ return func(token.text, token.lang, !!token.escaped);
2369
+ };
2370
+ case 'table':
2371
+ return function (token) {
2372
+ if (!token.type || token.type !== prop) {
2373
+ // @ts-ignore
2374
+ // eslint-disable-next-line prefer-rest-params
2375
+ return func.apply(this, arguments);
2376
+ }
2377
+ let header = '';
2378
+ // header
2379
+ let cell = '';
2380
+ for (let j = 0; j < token.header.length; j++) {
2381
+ cell += this.tablecell({
2382
+ text: token.header[j].text,
2383
+ tokens: token.header[j].tokens,
2384
+ header: true,
2385
+ align: token.align[j]
2386
+ });
2387
+ }
2388
+ header += this.tablerow({ text: cell });
2389
+ let body = '';
2390
+ for (let j = 0; j < token.rows.length; j++) {
2391
+ const row = token.rows[j];
2392
+ cell = '';
2393
+ for (let k = 0; k < row.length; k++) {
2394
+ cell += this.tablecell({
2395
+ text: row[k].text,
2396
+ tokens: row[k].tokens,
2397
+ header: false,
2398
+ align: token.align[k]
2399
+ });
2400
+ }
2401
+ body += this.tablerow({ text: cell });
2402
+ }
2403
+ return func(header, body);
2404
+ };
2405
+ case 'blockquote':
2406
+ return function (token) {
2407
+ if (!token.type || token.type !== prop) {
2408
+ // @ts-ignore
2409
+ // eslint-disable-next-line prefer-rest-params
2410
+ return func.apply(this, arguments);
2411
+ }
2412
+ const body = this.parser.parse(token.tokens);
2413
+ return func(body);
2414
+ };
2415
+ case 'list':
2416
+ return function (token) {
2417
+ if (!token.type || token.type !== prop) {
2418
+ // @ts-ignore
2419
+ // eslint-disable-next-line prefer-rest-params
2420
+ return func.apply(this, arguments);
2421
+ }
2422
+ const ordered = token.ordered;
2423
+ const start = token.start;
2424
+ const loose = token.loose;
2425
+ let body = '';
2426
+ for (let j = 0; j < token.items.length; j++) {
2427
+ const item = token.items[j];
2428
+ const checked = item.checked;
2429
+ const task = item.task;
2430
+ let itemBody = '';
2431
+ if (item.task) {
2432
+ const checkbox = this.checkbox({ checked: !!checked });
2433
+ if (loose) {
2434
+ if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
2435
+ item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
2436
+ if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
2437
+ item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
2438
+ }
2439
+ }
2440
+ else {
2441
+ item.tokens.unshift({
2442
+ type: 'text',
2443
+ text: checkbox + ' '
2444
+ });
2445
+ }
2446
+ }
2447
+ else {
2448
+ itemBody += checkbox + ' ';
2449
+ }
2450
+ }
2451
+ itemBody += this.parser.parse(item.tokens, loose);
2452
+ body += this.listitem({
2453
+ type: 'list_item',
2454
+ raw: itemBody,
2455
+ text: itemBody,
2456
+ task,
2457
+ checked: !!checked,
2458
+ loose,
2459
+ tokens: item.tokens
2460
+ });
2461
+ }
2462
+ return func(body, ordered, start);
2463
+ };
2464
+ case 'html':
2465
+ return function (token) {
2466
+ if (!token.type || token.type !== prop) {
2467
+ // @ts-ignore
2468
+ // eslint-disable-next-line prefer-rest-params
2469
+ return func.apply(this, arguments);
2470
+ }
2471
+ return func(token.text, token.block);
2472
+ };
2473
+ case 'paragraph':
2474
+ return function (token) {
2475
+ if (!token.type || token.type !== prop) {
2476
+ // @ts-ignore
2477
+ // eslint-disable-next-line prefer-rest-params
2478
+ return func.apply(this, arguments);
2479
+ }
2480
+ return func(this.parser.parseInline(token.tokens));
2481
+ };
2482
+ case 'escape':
2483
+ return function (token) {
2484
+ if (!token.type || token.type !== prop) {
2485
+ // @ts-ignore
2486
+ // eslint-disable-next-line prefer-rest-params
2487
+ return func.apply(this, arguments);
2488
+ }
2489
+ return func(token.text);
2490
+ };
2491
+ case 'link':
2492
+ return function (token) {
2493
+ if (!token.type || token.type !== prop) {
2494
+ // @ts-ignore
2495
+ // eslint-disable-next-line prefer-rest-params
2496
+ return func.apply(this, arguments);
2497
+ }
2498
+ return func(token.href, token.title, this.parser.parseInline(token.tokens));
2499
+ };
2500
+ case 'image':
2501
+ return function (token) {
2502
+ if (!token.type || token.type !== prop) {
2503
+ // @ts-ignore
2504
+ // eslint-disable-next-line prefer-rest-params
2505
+ return func.apply(this, arguments);
2506
+ }
2507
+ return func(token.href, token.title, token.text);
2508
+ };
2509
+ case 'strong':
2510
+ return function (token) {
2511
+ if (!token.type || token.type !== prop) {
2512
+ // @ts-ignore
2513
+ // eslint-disable-next-line prefer-rest-params
2514
+ return func.apply(this, arguments);
2515
+ }
2516
+ return func(this.parser.parseInline(token.tokens));
2517
+ };
2518
+ case 'em':
2519
+ return function (token) {
2520
+ if (!token.type || token.type !== prop) {
2521
+ // @ts-ignore
2522
+ // eslint-disable-next-line prefer-rest-params
2523
+ return func.apply(this, arguments);
2524
+ }
2525
+ return func(this.parser.parseInline(token.tokens));
2526
+ };
2527
+ case 'codespan':
2528
+ return function (token) {
2529
+ if (!token.type || token.type !== prop) {
2530
+ // @ts-ignore
2531
+ // eslint-disable-next-line prefer-rest-params
2532
+ return func.apply(this, arguments);
2533
+ }
2534
+ return func(token.text);
2535
+ };
2536
+ case 'del':
2537
+ return function (token) {
2538
+ if (!token.type || token.type !== prop) {
2539
+ // @ts-ignore
2540
+ // eslint-disable-next-line prefer-rest-params
2541
+ return func.apply(this, arguments);
2542
+ }
2543
+ return func(this.parser.parseInline(token.tokens));
2544
+ };
2545
+ case 'text':
2546
+ return function (token) {
2547
+ if (!token.type || token.type !== prop) {
2548
+ // @ts-ignore
2549
+ // eslint-disable-next-line prefer-rest-params
2550
+ return func.apply(this, arguments);
2551
+ }
2552
+ return func(token.text);
2553
+ };
2554
+ // do nothing
2555
+ }
2556
+ return func;
2557
+ }
2280
2558
  setOptions(opt) {
2281
2559
  this.defaults = { ...this.defaults, ...opt };
2282
2560
  return this;