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