marked 12.0.2 → 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.2 - 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,23 +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
- // precede setext continuation with 4 spaces so it isn't a setext
326
- let text = cap[0].replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g, '\n $1');
327
- text = rtrim(text.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;
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
+ }
332
391
  return {
333
392
  type: 'blockquote',
334
- raw: cap[0],
393
+ raw,
335
394
  tokens,
336
395
  text
337
396
  };
@@ -568,17 +627,21 @@ class _Tokenizer {
568
627
  item.align.push(null);
569
628
  }
570
629
  }
571
- for (const header of headers) {
630
+ for (let i = 0; i < headers.length; i++) {
572
631
  item.header.push({
573
- text: header,
574
- tokens: this.lexer.inline(header)
632
+ text: headers[i],
633
+ tokens: this.lexer.inline(headers[i]),
634
+ header: true,
635
+ align: item.align[i]
575
636
  });
576
637
  }
577
638
  for (const row of rows) {
578
- item.rows.push(splitCells(row, item.header.length).map(cell => {
639
+ item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
579
640
  return {
580
641
  text: cell,
581
- tokens: this.lexer.inline(cell)
642
+ tokens: this.lexer.inline(cell),
643
+ header: false,
644
+ align: item.align[i]
582
645
  };
583
646
  }));
584
647
  }
@@ -1274,7 +1337,7 @@ class _Lexer {
1274
1337
  this.inlineQueue = [];
1275
1338
  return this.tokens;
1276
1339
  }
1277
- blockTokens(src, tokens = []) {
1340
+ blockTokens(src, tokens = [], lastParagraphClipped = false) {
1278
1341
  if (this.options.pedantic) {
1279
1342
  src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
1280
1343
  }
@@ -1286,7 +1349,6 @@ class _Lexer {
1286
1349
  let token;
1287
1350
  let lastToken;
1288
1351
  let cutSrc;
1289
- let lastParagraphClipped;
1290
1352
  while (src) {
1291
1353
  if (this.options.extensions
1292
1354
  && this.options.extensions.block
@@ -1412,7 +1474,7 @@ class _Lexer {
1412
1474
  }
1413
1475
  if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1414
1476
  lastToken = tokens[tokens.length - 1];
1415
- if (lastParagraphClipped && lastToken.type === 'paragraph') {
1477
+ if (lastParagraphClipped && lastToken?.type === 'paragraph') {
1416
1478
  lastToken.raw += '\n' + token.raw;
1417
1479
  lastToken.text += '\n' + token.text;
1418
1480
  this.inlineQueue.pop();
@@ -1631,53 +1693,103 @@ class _Lexer {
1631
1693
  */
1632
1694
  class _Renderer {
1633
1695
  options;
1696
+ parser; // set by the parser
1634
1697
  constructor(options) {
1635
1698
  this.options = options || _defaults;
1636
1699
  }
1637
- code(code, infostring, escaped) {
1638
- const lang = (infostring || '').match(/^\S*/)?.[0];
1639
- code = code.replace(/\n$/, '') + '\n';
1640
- 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) {
1641
1707
  return '<pre><code>'
1642
1708
  + (escaped ? code : escape$1(code, true))
1643
1709
  + '</code></pre>\n';
1644
1710
  }
1645
1711
  return '<pre><code class="language-'
1646
- + escape$1(lang)
1712
+ + escape$1(langString)
1647
1713
  + '">'
1648
1714
  + (escaped ? code : escape$1(code, true))
1649
1715
  + '</code></pre>\n';
1650
1716
  }
1651
- blockquote(quote) {
1652
- return `<blockquote>\n${quote}</blockquote>\n`;
1717
+ blockquote({ tokens }) {
1718
+ const body = this.parser.parse(tokens);
1719
+ return `<blockquote>\n${body}</blockquote>\n`;
1653
1720
  }
1654
- html(html, block) {
1655
- return html;
1721
+ html({ text }) {
1722
+ return text;
1656
1723
  }
1657
- heading(text, level, raw) {
1658
- // ignore IDs
1659
- return `<h${level}>${text}</h${level}>\n`;
1724
+ heading({ tokens, depth }) {
1725
+ return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\n`;
1660
1726
  }
1661
- hr() {
1727
+ hr(token) {
1662
1728
  return '<hr>\n';
1663
1729
  }
1664
- 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
+ }
1665
1738
  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`;
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`;
1671
1767
  }
1672
- checkbox(checked) {
1768
+ checkbox({ checked }) {
1673
1769
  return '<input '
1674
1770
  + (checked ? 'checked="" ' : '')
1675
1771
  + 'disabled="" type="checkbox">';
1676
1772
  }
1677
- paragraph(text) {
1678
- return `<p>${text}</p>\n`;
1773
+ paragraph({ tokens }) {
1774
+ return `<p>${this.parser.parseInline(tokens)}</p>\n`;
1679
1775
  }
1680
- 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
+ }
1681
1793
  if (body)
1682
1794
  body = `<tbody>${body}</tbody>`;
1683
1795
  return '<table>\n'
@@ -1687,35 +1799,37 @@ class _Renderer {
1687
1799
  + body
1688
1800
  + '</table>\n';
1689
1801
  }
1690
- tablerow(content) {
1691
- return `<tr>\n${content}</tr>\n`;
1802
+ tablerow({ text }) {
1803
+ return `<tr>\n${text}</tr>\n`;
1692
1804
  }
1693
- tablecell(content, flags) {
1694
- const type = flags.header ? 'th' : 'td';
1695
- const tag = flags.align
1696
- ? `<${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}">`
1697
1810
  : `<${type}>`;
1698
1811
  return tag + content + `</${type}>\n`;
1699
1812
  }
1700
1813
  /**
1701
1814
  * span level renderer
1702
1815
  */
1703
- strong(text) {
1704
- return `<strong>${text}</strong>`;
1816
+ strong({ tokens }) {
1817
+ return `<strong>${this.parser.parseInline(tokens)}</strong>`;
1705
1818
  }
1706
- em(text) {
1707
- return `<em>${text}</em>`;
1819
+ em({ tokens }) {
1820
+ return `<em>${this.parser.parseInline(tokens)}</em>`;
1708
1821
  }
1709
- codespan(text) {
1822
+ codespan({ text }) {
1710
1823
  return `<code>${text}</code>`;
1711
1824
  }
1712
- br() {
1825
+ br(token) {
1713
1826
  return '<br>';
1714
1827
  }
1715
- del(text) {
1716
- return `<del>${text}</del>`;
1828
+ del({ tokens }) {
1829
+ return `<del>${this.parser.parseInline(tokens)}</del>`;
1717
1830
  }
1718
- link(href, title, text) {
1831
+ link({ href, title, tokens }) {
1832
+ const text = this.parser.parseInline(tokens);
1719
1833
  const cleanHref = cleanUrl(href);
1720
1834
  if (cleanHref === null) {
1721
1835
  return text;
@@ -1728,7 +1842,7 @@ class _Renderer {
1728
1842
  out += '>' + text + '</a>';
1729
1843
  return out;
1730
1844
  }
1731
- image(href, title, text) {
1845
+ image({ href, title, text }) {
1732
1846
  const cleanHref = cleanUrl(href);
1733
1847
  if (cleanHref === null) {
1734
1848
  return text;
@@ -1741,8 +1855,8 @@ class _Renderer {
1741
1855
  out += '>';
1742
1856
  return out;
1743
1857
  }
1744
- text(text) {
1745
- return text;
1858
+ text(token) {
1859
+ return 'tokens' in token && token.tokens ? this.parser.parseInline(token.tokens) : token.text;
1746
1860
  }
1747
1861
  }
1748
1862
 
@@ -1752,28 +1866,28 @@ class _Renderer {
1752
1866
  */
1753
1867
  class _TextRenderer {
1754
1868
  // no need for block level renderers
1755
- strong(text) {
1869
+ strong({ text }) {
1756
1870
  return text;
1757
1871
  }
1758
- em(text) {
1872
+ em({ text }) {
1759
1873
  return text;
1760
1874
  }
1761
- codespan(text) {
1875
+ codespan({ text }) {
1762
1876
  return text;
1763
1877
  }
1764
- del(text) {
1878
+ del({ text }) {
1765
1879
  return text;
1766
1880
  }
1767
- html(text) {
1881
+ html({ text }) {
1768
1882
  return text;
1769
1883
  }
1770
- text(text) {
1884
+ text({ text }) {
1771
1885
  return text;
1772
1886
  }
1773
- link(href, title, text) {
1887
+ link({ text }) {
1774
1888
  return '' + text;
1775
1889
  }
1776
- image(href, title, text) {
1890
+ image({ text }) {
1777
1891
  return '' + text;
1778
1892
  }
1779
1893
  br() {
@@ -1793,6 +1907,7 @@ class _Parser {
1793
1907
  this.options.renderer = this.options.renderer || new _Renderer();
1794
1908
  this.renderer = this.options.renderer;
1795
1909
  this.renderer.options = this.options;
1910
+ this.renderer.parser = this;
1796
1911
  this.textRenderer = new _TextRenderer();
1797
1912
  }
1798
1913
  /**
@@ -1815,116 +1930,72 @@ class _Parser {
1815
1930
  parse(tokens, top = true) {
1816
1931
  let out = '';
1817
1932
  for (let i = 0; i < tokens.length; i++) {
1818
- const token = tokens[i];
1933
+ const anyToken = tokens[i];
1819
1934
  // Run any renderer extensions
1820
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
1821
- const genericToken = token;
1935
+ if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
1936
+ const genericToken = anyToken;
1822
1937
  const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
1823
1938
  if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
1824
1939
  out += ret || '';
1825
1940
  continue;
1826
1941
  }
1827
1942
  }
1943
+ const token = anyToken;
1828
1944
  switch (token.type) {
1829
1945
  case 'space': {
1946
+ out += this.renderer.space(token);
1830
1947
  continue;
1831
1948
  }
1832
1949
  case 'hr': {
1833
- out += this.renderer.hr();
1950
+ out += this.renderer.hr(token);
1834
1951
  continue;
1835
1952
  }
1836
1953
  case 'heading': {
1837
- const headingToken = token;
1838
- out += this.renderer.heading(this.parseInline(headingToken.tokens), headingToken.depth, unescape(this.parseInline(headingToken.tokens, this.textRenderer)));
1954
+ out += this.renderer.heading(token);
1839
1955
  continue;
1840
1956
  }
1841
1957
  case 'code': {
1842
- const codeToken = token;
1843
- out += this.renderer.code(codeToken.text, codeToken.lang, !!codeToken.escaped);
1958
+ out += this.renderer.code(token);
1844
1959
  continue;
1845
1960
  }
1846
1961
  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);
1962
+ out += this.renderer.table(token);
1865
1963
  continue;
1866
1964
  }
1867
1965
  case 'blockquote': {
1868
- const blockquoteToken = token;
1869
- const body = this.parse(blockquoteToken.tokens);
1870
- out += this.renderer.blockquote(body);
1966
+ out += this.renderer.blockquote(token);
1871
1967
  continue;
1872
1968
  }
1873
1969
  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);
1970
+ out += this.renderer.list(token);
1908
1971
  continue;
1909
1972
  }
1910
1973
  case 'html': {
1911
- const htmlToken = token;
1912
- out += this.renderer.html(htmlToken.text, htmlToken.block);
1974
+ out += this.renderer.html(token);
1913
1975
  continue;
1914
1976
  }
1915
1977
  case 'paragraph': {
1916
- const paragraphToken = token;
1917
- out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens));
1978
+ out += this.renderer.paragraph(token);
1918
1979
  continue;
1919
1980
  }
1920
1981
  case 'text': {
1921
1982
  let textToken = token;
1922
- let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text;
1983
+ let body = this.renderer.text(textToken);
1923
1984
  while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
1924
1985
  textToken = tokens[++i];
1925
- 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;
1926
1998
  }
1927
- out += top ? this.renderer.paragraph(body) : body;
1928
1999
  continue;
1929
2000
  }
1930
2001
  default: {
@@ -1948,63 +2019,55 @@ class _Parser {
1948
2019
  renderer = renderer || this.renderer;
1949
2020
  let out = '';
1950
2021
  for (let i = 0; i < tokens.length; i++) {
1951
- const token = tokens[i];
2022
+ const anyToken = tokens[i];
1952
2023
  // 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)) {
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)) {
1956
2027
  out += ret || '';
1957
2028
  continue;
1958
2029
  }
1959
2030
  }
2031
+ const token = anyToken;
1960
2032
  switch (token.type) {
1961
2033
  case 'escape': {
1962
- const escapeToken = token;
1963
- out += renderer.text(escapeToken.text);
2034
+ out += renderer.text(token);
1964
2035
  break;
1965
2036
  }
1966
2037
  case 'html': {
1967
- const tagToken = token;
1968
- out += renderer.html(tagToken.text);
2038
+ out += renderer.html(token);
1969
2039
  break;
1970
2040
  }
1971
2041
  case 'link': {
1972
- const linkToken = token;
1973
- out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer));
2042
+ out += renderer.link(token);
1974
2043
  break;
1975
2044
  }
1976
2045
  case 'image': {
1977
- const imageToken = token;
1978
- out += renderer.image(imageToken.href, imageToken.title, imageToken.text);
2046
+ out += renderer.image(token);
1979
2047
  break;
1980
2048
  }
1981
2049
  case 'strong': {
1982
- const strongToken = token;
1983
- out += renderer.strong(this.parseInline(strongToken.tokens, renderer));
2050
+ out += renderer.strong(token);
1984
2051
  break;
1985
2052
  }
1986
2053
  case 'em': {
1987
- const emToken = token;
1988
- out += renderer.em(this.parseInline(emToken.tokens, renderer));
2054
+ out += renderer.em(token);
1989
2055
  break;
1990
2056
  }
1991
2057
  case 'codespan': {
1992
- const codespanToken = token;
1993
- out += renderer.codespan(codespanToken.text);
2058
+ out += renderer.codespan(token);
1994
2059
  break;
1995
2060
  }
1996
2061
  case 'br': {
1997
- out += renderer.br();
2062
+ out += renderer.br(token);
1998
2063
  break;
1999
2064
  }
2000
2065
  case 'del': {
2001
- const delToken = token;
2002
- out += renderer.del(this.parseInline(delToken.tokens, renderer));
2066
+ out += renderer.del(token);
2003
2067
  break;
2004
2068
  }
2005
2069
  case 'text': {
2006
- const textToken = token;
2007
- out += renderer.text(textToken.text);
2070
+ out += renderer.text(token);
2008
2071
  break;
2009
2072
  }
2010
2073
  default: {
@@ -2180,15 +2243,19 @@ class Marked {
2180
2243
  if (!(prop in renderer)) {
2181
2244
  throw new Error(`renderer '${prop}' does not exist`);
2182
2245
  }
2183
- if (prop === 'options') {
2246
+ if (['options', 'parser'].includes(prop)) {
2184
2247
  // ignore options property
2185
2248
  continue;
2186
2249
  }
2187
2250
  const rendererProp = prop;
2188
- const rendererFunc = pack.renderer[rendererProp];
2251
+ let rendererFunc = pack.renderer[rendererProp];
2189
2252
  const prevRenderer = renderer[rendererProp];
2190
2253
  // Replace renderer with func to run extension, but fall back if false
2191
2254
  renderer[rendererProp] = (...args) => {
2255
+ if (!pack.useNewRenderer) {
2256
+ // TODO: Remove this in next major version
2257
+ rendererFunc = this.#convertRendererFunction(rendererFunc, rendererProp, renderer);
2258
+ }
2192
2259
  let ret = rendererFunc.apply(renderer, args);
2193
2260
  if (ret === false) {
2194
2261
  ret = prevRenderer.apply(renderer, args);
@@ -2279,6 +2346,215 @@ class Marked {
2279
2346
  });
2280
2347
  return this;
2281
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
+ }
2282
2558
  setOptions(opt) {
2283
2559
  this.defaults = { ...this.defaults, ...opt };
2284
2560
  return this;