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.umd.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
  */
@@ -259,7 +259,7 @@
259
259
  const br = /^( {2,}|\\)\n(?!\s*$)/;
260
260
  const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
261
261
  // list of unicode punctuation marks, plus any missing characters from CommonMark spec
262
- const _punctuation = '\\p{P}\\p{S}';
262
+ const _punctuation = /\p{P}\p{S}/u;
263
263
  const punctuation = edit(/^((?![*_])[\spunctuation])/, 'u')
264
264
  .replace(/punctuation/g, _punctuation).getRegex();
265
265
  // sequences em should skip over [title](link), `code`, <html>
@@ -452,7 +452,7 @@
452
452
  if (!cells[0].trim()) {
453
453
  cells.shift();
454
454
  }
455
- if (cells.length > 0 && !cells[cells.length - 1].trim()) {
455
+ if (cells.length > 0 && !cells.at(-1)?.trim()) {
456
456
  cells.pop();
457
457
  }
458
458
  if (count) {
@@ -689,7 +689,7 @@
689
689
  if (lines.length === 0) {
690
690
  break;
691
691
  }
692
- const lastToken = tokens[tokens.length - 1];
692
+ const lastToken = tokens.at(-1);
693
693
  if (lastToken?.type === 'code') {
694
694
  // blockquote continuation cannot be preceded by a code block
695
695
  break;
@@ -712,7 +712,7 @@
712
712
  tokens[tokens.length - 1] = newToken;
713
713
  raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
714
714
  text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
715
- lines = newText.substring(tokens[tokens.length - 1].raw.length).split('\n');
715
+ lines = newText.substring(tokens.at(-1).raw.length).split('\n');
716
716
  continue;
717
717
  }
718
718
  }
@@ -880,8 +880,11 @@
880
880
  list.raw += raw;
881
881
  }
882
882
  // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
883
- list.items[list.items.length - 1].raw = list.items[list.items.length - 1].raw.trimEnd();
884
- list.items[list.items.length - 1].text = list.items[list.items.length - 1].text.trimEnd();
883
+ const lastItem = list.items.at(-1);
884
+ if (lastItem) {
885
+ lastItem.raw = lastItem.raw.trimEnd();
886
+ lastItem.text = lastItem.text.trimEnd();
887
+ }
885
888
  list.raw = list.raw.trimEnd();
886
889
  // Item child tokens handled here at end because we needed to have the final item to trim it first
887
890
  for (let i = 0; i < list.items.length; i++) {
@@ -942,7 +945,7 @@
942
945
  }
943
946
  const headers = splitCells(cap[1]);
944
947
  const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');
