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