marked 14.0.0 → 14.1.1

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 v14.0.0 - a markdown parser
2
+ * marked v14.1.1 - 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 @@
253
253
  code(src) {
254
254
  const cap = this.rules.block.code.exec(src);
255
255
  if (cap) {
256
- const text = cap[0].replace(/^ {1,4}/gm, '');
256
+ const text = cap[0].replace(/^(?: {1,4}| {0,3}\t)/gm, '');
257
257
  return {
258
258
  type: 'code',
259
259
  raw: cap[0],
@@ -437,7 +437,7 @@
437
437
  itemContents = line.slice(indent);
438
438
  indent += cap[1].length;
439
439
  }
440
- if (blankLine && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
440
+ if (blankLine && /^[ \t]*$/.test(nextLine)) { // Items begin with at most one blank line
441
441
  raw += nextLine + '\n';
442
442
  src = src.substring(nextLine.length + 1);
443
443
  endEarly = true;
@@ -450,10 +450,15 @@
450
450
  // Check if following lines should be included in List Item
451
451
  while (src) {
452
452
  const rawLine = src.split('\n', 1)[0];
453
+ let nextLineWithoutTabs;
453
454
  nextLine = rawLine;
454
455
  // Re-align to follow commonmark nesting rules
455
456
  if (this.options.pedantic) {
456
457
  nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');
458
+ nextLineWithoutTabs = nextLine;
459
+ }
460
+ else {
461
+ nextLineWithoutTabs = nextLine.replace(/\t/g, ' ');
457
462
  }
458
463
  // End list item if found code fences
459
464
  if (fencesBeginRegex.test(nextLine)) {
@@ -468,11 +473,11 @@
468
473
  break;
469
474
  }
470
475
  // Horizontal rule found
471
- if (hrRegex.test(src)) {
476
+ if (hrRegex.test(nextLine)) {
472
477
  break;
473
478
  }
474
- if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
475
- itemContents += '\n' + nextLine.slice(indent);
479
+ if (nextLineWithoutTabs.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
480
+ itemContents += '\n' + nextLineWithoutTabs.slice(indent);
476
481
  }
477
482
  else {
478
483
  // not enough indentation
@@ -480,7 +485,7 @@
480
485
  break;
481
486
  }
482
487
  // paragraph continuation unless last line was a different block level element
483
- if (line.search(/[^ ]/) >= 4) { // indented code block
488
+ if (line.replace(/\t/g, ' ').search(/[^ ]/) >= 4) { // indented code block
484
489
  break;
485
490
  }
486
491
  if (fencesBeginRegex.test(line)) {
@@ -499,7 +504,7 @@
499
504
  }
500
505
  raw += rawLine + '\n';
501
506
  src = src.substring(rawLine.length + 1);
502
- line = nextLine.slice(indent);
507
+ line = nextLineWithoutTabs.slice(indent);
503
508
  }
504
509
  }
505
510
  if (!list.loose) {
@@ -507,7 +512,7 @@
507
512
  if (endsWithBlankLine) {
508
513
  list.loose = true;
509
514
  }
510
- else if (/\n *\n *$/.test(raw)) {
515
+ else if (/\n[ \t]*\n[ \t]*$/.test(raw)) {
511
516
  endsWithBlankLine = true;
512
517
  }
513
518
  }
@@ -969,15 +974,15 @@
969
974
  /**
970
975
  * Block-Level Grammar
971
976
  */
972
- const newline = /^(?: *(?:\n|$))+/;
973
- const blockCode = /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/;
977
+ const newline = /^(?:[ \t]*(?:\n|$))+/;
978
+ const blockCode = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
974
979
  const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
975
980
  const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
976
981
  const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
977
982
  const bullet = /(?:[*+-]|\d{1,9}[.)])/;
978
983
  const lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/)
979
984
  .replace(/bull/g, bullet) // lists can interrupt
980
- .replace(/blockCode/g, / {4}/) // indented code blocks can interrupt
985
+ .replace(/blockCode/g, /(?: {4}| {0,3}\t)/) // indented code blocks can interrupt
981
986
  .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt
982
987
  .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt
983
988
  .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt
@@ -986,7 +991,7 @@
986
991
  const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
987
992
  const blockText = /^[^\n]+/;
988
993
  const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
989
- const def = edit(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/)
994
+ const def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/)
990
995
  .replace('label', _blockLabel)
991
996
  .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/)
992
997
  .getRegex();
@@ -1006,9 +1011,9 @@
1006
1011
  + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
1007
1012
  + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
1008
1013
  + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
1009
- + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
1010
- + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
1011
- + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
1014
+ + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (6)
1015
+ + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) open tag
1016
+ + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) closing tag
1012
1017
  + ')', 'i')