945
- const rows = cap[3] && cap[3].trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
948
+ const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
946
949
  const item = {
947
950
  type: 'table',
948
951
  raw: cap[0],
@@ -1378,8 +1381,7 @@
1378
1381
  * Preprocessing
1379
1382
  */
1380
1383
  lex(src) {
1381
- src = src
1382
- .replace(other.carriageReturn, '\n');
1384
+ src = src.replace(other.carriageReturn, '\n');
1383
1385
  this.blockTokens(src, this.tokens);
1384
1386
  for (let i = 0; i < this.inlineQueue.length; i++) {
1385
1387
  const next = this.inlineQueue[i];
@@ -1392,29 +1394,26 @@
1392
1394
  if (this.options.pedantic) {
1393
1395
  src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');
1394
1396
  }
1395
- let token;
1396
- let lastToken;
1397
- let cutSrc;
1398
1397
  while (src) {
1399
- if (this.options.extensions
1400
- && this.options.extensions.block
1401
- && this.options.extensions.block.some((extTokenizer) => {
1402
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1403
- src = src.substring(token.raw.length);
1404
- tokens.push(token);
1405
- return true;
1406
- }
1407
- return false;
1408
- })) {
1398
+ let token;
1399
+ if (this.options.extensions?.block?.some((extTokenizer) => {
1400
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1401
+ src = src.substring(token.raw.length);
1402
+ tokens.push(token);
1403
+ return true;
1404
+ }
1405
+ return false;
1406
+ })) {
1409
1407
  continue;
1410
1408
  }
1411
1409
  // newline
1412
1410
  if (token = this.tokenizer.space(src)) {
1413
1411
  src = src.substring(token.raw.length);
1414
- if (token.raw.length === 1 && tokens.length > 0) {
1412
+ const lastToken = tokens.at(-1);
1413
+ if (token.raw.length === 1 && lastToken !== undefined) {
1415
1414
  // if there's a single \n as a spacer, it's terminating the last line,
1416
1415
  // so move it there so that we don't get unnecessary paragraph tags
1417
- tokens[tokens.length - 1].raw += '\n';
1416
+ lastToken.raw += '\n';
1418
1417
  }
1419
1418
  else {
1420
1419
  tokens.push(token);
@@ -1424,12 +1423,12 @@
1424
1423
  // code
1425
1424
  if (token = this.tokenizer.code(src)) {
1426
1425
  src = src.substring(token.raw.length);
1427
- lastToken = tokens[tokens.length - 1];
1426
+ const lastToken = tokens.at(-1);
1428
1427
  // An indented code block cannot interrupt a paragraph.
1429
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1428
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
1430
1429
  lastToken.raw += '\n' + token.raw;
1431
1430
  lastToken.text += '\n' + token.text;
1432
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1431
+ this.inlineQueue.at(-1).src = lastToken.text;
1433
1432
  }
1434
1433
  else {
1435
1434
  tokens.push(token);
@@ -1475,11 +1474,11 @@
1475
1474
  // def
1476
1475
  if (token = this.tokenizer.def(src)) {
1477
1476
  src = src.substring(token.raw.length);
1478
- lastToken = tokens[tokens.length - 1];
1479
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1477
+ const lastToken = tokens.at(-1);
1478
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
1480
1479
  lastToken.raw += '\n' + token.raw;
1481
1480
  lastToken.text += '\n' + token.raw;
1482
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1481
+ this.inlineQueue.at(-1).src = lastToken.text;
1483
1482
  }
1484
1483
  else if (!this.tokens.links[token.tag]) {
1485
1484
  this.tokens.links[token.tag] = {
@@ -1503,8 +1502,8 @@
1503
1502
  }
1504
1503
  // top-level paragraph
1505
1504
  // prevent paragraph consuming extensions by clipping 'src' to extension start
1506
- cutSrc = src;
1507
- if (this.options.extensions && this.options.extensions.startBlock) {
1505
+ let cutSrc = src;
1506
+ if (this.options.extensions?.startBlock) {
1508
1507
  let startIndex = Infinity;
1509
1508
  const tempSrc = src.slice(1);
1510
1509
  let tempStart;
@@ -1519,29 +1518,29 @@
1519
1518
  }
1520
1519
  }
1521
1520
  if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1522
- lastToken = tokens[tokens.length - 1];
1521
+ const lastToken = tokens.at(-1);
1523
1522
  if (lastParagraphClipped && lastToken?.type === 'paragraph') {
1524
1523
  lastToken.raw += '\n' + token.raw;
1525
1524
  lastToken.text += '\n' + token.text;
1526
1525
  this.inlineQueue.pop();
1527
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1526
+ this.inlineQueue.at(-1).src = lastToken.text;
1528
1527
  }
1529
1528
  else {
1530
1529
  tokens.push(token);
1531
1530
  }
1532
- lastParagraphClipped = (cutSrc.length !== src.length);
1531
+ lastParagraphClipped = cutSrc.length !== src.length;
1533
1532
  src = src.substring(token.raw.length);
1534
1533
  continue;
1535
1534
  }
1536
1535
  // text
1537
1536
  if (token = this.tokenizer.text(src)) {
1538
1537
  src = src.substring(token.raw.length);
1539
- lastToken = tokens[tokens.length - 1];
1540
- if (lastToken && lastToken.type === 'text') {
1538
+ const lastToken = tokens.at(-1);
1539
+ if (lastToken?.type === 'text') {
1541
1540
  lastToken.raw += '\n' + token.raw;
1542
1541
  lastToken.text += '\n' + token.text;
1543
1542
  this.inlineQueue.pop();
1544
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1543
+ this.inlineQueue.at(-1).src = lastToken.text;
1545
1544
  }
1546
1545
  else {
1547
1546
  tokens.push(token);
@@ -1570,18 +1569,18 @@
1570
1569
  * Lexing/Compiling
1571
1570
  */
1572
1571
  inlineTokens(src, tokens = []) {
1573
- let token, lastToken, cutSrc;
1574
1572
  // String with links masked to avoid interference with em and strong
1575
1573
  let maskedSrc = src;
1576
- let match;
1577
- let keepPrevChar, prevChar;
1574
+ let match = null;
1578
1575
  // Mask out reflinks
1579
1576
  if (this.tokens.links) {
1580
1577
  const links = Object.keys(this.tokens.links);
1581
1578
  if (links.length > 0) {
1582
1579
  while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
1583
1580
  if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
1584
- maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
1581
+ maskedSrc = maskedSrc.slice(0, match.index)
1582
+ + '[' + 'a'.repeat(match[0].length - 2) + ']'
1583
+ + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
1585
1584
  }
1586
1585
  }
1587
1586
  }
@@ -1594,22 +1593,23 @@
1594
1593
  while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
1595
1594
  maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
1596
1595
  }
1596
+ let keepPrevChar = false;
1597
+ let prevChar = '';
1597
1598
  while (src) {
1598
1599
  if (!keepPrevChar) {
1599
1600
  prevChar = '';
1600
1601
  }
1601
1602
  keepPrevChar = false;
1603
+ let token;
1602
1604
  // extensions
1603
- if (this.options.extensions
1604
- && this.options.extensions.inline
1605
- && this.options.extensions.inline.some((extTokenizer) => {
1606
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1607
- src = src.substring(token.raw.length);
1608
- tokens.push(token);
1609
- return true;
1610
- }
1611
- return false;
1612
- })) {
1605
+ if (this.options.extensions?.inline?.some((extTokenizer) => {
1606
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1607
+ src = src.substring(token.raw.length);
1608
+ tokens.push(token);
1609
+ return true;
1610
+ }
1611
+ return false;
1612
+ })) {
1613
1613
  continue;
1614
1614
  }
1615
1615
  // escape
@@ -1621,7 +1621,6 @@
1621
1621
  // tag
1622
1622
  if (token = this.tokenizer.tag(src)) {
1623
1623
  src = src.substring(token.raw.length);
1624
- lastToken = tokens[tokens.length - 1];
1625
1624
  tokens.push(token);
1626
1625
  continue;
1627
1626
  }
@@ -1634,8 +1633,8 @@
1634
1633
  // reflink, nolink
1635
1634
  if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1636
1635
  src = src.substring(token.raw.length);
1637
- lastToken = tokens[tokens.length - 1];
1638
- if (lastToken && token.type === 'text' && lastToken.type === 'text') {
1636
+ const lastToken = tokens.at(-1);
1637
+ if (token.type === 'text' && lastToken?.type === 'text') {
1639
1638
  lastToken.raw += token.raw;
1640
1639
  lastToken.text += token.text;
1641
1640
  }
@@ -1682,8 +1681,8 @@
1682
1681
  }
1683
1682
  // text
1684
1683
  // prevent inlineText consuming extensions by clipping 'src' to extension start
1685
- cutSrc = src;
1686
- if (this.options.extensions && this.options.extensions.startInline) {
1684
+ let cutSrc = src;
1685
+ if (this.options.extensions?.startInline) {
1687
1686
  let startIndex = Infinity;
1688
1687
  const tempSrc = src.slice(1);
1689
1688
  let tempStart;
@@ -1703,8 +1702,8 @@
1703
1702
  prevChar = token.raw.slice(-1);
1704
1703
  }
1705
1704
  keepPrevChar = true;
1706
- lastToken = tokens[tokens.length - 1];
1707
- if (lastToken && lastToken.type === 'text') {
1705
+ const lastToken = tokens.at(-1);
1706
+ if (lastToken?.type === 'text') {
1708
1707
  lastToken.raw += token.raw;
1709
1708
  lastToken.text += token.text;
1710
1709
  }
@@ -1784,7 +1783,7 @@
1784
1783
  if (item.task) {
1785
1784
  const checkbox = this.checkbox({ checked: !!item.checked });
1786
1785
  if (item.loose) {
1787
- if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
1786
+ if (item.tokens[0]?.type === 'paragraph') {
1788
1787
  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1789
1788
  if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1790
1789
  item.tokens[0].tokens[0].text = checkbox + ' ' + escape(item.tokens[0].tokens[0].text);
@@ -1976,7 +1975,7 @@
1976
1975
  for (let i = 0; i < tokens.length; i++) {
1977
1976
  const anyToken = tokens[i];
1978
1977
  // Run any renderer extensions
1979
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
1978
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
1980
1979
  const genericToken = anyToken;
1981
1980
  const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
1982
1981
  if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
@@ -2059,13 +2058,12 @@
2059
2058
  /**
2060
2059
  * Parse Inline Tokens
2061
2060
  */
2062
- parseInline(tokens, renderer) {
2063
- renderer = renderer || this.renderer;
2061
+ parseInline(tokens, renderer = this.renderer) {
2064
2062
  let out = '';
2065
2063
  for (let i = 0; i < tokens.length; i++) {
2066
2064
  const anyToken = tokens[i];
2067
2065
  // Run any renderer extensions
2068
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
2066
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
2069
2067
  const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
2070
2068
  if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
2071
2069
  out += ret || '';