marked 15.0.0 → 15.0.2

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 v15.0.0 - a markdown parser
2
+ * marked v15.0.2 - a markdown parser
3
3
  * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
4
4
  * https://github.com/markedjs/marked
5
5
  */
@@ -253,7 +253,7 @@ const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
253
253
  const br = /^( {2,}|\\)\n(?!\s*$)/;
254
254
  const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
255
255
  // list of unicode punctuation marks, plus any missing characters from CommonMark spec
256
- const _punctuation = '\\p{P}\\p{S}';
256
+ const _punctuation = /\p{P}\p{S}/u;
257
257
  const punctuation = edit(/^((?![*_])[\spunctuation])/, 'u')
258
258
  .replace(/punctuation/g, _punctuation).getRegex();
259
259
  // sequences em should skip over [title](link), `code`, <html>
@@ -446,7 +446,7 @@ function splitCells(tableRow, count) {
446
446
  if (!cells[0].trim()) {
447
447
  cells.shift();
448
448
  }
449
- if (cells.length > 0 && !cells[cells.length - 1].trim()) {
449
+ if (cells.length > 0 && !cells.at(-1)?.trim()) {
450
450
  cells.pop();
451
451
  }
452
452
  if (count) {
@@ -683,7 +683,7 @@ class _Tokenizer {
683
683
  if (lines.length === 0) {
684
684
  break;
685
685
  }
686
- const lastToken = tokens[tokens.length - 1];
686
+ const lastToken = tokens.at(-1);
687
687
  if (lastToken?.type === 'code') {
688
688
  // blockquote continuation cannot be preceded by a code block
689
689
  break;
@@ -706,7 +706,7 @@ class _Tokenizer {
706
706
  tokens[tokens.length - 1] = newToken;
707
707
  raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
708
708
  text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
709
- lines = newText.substring(tokens[tokens.length - 1].raw.length).split('\n');
709
+ lines = newText.substring(tokens.at(-1).raw.length).split('\n');
710
710
  continue;
711
711
  }
712
712
  }
@@ -874,8 +874,11 @@ class _Tokenizer {
874
874
  list.raw += raw;
875
875
  }
876
876
  // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
877
- list.items[list.items.length - 1].raw = list.items[list.items.length - 1].raw.trimEnd();
878
- list.items[list.items.length - 1].text = list.items[list.items.length - 1].text.trimEnd();
877
+ const lastItem = list.items.at(-1);
878
+ if (lastItem) {
879
+ lastItem.raw = lastItem.raw.trimEnd();
880
+ lastItem.text = lastItem.text.trimEnd();
881
+ }
879
882
  list.raw = list.raw.trimEnd();
880
883
  // Item child tokens handled here at end because we needed to have the final item to trim it first
881
884
  for (let i = 0; i < list.items.length; i++) {
@@ -936,7 +939,7 @@ class _Tokenizer {
936
939
  }
937
940
  const headers = splitCells(cap[1]);
938
941
  const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');
939
- const rows = cap[3] && cap[3].trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
942
+ const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
940
943
  const item = {
941
944
  type: 'table',
942
945
  raw: cap[0],
@@ -1372,8 +1375,7 @@ class _Lexer {
1372
1375
  * Preprocessing
1373
1376
  */
1374
1377
  lex(src) {
1375
- src = src
1376
- .replace(other.carriageReturn, '\n');
1378
+ src = src.replace(other.carriageReturn, '\n');
1377
1379
  this.blockTokens(src, this.tokens);
1378
1380
  for (let i = 0; i < this.inlineQueue.length; i++) {
1379
1381
  const next = this.inlineQueue[i];
@@ -1386,29 +1388,26 @@ class _Lexer {
1386
1388
  if (this.options.pedantic) {
1387
1389
  src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');
1388
1390
  }
1389
- let token;
1390
- let lastToken;
1391
- let cutSrc;
1392
1391
  while (src) {
1393
- if (this.options.extensions
1394
- && this.options.extensions.block
1395
- && this.options.extensions.block.some((extTokenizer) => {
1396
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1397
- src = src.substring(token.raw.length);
1398
- tokens.push(token);
1399
- return true;
1400
- }
1401
- return false;
1402
- })) {
1392
+ let token;
1393
+ if (this.options.extensions?.block?.some((extTokenizer) => {
1394
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1395
+ src = src.substring(token.raw.length);
1396
+ tokens.push(token);
1397
+ return true;
1398
+ }
1399
+ return false;
1400
+ })) {
1403
1401
  continue;
1404
1402
  }
1405
1403
  // newline
1406
1404
  if (token = this.tokenizer.space(src)) {
1407
1405
  src = src.substring(token.raw.length);
1408
- if (token.raw.length === 1 && tokens.length > 0) {
1406
+ const lastToken = tokens.at(-1);
1407
+ if (token.raw.length === 1 && lastToken !== undefined) {
1409
1408
  // if there's a single \n as a spacer, it's terminating the last line,
1410
1409
  // so move it there so that we don't get unnecessary paragraph tags
1411
- tokens[tokens.length - 1].raw += '\n';
1410
+ lastToken.raw += '\n';
1412
1411
  }
1413
1412
  else {
1414
1413
  tokens.push(token);
@@ -1418,12 +1417,12 @@ class _Lexer {
1418
1417
  // code
1419
1418
  if (token = this.tokenizer.code(src)) {
1420
1419
  src = src.substring(token.raw.length);
1421
- lastToken = tokens[tokens.length - 1];
1420
+ const lastToken = tokens.at(-1);
1422
1421
  // An indented code block cannot interrupt a paragraph.
1423
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1422
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
1424
1423
  lastToken.raw += '\n' + token.raw;
1425
1424
  lastToken.text += '\n' + token.text;
1426
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1425
+ this.inlineQueue.at(-1).src = lastToken.text;
1427
1426
  }
1428
1427
  else {
1429
1428
  tokens.push(token);
@@ -1469,11 +1468,11 @@ class _Lexer {
1469
1468
  // def
1470
1469
  if (token = this.tokenizer.def(src)) {
1471
1470
  src = src.substring(token.raw.length);
1472
- lastToken = tokens[tokens.length - 1];
1473
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1471
+ const lastToken = tokens.at(-1);
1472
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
1474
1473
  lastToken.raw += '\n' + token.raw;
1475
1474
  lastToken.text += '\n' + token.raw;
1476
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1475
+ this.inlineQueue.at(-1).src = lastToken.text;
1477
1476
  }
1478
1477
  else if (!this.tokens.links[token.tag]) {
1479
1478
  this.tokens.links[token.tag] = {
@@ -1497,8 +1496,8 @@ class _Lexer {
1497
1496
  }
1498
1497
  // top-level paragraph
1499
1498
  // prevent paragraph consuming extensions by clipping 'src' to extension start
1500
- cutSrc = src;
1501
- if (this.options.extensions && this.options.extensions.startBlock) {
1499
+ let cutSrc = src;
1500
+ if (this.options.extensions?.startBlock) {
1502
1501
  let startIndex = Infinity;
1503
1502
  const tempSrc = src.slice(1);
1504
1503
  let tempStart;
@@ -1513,29 +1512,29 @@ class _Lexer {
1513
1512
  }
1514
1513
  }
1515
1514
  if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1516
- lastToken = tokens[tokens.length - 1];
1515
+ const lastToken = tokens.at(-1);
1517
1516
  if (lastParagraphClipped && lastToken?.type === 'paragraph') {
1518
1517
  lastToken.raw += '\n' + token.raw;
1519
1518
  lastToken.text += '\n' + token.text;
1520
1519
  this.inlineQueue.pop();
1521
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1520
+ this.inlineQueue.at(-1).src = lastToken.text;
1522
1521
  }
1523
1522
  else {
1524
1523
  tokens.push(token);
1525
1524
  }
1526
- lastParagraphClipped = (cutSrc.length !== src.length);
1525
+ lastParagraphClipped = cutSrc.length !== src.length;
1527
1526
  src = src.substring(token.raw.length);
1528
1527
  continue;
1529
1528
  }
1530
1529
  // text
1531
1530
  if (token = this.tokenizer.text(src)) {
1532
1531
  src = src.substring(token.raw.length);
1533
- lastToken = tokens[tokens.length - 1];
1534
- if (lastToken && lastToken.type === 'text') {
1532
+ const lastToken = tokens.at(-1);
1533
+ if (lastToken?.type === 'text') {
1535
1534
  lastToken.raw += '\n' + token.raw;
1536
1535
  lastToken.text += '\n' + token.text;
1537
1536
  this.inlineQueue.pop();
1538
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1537
+ this.inlineQueue.at(-1).src = lastToken.text;
1539
1538
  }
1540
1539
  else {
1541
1540
  tokens.push(token);
@@ -1564,18 +1563,18 @@ class _Lexer {
1564
1563
  * Lexing/Compiling
1565
1564
  */
1566
1565
  inlineTokens(src, tokens = []) {
1567
- let token, lastToken, cutSrc;
1568
1566
  // String with links masked to avoid interference with em and strong
1569
1567
  let maskedSrc = src;
1570
- let match;
1571
- let keepPrevChar, prevChar;
1568
+ let match = null;
1572
1569
  // Mask out reflinks
1573
1570
  if (this.tokens.links) {
1574
1571
  const links = Object.keys(this.tokens.links);
1575
1572
  if (links.length > 0) {
1576
1573
  while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
1577
1574
  if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
1578
- maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
1575
+ maskedSrc = maskedSrc.slice(0, match.index)
1576
+ + '[' + 'a'.repeat(match[0].length - 2) + ']'
1577
+ + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
1579
1578
  }
1580
1579
  }
1581
1580
  }
@@ -1588,22 +1587,23 @@ class _Lexer {
1588
1587
  while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
1589
1588
  maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
1590
1589
  }
1590
+ let keepPrevChar = false;
1591
+ let prevChar = '';
1591
1592
  while (src) {
1592
1593
  if (!keepPrevChar) {
1593
1594
  prevChar = '';
1594
1595
  }
1595
1596
  keepPrevChar = false;
1597
+ let token;
1596
1598
  // extensions
1597
- if (this.options.extensions
1598
- && this.options.extensions.inline
1599
- && this.options.extensions.inline.some((extTokenizer) => {
1600
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1601
- src = src.substring(token.raw.length);
1602
- tokens.push(token);
1603
- return true;
1604
- }
1605
- return false;
1606
- })) {
1599
+ if (this.options.extensions?.inline?.some((extTokenizer) => {
1600
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1601
+ src = src.substring(token.raw.length);
1602
+ tokens.push(token);
1603
+ return true;
1604
+ }
1605
+ return false;
1606
+ })) {
1607
1607
  continue;
1608
1608
  }
1609
1609
  // escape
@@ -1615,7 +1615,6 @@ class _Lexer {
1615
1615
  // tag
1616
1616
  if (token = this.tokenizer.tag(src)) {
1617
1617
  src = src.substring(token.raw.length);
1618
- lastToken = tokens[tokens.length - 1];
1619
1618
  tokens.push(token);
1620
1619
  continue;
1621
1620
  }
@@ -1628,8 +1627,8 @@ class _Lexer {
1628
1627
  // reflink, nolink
1629
1628
  if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1630
1629
  src = src.substring(token.raw.length);
1631
- lastToken = tokens[tokens.length - 1];
1632
- if (lastToken && token.type === 'text' && lastToken.type === 'text') {
1630
+ const lastToken = tokens.at(-1);
1631
+ if (token.type === 'text' && lastToken?.type === 'text') {
1633
1632
  lastToken.raw += token.raw;
1634
1633
  lastToken.text += token.text;
1635
1634
  }
@@ -1676,8 +1675,8 @@ class _Lexer {
1676
1675
  }
1677
1676
  // text
1678
1677
  // prevent inlineText consuming extensions by clipping 'src' to extension start
1679
- cutSrc = src;
1680
- if (this.options.extensions && this.options.extensions.startInline) {
1678
+ let cutSrc = src;
1679
+ if (this.options.extensions?.startInline) {
1681
1680
  let startIndex = Infinity;
1682
1681
  const tempSrc = src.slice(1);
1683
1682
  let tempStart;
@@ -1697,8 +1696,8 @@ class _Lexer {
1697
1696
  prevChar = token.raw.slice(-1);
1698
1697
  }
1699
1698
  keepPrevChar = true;
1700
- lastToken = tokens[tokens.length - 1];
1701
- if (lastToken && lastToken.type === 'text') {
1699
+ const lastToken = tokens.at(-1);
1700
+ if (lastToken?.type === 'text') {
1702
1701
  lastToken.raw += token.raw;
1703
1702
  lastToken.text += token.text;
1704
1703
  }
@@ -1778,7 +1777,7 @@ class _Renderer {
1778
1777
  if (item.task) {
1779
1778
  const checkbox = this.checkbox({ checked: !!item.checked });
1780
1779
  if (item.loose) {
1781
- if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
1780
+ if (item.tokens[0]?.type === 'paragraph') {
1782
1781
  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1783
1782
  if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1784
1783
  item.tokens[0].tokens[0].text = checkbox + ' ' + escape(item.tokens[0].tokens[0].text);
@@ -1970,7 +1969,7 @@ class _Parser {
1970
1969
  for (let i = 0; i < tokens.length; i++) {
1971
1970
  const anyToken = tokens[i];
1972
1971
  // Run any renderer extensions
1973
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
1972
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
1974
1973
  const genericToken = anyToken;
1975
1974
  const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
1976
1975
  if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
@@ -2053,13 +2052,12 @@ class _Parser {
2053
2052
  /**
2054
2053
  * Parse Inline Tokens
2055
2054
  */
2056
- parseInline(tokens, renderer) {
2057
- renderer = renderer || this.renderer;
2055
+ parseInline(tokens, renderer = this.renderer) {
2058
2056
  let out = '';
2059
2057
  for (let i = 0; i < tokens.length; i++) {
2060
2058
  const anyToken = tokens[i];
2061
2059
  // Run any renderer extensions
2062
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
2060
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
2063
2061
  const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
2064
2062
  if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
2065
2063
  out += ret || '';