1013
1018
  .replace('comment', _comment)
1014
1019
  .replace('tag', _tag)
@@ -1055,7 +1060,7 @@
1055
1060
  .replace('hr', hr)
1056
1061
  .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1057
1062
  .replace('blockquote', ' {0,3}>')
1058
- .replace('code', ' {4}[^\\n]')
1063
+ .replace('code', '(?: {4}| {0,3}\t)[^\\n]')
1059
1064
  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1060
1065
  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1061
1066
  .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
@@ -1335,11 +1340,6 @@
1335
1340
  if (this.options.pedantic) {
1336
1341
  src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
1337
1342
  }
1338
- else {
1339
- src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
1340
- return leading + ' '.repeat(tabs.length);
1341
- });
1342
- }
1343
1343
  let token;
1344
1344
  let lastToken;
1345
1345
  let cutSrc;
@@ -2082,6 +2082,7 @@
2082
2082
 
2083
2083
  class _Hooks {
2084
2084
  options;
2085
+ block;
2085
2086
  constructor(options) {
2086
2087
  this.options = options || exports.defaults;
2087
2088
  }
@@ -2108,13 +2109,25 @@
2108
2109
  processAllTokens(tokens) {
2109
2110
  return tokens;
2110
2111
  }
2112
+ /**
2113
+ * Provide function to tokenize markdown
2114
+ */
2115
+ provideLexer() {
2116
+ return this.block ? _Lexer.lex : _Lexer.lexInline;
2117
+ }
2118
+ /**
2119
+ * Provide function to parse tokens
2120
+ */
2121
+ provideParser() {
2122
+ return this.block ? _Parser.parse : _Parser.parseInline;
2123
+ }
2111
2124
  }
2112
2125
 
2113
2126
  class Marked {
2114
2127
  defaults = _getDefaults();
2115
2128
  options = this.setOptions;
2116
- parse = this.parseMarkdown(_Lexer.lex, _Parser.parse);
2117
- parseInline = this.parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
2129
+ parse = this.parseMarkdown(true);
2130
+ parseInline = this.parseMarkdown(false);
2118
2131
  Parser = _Parser;
2119
2132
  Renderer = _Renderer;
2120
2133
  TextRenderer = _TextRenderer;
@@ -2287,8 +2300,8 @@
2287
2300
  if (!(prop in hooks)) {
2288
2301
  throw new Error(`hook '${prop}' does not exist`);
2289
2302
  }
2290
- if (prop === 'options') {
2291
- // ignore options property
2303
+ if (['options', 'block'].includes(prop)) {
2304
+ // ignore options and block properties
2292
2305
  continue;
2293
2306
  }
2294
2307
  const hooksProp = prop;
@@ -2346,7 +2359,7 @@
2346
2359
  parser(tokens, options) {
2347
2360
  return _Parser.parse(tokens, options ?? this.defaults);
2348
2361
  }
2349
- parseMarkdown(lexer, parser) {
2362
+ parseMarkdown(blockType) {
2350
2363
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2351
2364
  const parse = (src, options) => {
2352
2365
  const origOpt = { ...options };
@@ -2366,7 +2379,10 @@
2366
2379
  }
2367
2380
  if (opt.hooks) {
2368
2381
  opt.hooks.options = opt;
2382
+ opt.hooks.block = blockType;
2369
2383
  }
2384
+ const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);
2385
+ const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);
2370
2386
  if (opt.async) {
2371
2387
  return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
2372
2388
  .then(src => lexer(src, opt))