stream-markdown-parser 0.0.92 → 0.0.94

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/dist/index.js CHANGED
@@ -9347,7 +9347,7 @@ function applyContainers(md) {
9347
9347
  if (!jsonStr) argsStr = trimmedRest || void 0;
9348
9348
  }
9349
9349
  if (silent) return true;
9350
- const envFinal = !!s.env?.__markstreamFinal;
9350
+ const envFinal = !!s.env.__markstreamFinal;
9351
9351
  let nextLine = startLine + 1;
9352
9352
  let found = false;
9353
9353
  while (nextLine <= endLine) {
@@ -9363,7 +9363,7 @@ function applyContainers(md) {
9363
9363
  const tokenOpen = s.push("vmr_container_open", "div", 1);
9364
9364
  tokenOpen.attrSet("class", `vmr-container vmr-container-${name}`);
9365
9365
  tokenOpen.meta = {
9366
- ...tokenOpen.meta,
9366
+ ...tokenOpen.meta ?? {},
9367
9367
  unclosed: !found && !envFinal
9368
9368
  };
9369
9369
  if (argsStr) tokenOpen.attrSet("data-args", argsStr);
@@ -10392,7 +10392,7 @@ function applyFixHtmlInlineTokens(md, options = {}) {
10392
10392
  type: "html_block",
10393
10393
  loading: true,
10394
10394
  tag,
10395
- content: t.children[0].content + t.children[1].content
10395
+ content: String(t.children[0]?.content ?? "") + String(t.children[1]?.content ?? "")
10396
10396
  }];
10397
10397
  continue;
10398
10398
  } else if (t.children.length === 3 && t.children[0].type === "html_inline" && t.children[2].type === "html_inline") {
@@ -10465,7 +10465,7 @@ function looksLikeCode(line) {
10465
10465
  function applyFixIndentedCodeBlock(md, options = {}) {
10466
10466
  if (options.enabled === false) return;
10467
10467
  md.core.ruler.after("inline", "fix_indented_code_block", (state) => {
10468
- const tokens = state.tokens;
10468
+ const tokens = state.tokens ?? [];
10469
10469
  for (let i = 0; i < tokens.length; i++) {
10470
10470
  const token = tokens[i];
10471
10471
  if (token.type !== "code_block") continue;
@@ -10474,28 +10474,30 @@ function applyFixIndentedCodeBlock(md, options = {}) {
10474
10474
  const lines = content.split(/\r?\n/).filter((line) => line.trim().length > 0);
10475
10475
  if (lines.length === 1 && !looksLikeCode(lines[0] ?? "")) {
10476
10476
  const textContent = lines[0] ?? "";
10477
+ const level = token.level ?? 0;
10477
10478
  tokens.splice(i, 1, {
10478
10479
  type: "paragraph_open",
10479
10480
  tag: "p",
10480
10481
  nesting: 1,
10481
- level: token.level
10482
+ level
10482
10483
  }, {
10483
10484
  type: "inline",
10484
10485
  tag: "",
10485
10486
  nesting: 0,
10486
- level: token.level,
10487
+ level,
10487
10488
  content: textContent,
10488
10489
  children: [{
10489
10490
  type: "text",
10490
10491
  content: textContent,
10491
- level: token.level + 1
10492
+ level: level + 1,
10493
+ raw: textContent
10492
10494
  }],
10493
10495
  block: true
10494
10496
  }, {
10495
10497
  type: "paragraph_close",
10496
10498
  tag: "p",
10497
10499
  nesting: -1,
10498
- level: token.level
10500
+ level
10499
10501
  });
10500
10502
  i += 2;
10501
10503
  }
@@ -10722,7 +10724,7 @@ function firstIndexOfAny(input, chars) {
10722
10724
  return first;
10723
10725
  }
10724
10726
  function getHrefFromLinkOpen(token) {
10725
- const href = token?.attrs?.find((attr) => attr?.[0] === "href")?.[1];
10727
+ const href = token.attrs?.find((attr) => attr?.[0] === "href")?.[1];
10726
10728
  return typeof href === "string" ? href : "";
10727
10729
  }
10728
10730
  function setHrefOnLinkOpen(token, href) {
@@ -10963,7 +10965,7 @@ function fixLinkToken(tokens) {
10963
10965
  count += 1;
10964
10966
  }
10965
10967
  }
10966
- replacerTokens.push({
10968
+ const linkToken = {
10967
10969
  type: "link",
10968
10970
  loading: false,
10969
10971
  href,
@@ -10975,7 +10977,8 @@ function fixLinkToken(tokens) {
10975
10977
  raw: text$1
10976
10978
  }],
10977
10979
  raw: String(`[${text$1}](${href})`)
10978
- });
10980
+ };
10981
+ replacerTokens.push(linkToken);
10979
10982
  if (emphasisMatch) {
10980
10983
  const type = emphasisMatch[1].length;
10981
10984
  pushEmClose(replacerTokens, type);
@@ -11342,10 +11345,50 @@ function mergeBrokenStrongAroundMathInline(tokens) {
11342
11345
  continue;
11343
11346
  }
11344
11347
  }
11348
+ if (t0?.type === "strong_open" && t1?.type === "text" && t2?.type === "strong_close" && t3?.type === "strong_open" && t4?.type === "math_inline" && t5?.type === "strong_close") {
11349
+ const close = findTrailingTextStrongClose(tokens, i + 6);
11350
+ if (close) {
11351
+ out.push(t0);
11352
+ out.push(t1);
11353
+ out.push(t4);
11354
+ for (let j = i + 6; j < close.index; j++) out.push(tokens[j]);
11355
+ if (close.beforeClose) out.push({
11356
+ ...tokens[close.index],
11357
+ type: "text",
11358
+ content: close.beforeClose,
11359
+ raw: close.beforeClose
11360
+ });
11361
+ out.push(t5);
11362
+ if (close.afterClose) out.push({
11363
+ ...tokens[close.index],
11364
+ type: "text",
11365
+ content: close.afterClose,
11366
+ raw: close.afterClose
11367
+ });
11368
+ i = close.index;
11369
+ continue;
11370
+ }
11371
+ }
11345
11372
  out.push(t0);
11346
11373
  }
11347
11374
  return out;
11348
11375
  }
11376
+ function findTrailingTextStrongClose(tokens, startIndex) {
11377
+ for (let i = startIndex; i < tokens.length; i++) {
11378
+ const token = tokens[i];
11379
+ if (token?.type === "strong_open") return null;
11380
+ if (token?.type !== "text") continue;
11381
+ const content = String(token.content ?? "");
11382
+ const closeIdx = content.indexOf("**");
11383
+ if (closeIdx === -1) continue;
11384
+ return {
11385
+ index: i,
11386
+ beforeClose: content.slice(0, closeIdx),
11387
+ afterClose: content.slice(closeIdx + 2)
11388
+ };
11389
+ }
11390
+ return null;
11391
+ }
11349
11392
 
11350
11393
  //#endregion
11351
11394
  //#region src/plugins/fixTableTokens.ts
@@ -11353,7 +11396,7 @@ function applyFixTableTokens(md) {
11353
11396
  md.core.ruler.after("block", "fix_table_tokens", (state) => {
11354
11397
  const s = state;
11355
11398
  try {
11356
- const fixed = fixTableTokens(s.tokens ?? []);
11399
+ const fixed = fixTableTokens(s.tokens ?? [], !!s.env?.__markstreamFinal, s.src ?? "");
11357
11400
  if (Array.isArray(fixed)) s.tokens = fixed;
11358
11401
  } catch (e) {
11359
11402
  console.error("[applyFixTableTokens] failed to fix table tokens", e);
@@ -11459,10 +11502,7 @@ function getPipeRowCells(line, requireTrailingPipe) {
11459
11502
  if (requireTrailingPipe && !line.endsWith("|")) return null;
11460
11503
  const cells = line.slice(1).split("|");
11461
11504
  if (cells.at(-1) === "") cells.pop();
11462
- return cells.length > 0 && cells.every((cell) => cell.length > 0) ? cells : null;
11463
- }
11464
- function isSingleLineFallbackTable(line) {
11465
- return getPipeRowCells(line, false) !== null;
11505
+ return cells.length > 0 && cells.every((cell) => cell.trim().length > 0) ? cells : null;
11466
11506
  }
11467
11507
  function hasTrailingPipeHeaderRow(line) {
11468
11508
  return getPipeRowCells(line, true) !== null;
@@ -11476,6 +11516,16 @@ function isTableSeparatorRow(line) {
11476
11516
  if (cells.at(-1) === "") cells.pop();
11477
11517
  return cells.length > 0 && cells.every(isSeparatorCell);
11478
11518
  }
11519
+ function isPartialSeparatorTail(cell) {
11520
+ return /^(?:[::]-*|:?-+:?)?$/.test(cell.trim());
11521
+ }
11522
+ function isTableSeparatorRowWithPartialTail(line) {
11523
+ if (line === "") return true;
11524
+ if (!line.startsWith("|")) return false;
11525
+ const cells = line.slice(1).split("|");
11526
+ const tail = cells.at(-1) ?? "";
11527
+ return cells.slice(0, -1).every(isSeparatorCell) && isPartialSeparatorTail(tail);
11528
+ }
11479
11529
  function isTruncatedSeparatorRow(line) {
11480
11530
  return line === "|" || line === "|:";
11481
11531
  }
@@ -11483,7 +11533,7 @@ function hasTrailingPipeHeaderRowWithoutColon(line) {
11483
11533
  const cells = getPipeRowCells(line, true);
11484
11534
  return cells !== null && cells.every((cell) => !cell.includes(":"));
11485
11535
  }
11486
- function fixTableTokens(tokens) {
11536
+ function fixTableTokens(tokens, final = false, source = "") {
11487
11537
  const fixedTokens = [...tokens];
11488
11538
  if (tokens.length < 3) return fixedTokens;
11489
11539
  const i = tokens.length - 2;
@@ -11492,8 +11542,9 @@ function fixTableTokens(tokens) {
11492
11542
  const tcontent = String(token.content ?? "");
11493
11543
  const headerContent = tcontent.split("\n")[0] ?? "";
11494
11544
  const [headerLine = "", separatorLine = "", ...rest] = tcontent.split("\n");
11495
- if (!tcontent.includes("\n") && isSingleLineFallbackTable(tcontent)) {
11496
- const body = headerContent.slice(1).split("|").map((i$1) => i$1.trim()).filter(Boolean).flatMap((i$1) => createTh(i$1));
11545
+ const hasTrailingNewlineSeparatorStart = !final && !tcontent.includes("\n") && /\r?\n$/.test(source) && hasTrailingPipeHeaderRow(tcontent);
11546
+ if (!final && (tcontent.includes("\n") && rest.length === 0 && hasTrailingPipeHeaderRow(headerLine) && isTableSeparatorRowWithPartialTail(separatorLine) || hasTrailingNewlineSeparatorStart)) {
11547
+ const body = headerContent.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1));
11497
11548
  const insert = [
11498
11549
  ...createStart(),
11499
11550
  ...body,
@@ -12179,7 +12230,7 @@ function applyMath(md, mathOpts) {
12179
12230
  }
12180
12231
  foundAny = true;
12181
12232
  if (!silent) {
12182
- const before = src.slice(s.pos - s.pending.length, index);
12233
+ const before = src.slice(s.pos - (s.pending ?? "").length, index);
12183
12234
  let toPushBefore = src.slice(0, searchPos) ? src.slice(preMathPos, index) : before;
12184
12235
  const isStrongPrefix = countUnescapedStrong(toPushBefore) % 2 === 1;
12185
12236
  if (index !== s.pos && isStrongPrefix) toPushBefore = s.pending + src.slice(s.pos, index);
@@ -12503,7 +12554,8 @@ function parseEmphasisToken(tokens, startIndex, options) {
12503
12554
  let i = startIndex + 1;
12504
12555
  const innerTokens = [];
12505
12556
  while (i < tokens.length && tokens[i].type !== "em_close") {
12506
- emText += String(tokens[i].content ?? tokens[i]?.text ?? "");
12557
+ const tokenText = tokens[i];
12558
+ emText += String(tokens[i].content ?? tokenText.text ?? "");
12507
12559
  innerTokens.push(tokens[i]);
12508
12560
  i++;
12509
12561
  }
@@ -12712,8 +12764,8 @@ function normalizeStandardHtmlChildren(children) {
12712
12764
  if (!text$1) return;
12713
12765
  const last = normalized[normalized.length - 1];
12714
12766
  if (last?.type === "text") {
12715
- last.content = String(last.content ?? "") + text$1;
12716
- last.raw = String(last.raw ?? "") + text$1;
12767
+ last.content = `${last.content}${text$1}`;
12768
+ last.raw = `${last.raw}${text$1}`;
12717
12769
  return;
12718
12770
  }
12719
12771
  normalized.push({
@@ -12728,10 +12780,10 @@ function normalizeStandardHtmlChildren(children) {
12728
12780
  pushText(String(child.raw ?? ""));
12729
12781
  continue;
12730
12782
  }
12731
- if (Array.isArray(child.children)) {
12783
+ if ("children" in child && Array.isArray(child.children)) {
12732
12784
  normalized.push({
12733
12785
  ...child,
12734
- children: normalizeStandardHtmlChildren(child.children ?? [])
12786
+ children: normalizeStandardHtmlChildren(child.children)
12735
12787
  });
12736
12788
  continue;
12737
12789
  }
@@ -12901,7 +12953,7 @@ function parseImageToken(token, loading = false) {
12901
12953
  let attrs = token.attrs ?? [];
12902
12954
  let childWithAttrs = null;
12903
12955
  if ((!attrs || attrs.length === 0) && Array.isArray(token.children)) for (const child of token.children) {
12904
- const childAttrs = child?.attrs;
12956
+ const childAttrs = child.attrs;
12905
12957
  if (Array.isArray(childAttrs) && childAttrs.length > 0) {
12906
12958
  attrs = childAttrs;
12907
12959
  childWithAttrs = child;
@@ -13104,10 +13156,11 @@ function parseStrongToken(tokens, startIndex, raw, options) {
13104
13156
  innerTokens.push(tokens[i]);
13105
13157
  i++;
13106
13158
  }
13107
- children.push(...parseInlineTokens(innerTokens, resolveInnerRaw(raw, strongText), void 0, {
13159
+ const innerOptions = {
13108
13160
  ...options,
13109
13161
  __insideStrong: true
13110
- }));
13162
+ };
13163
+ children.push(...parseInlineTokens(innerTokens, resolveInnerRaw(raw, strongText), void 0, innerOptions));
13111
13164
  return {
13112
13165
  node: {
13113
13166
  type: "strong",
@@ -13429,6 +13482,7 @@ function recoverTrailingMarkdownLinkLabel(raw, href) {
13429
13482
  }
13430
13483
  function parseInlineTokens(tokens, raw, pPreToken, options) {
13431
13484
  if (!tokens || tokens.length === 0) return [];
13485
+ const internalOptions = options;
13432
13486
  const result = [];
13433
13487
  let currentTextNode = null;
13434
13488
  let i = 0;
@@ -13864,7 +13918,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
13864
13918
  return true;
13865
13919
  }
13866
13920
  function tryReparseCollapsedInlineText(rawContent) {
13867
- const md = options?.__markdownIt;
13921
+ const md = internalOptions?.__markdownIt;
13868
13922
  if (!md) return null;
13869
13923
  if (tokens.length <= 1 || !tokens.some((token) => token?.type === "math_inline")) return null;
13870
13924
  if (!INLINE_REPARSE_MARKER_RE.test(rawContent)) return null;
@@ -13901,9 +13955,28 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
13901
13955
  result.push(currentTextNode);
13902
13956
  }
13903
13957
  }
13958
+ function pushInlineTextContent(content, token) {
13959
+ if (!content) return;
13960
+ const parsed = parseInlineTokens([{
13961
+ ...token,
13962
+ type: "text",
13963
+ content,
13964
+ raw: content
13965
+ }], content, pPreToken, options);
13966
+ if (parsed.length === 1 && parsed[0]?.type === "text") {
13967
+ const text$1 = parsed[0];
13968
+ pushText(String(text$1.content ?? ""), String(text$1.raw ?? text$1.content ?? ""));
13969
+ return;
13970
+ }
13971
+ for (const node of parsed) pushNode(node);
13972
+ }
13904
13973
  function hasEscapedMarkup(token, escapedPrefix) {
13905
13974
  return String(token.markup ?? "").startsWith(escapedPrefix);
13906
13975
  }
13976
+ function isMarkdownLinkBeforeLinkifiedUrl(content) {
13977
+ if (!content.endsWith("](")) return false;
13978
+ return tokens[i + 1]?.type === "link_open" && tokens[i + 1]?.markup === "linkify" && tokens[i + 2]?.type === "text" && tokens[i + 3]?.type === "link_close" && tokens[i + 4]?.type === "text" && String(tokens[i + 4]?.content ?? "").startsWith(")");
13979
+ }
13907
13980
  function stripTrailingMidStateMarker(content, token) {
13908
13981
  let nextContent = content;
13909
13982
  const rawTokenContent = String(token.content ?? "");
@@ -14092,10 +14165,11 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
14092
14165
  pushText(String(token.content ?? ""), String(token.content ?? ""));
14093
14166
  i++;
14094
14167
  break;
14095
- default:
14096
- if (token.type === "link" && token.href != null && options?.validateLink && !options.validateLink(token.href)) {
14168
+ default: {
14169
+ const syntheticLink = token;
14170
+ if (token.type === "link" && syntheticLink.href != null && options?.validateLink && !options.validateLink(String(syntheticLink.href))) {
14097
14171
  resetCurrentTextNode();
14098
- const displayText = String(token.text ?? "");
14172
+ const displayText = String(syntheticLink.text ?? "");
14099
14173
  pushText(displayText, displayText);
14100
14174
  i++;
14101
14175
  } else if (recoverOuterImageLinkFromSyntheticLinkToken(token)) i++;
@@ -14106,6 +14180,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
14106
14180
  i++;
14107
14181
  }
14108
14182
  break;
14183
+ }
14109
14184
  }
14110
14185
  }
14111
14186
  function commitTextNode(content, token, preToken, nextToken) {
@@ -14176,7 +14251,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
14176
14251
  }
14177
14252
  if (handleInlineCodeContent(rawContent, token)) return;
14178
14253
  if (handleInlineImageContent(content)) return;
14179
- if (tokens[i + 1]?.type !== "link_open" && handleInlineLinkContent(content, token)) return;
14254
+ if ((tokens[i + 1]?.type !== "link_open" || isMarkdownLinkBeforeLinkifiedUrl(content)) && handleInlineLinkContent(content, token)) return;
14180
14255
  const reparsedNodes = tryReparseCollapsedInlineText(rawContent);
14181
14256
  if (reparsedNodes) {
14182
14257
  resetCurrentTextNode();
@@ -14381,7 +14456,8 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
14381
14456
  if (outerOpenToken?.type === "text" && String(outerOpenToken.content ?? "").endsWith("[") && hasEscapedMarkup(outerOpenToken, "\\[")) return false;
14382
14457
  const previous = result[result.length - 1];
14383
14458
  if (previous?.type !== "image" && previous?.type !== "link") return false;
14384
- const previousLink = previous?.type === "link" && Array.isArray(previous.children) && previous.children.length === 1 && previous.children[0]?.type === "image" ? result.pop() : null;
14459
+ const previousWithChildren = previous;
14460
+ const previousLink = previous?.type === "link" && Array.isArray(previousWithChildren.children) && previousWithChildren.children.length === 1 && previousWithChildren.children[0]?.type === "image" ? result.pop() : null;
14385
14461
  const imageNode = previousLink ? previousLink.children[0] : result.pop();
14386
14462
  if (!imageNode || imageNode.type !== "image") return false;
14387
14463
  const nextToken = tokens[i + 1];
@@ -14431,11 +14507,18 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
14431
14507
  const last = tokens[i + 4];
14432
14508
  let index = 4;
14433
14509
  let loading$1 = true;
14434
- if (last?.type === "text" && last.content === ")") {
14435
- index++;
14436
- loading$1 = false;
14437
- } else if (last?.type === "text" && last.content === ".") i++;
14438
- if (textNodeContent) pushText(textNodeContent, textNodeContent);
14510
+ if (last?.type === "text") {
14511
+ const lastContent = String(last.content ?? "");
14512
+ if (lastContent.startsWith(")")) {
14513
+ loading$1 = false;
14514
+ const trailing = lastContent.slice(1);
14515
+ if (trailing) {
14516
+ last.content = trailing;
14517
+ last.raw = trailing;
14518
+ } else index++;
14519
+ } else if (lastContent === ".") i++;
14520
+ }
14521
+ pushInlineTextContent(textNodeContent, _token);
14439
14522
  const hrefFromToken = String(textToken$1.content ?? "");
14440
14523
  if (options?.validateLink && !options.validateLink(hrefFromToken)) pushText(text$1, text$1);
14441
14524
  else pushParsed({
@@ -14458,7 +14541,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
14458
14541
  const loading = linkContentEnd === -1;
14459
14542
  let emphasisMatch = textNodeContent.match(/\*+$/);
14460
14543
  if (emphasisMatch) textNodeContent = textNodeContent.replace(/\*+$/, "");
14461
- if (textNodeContent) pushText(textNodeContent, textNodeContent);
14544
+ pushInlineTextContent(textNodeContent, _token);
14462
14545
  if (!emphasisMatch) emphasisMatch = text$1.match(/^\*+/);
14463
14546
  if (!requireClosingStrong && emphasisMatch) {
14464
14547
  const type = emphasisMatch[0].length;
@@ -14977,11 +15060,11 @@ function parseFootnote(tokens, index, options) {
14977
15060
  let j = index + 1;
14978
15061
  while (j < tokens.length && tokens[j].type !== "footnote_close") if (tokens[j].type === "paragraph_open") {
14979
15062
  const contentToken = tokens[j + 1];
14980
- const children = contentToken.children || [];
15063
+ const children = contentToken.children ? [...contentToken.children] : [];
14981
15064
  if (tokens[j + 2].type === "footnote_anchor") children.push(tokens[j + 2]);
14982
15065
  footnoteChildren.push({
14983
15066
  type: "paragraph",
14984
- children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, options),
15067
+ children: parseInlineTokens(children, String(contentToken.content ?? ""), void 0, options),
14985
15068
  raw: String(contentToken.content ?? "")
14986
15069
  });
14987
15070
  j += 3;
@@ -14998,7 +15081,7 @@ function parseFootnote(tokens, index, options) {
14998
15081
  //#region src/parser/node-parsers/heading-parser.ts
14999
15082
  function parseHeading(tokens, index, options) {
15000
15083
  const token = tokens[index];
15001
- const attrs = token?.attrs;
15084
+ const attrs = token.attrs;
15002
15085
  const attrsRecord = Array.isArray(attrs) && attrs.length ? Object.fromEntries(attrs.filter((pair) => Array.isArray(pair) && pair.length >= 1 && pair[0]).map(([name, value]) => [String(name), value == null || value === "" ? true : String(value)])) : void 0;
15003
15086
  const levelStr = String(token.tag?.substring(1) ?? "1");
15004
15087
  const headingLevel = Number.parseInt(levelStr, 10);
@@ -15393,7 +15476,7 @@ function parseBasicBlockToken(tokens, index, options) {
15393
15476
  const htmlBlockNode = parseHtmlBlock(token);
15394
15477
  const tagSets = htmlBlockNode.tag ? getHtmlTagSets(options?.customHtmlTags) : null;
15395
15478
  if (htmlBlockNode.tag && htmlBlockNode.loading && tagSets && !tagSets.allowedTagSet.has(htmlBlockNode.tag)) {
15396
- const content = String(token?.content ?? "").replace(/\n+$/, "");
15479
+ const content = String(token.content ?? "").replace(/\n+$/, "");
15397
15480
  return [{
15398
15481
  type: "paragraph",
15399
15482
  children: content ? [{
@@ -15410,7 +15493,7 @@ function parseBasicBlockToken(tokens, index, options) {
15410
15493
  const cursor = Number(options?.__customHtmlBlockCursor ?? 0);
15411
15494
  const mappedLineStart = Array.isArray(token.map) ? lineToIndex(source, Number(token.map?.[0] ?? 0)) : 0;
15412
15495
  const fromSource = findNextCustomHtmlBlockFromSource(source, tag, Math.max(clampNonNegative(cursor), clampNonNegative(mappedLineStart)));
15413
- if (fromSource) options.__customHtmlBlockCursor = fromSource.end;
15496
+ if (fromSource && options) options.__customHtmlBlockCursor = fromSource.end;
15414
15497
  const rawHtml = String(fromSource?.raw ?? htmlBlockNode.raw ?? "");
15415
15498
  const openEnd = findTagCloseIndexOutsideQuotes(rawHtml);
15416
15499
  const openTag = openEnd !== -1 ? rawHtml.slice(0, openEnd + 1) : rawHtml;
@@ -15507,6 +15590,9 @@ function parseParagraph(tokens, index, options) {
15507
15590
 
15508
15591
  //#endregion
15509
15592
  //#region src/parser/index.ts
15593
+ function getNodeFields(node) {
15594
+ return node;
15595
+ }
15510
15596
  function getCustomHtmlTagSet(options) {
15511
15597
  const custom = options?.customHtmlTags;
15512
15598
  if (!Array.isArray(custom) || custom.length === 0) return null;
@@ -15521,11 +15607,11 @@ function buildAllowedHtmlTagSet(options) {
15521
15607
  return set;
15522
15608
  }
15523
15609
  function stringifyInlineNodeRaw(node) {
15524
- const raw = node?.raw;
15610
+ const raw = node.raw;
15525
15611
  if (typeof raw === "string") return raw;
15526
- const content = node?.content;
15612
+ const content = getNodeFields(node).content;
15527
15613
  if (typeof content === "string") return content;
15528
- if (node?.type === "hardbreak") return "<br>";
15614
+ if (node.type === "hardbreak") return "<br>";
15529
15615
  return "";
15530
15616
  }
15531
15617
  function buildParagraphFromInlineChildren(children) {
@@ -15537,7 +15623,8 @@ function buildParagraphFromInlineChildren(children) {
15537
15623
  }
15538
15624
  function maybePromoteCustomNodeFromParagraph(node, options) {
15539
15625
  if (node.type !== "paragraph") return null;
15540
- const children = Array.isArray(node.children) ? node.children : [];
15626
+ const nodeChildren = getNodeFields(node).children;
15627
+ const children = Array.isArray(nodeChildren) ? nodeChildren : [];
15541
15628
  if (children.length === 0) return null;
15542
15629
  const customTagSet = getCustomHtmlTagSet(options);
15543
15630
  if (!customTagSet?.size) return null;
@@ -15546,7 +15633,7 @@ function maybePromoteCustomNodeFromParagraph(node, options) {
15546
15633
  const child = children[i];
15547
15634
  if (!customTagSet.has(String(child?.type ?? "").toLowerCase())) continue;
15548
15635
  const prefixChildren$1 = children.slice(0, i);
15549
- if (!String(child?.content ?? "").trim()) continue;
15636
+ if (!String(getNodeFields(child).content ?? "").trim()) continue;
15550
15637
  if (!prefixChildren$1.some((prefixChild) => prefixChild?.type === "hardbreak")) continue;
15551
15638
  customIndex = i;
15552
15639
  break;
@@ -15577,15 +15664,15 @@ function parseStandaloneHtmlDocument(markdown) {
15577
15664
  }];
15578
15665
  }
15579
15666
  function getMergeableNodeRaw(node) {
15580
- const raw = node?.raw;
15667
+ const raw = node.raw;
15581
15668
  if (typeof raw === "string") return raw;
15582
- const content = node?.content;
15669
+ const content = getNodeFields(node).content;
15583
15670
  if (typeof content === "string") return content;
15584
15671
  return "";
15585
15672
  }
15586
15673
  function isCloseOnlyHtmlBlockForTag(node, tag) {
15587
15674
  if (node.type !== "html_block" || !tag) return false;
15588
- const raw = String(node?.raw ?? node?.content ?? "");
15675
+ const raw = String(node.raw ?? node.content ?? "");
15589
15676
  return new RegExp(String.raw`^\s*<\s*\/\s*${escapeTagForRegExp(tag)}\s*>\s*$`, "i").test(raw);
15590
15677
  }
15591
15678
  function findNextHtmlBlockFromSource(source, tag, startIndex) {
@@ -15743,7 +15830,8 @@ function shouldStructureGenericHtmlBlockChildren(innerRaw, children) {
15743
15830
  if (children.some((child) => STRUCTURED_HTML_WRAPPER_BLOCK_TYPES.has(String(child?.type ?? "").toLowerCase()))) return true;
15744
15831
  if (children.some((child) => {
15745
15832
  if (child?.type !== "html_block") return false;
15746
- return Array.isArray(child?.children) && child.children.length > 0;
15833
+ const childFields = getNodeFields(child);
15834
+ return Array.isArray(childFields.children) && childFields.children.length > 0;
15747
15835
  })) return true;
15748
15836
  if (!hasStructuredHtmlWrapperMarkers(innerRaw)) return false;
15749
15837
  if (children.length > 1) return true;
@@ -15753,9 +15841,10 @@ function shouldStructureGenericHtmlBlockChildren(innerRaw, children) {
15753
15841
  function structureGenericHtmlBlockChildren(nodes, md, options, final) {
15754
15842
  return nodes.map((node) => {
15755
15843
  if (node?.type !== "html_block") return node;
15756
- const tag = String(node?.tag ?? "").toLowerCase();
15757
- if (!tag || tag === "details" || NON_STRUCTURING_HTML_TAGS.has(tag) || Array.isArray(node?.children)) return node;
15758
- const raw = String(node?.raw ?? node?.content ?? "");
15844
+ const fields = getNodeFields(node);
15845
+ const tag = String(fields.tag ?? "").toLowerCase();
15846
+ if (!tag || tag === "details" || NON_STRUCTURING_HTML_TAGS.has(tag) || Array.isArray(fields.children)) return node;
15847
+ const raw = String(node.raw ?? fields.content ?? "");
15759
15848
  if (!raw) return node;
15760
15849
  const openEnd = findTagCloseIndexOutsideQuotes(raw);
15761
15850
  if (openEnd === -1) return node;
@@ -15850,7 +15939,7 @@ function combineStructuredDetailsHtmlBlocks(nodes, source, md, options, final, s
15850
15939
  })() : openRaw;
15851
15940
  const [children] = combineStructuredDetailsHtmlBlocks(selfContained ? [] : closeIndex === -1 ? nodes.slice(i + 1) : nodes.slice(i + 1, closeIndex), source, md, options, final, openStart + openRaw.length);
15852
15941
  const prefixChildren = buildDetailsPrefixChildren(effectiveOpenRaw, md, buildDetailsChildParseOptions(options, final));
15853
- const closeRaw = closeIndex === -1 ? "</details>" : String(nodes[closeIndex]?.raw ?? getMergeableNodeRaw(nodes[closeIndex]) ?? "</details>");
15942
+ const closeRaw = closeIndex === -1 ? "</details>" : String(nodes[closeIndex].raw ?? getMergeableNodeRaw(nodes[closeIndex]) ?? "</details>");
15854
15943
  const explicitClose = selfContained || closeIndex !== -1 && exact?.closed === true;
15855
15944
  const trimmedCloseRaw = closeRaw.replace(/[\t\r\n ]+$/, "");
15856
15945
  const closeStart = explicitClose ? (() => {
@@ -15894,7 +15983,7 @@ function mergeSplitTopLevelHtmlBlocks(nodes, final, source) {
15894
15983
  if (nodePos !== -1) sourceHtmlCursor = nodePos + nodeRaw.length;
15895
15984
  continue;
15896
15985
  }
15897
- const tag = String(node?.tag ?? "").toLowerCase();
15986
+ const tag = String(node.tag ?? "").toLowerCase();
15898
15987
  if (!tag) continue;
15899
15988
  if (tag === "details") {
15900
15989
  if (nodePos !== -1) sourceHtmlCursor = nodePos + nodeRaw.length;
@@ -15903,11 +15992,11 @@ function mergeSplitTopLevelHtmlBlocks(nodes, final, source) {
15903
15992
  const exact = findNextHtmlBlockFromSource(source, tag, nodePos !== -1 ? nodePos : sourceHtmlCursor);
15904
15993
  if (!exact) continue;
15905
15994
  sourceHtmlCursor = exact.end;
15906
- const currentContent = String(node?.content ?? nodeRaw);
15907
- const currentRaw = String(node?.raw ?? currentContent);
15995
+ const currentContent = String(node.content ?? nodeRaw);
15996
+ const currentRaw = String(node.raw ?? currentContent);
15908
15997
  const nextContent = buildHtmlBlockContent(exact.raw, tag, exact.closed);
15909
15998
  const desiredLoading = !final && !exact.closed;
15910
- const needsExpansion = currentContent !== nextContent || currentRaw !== exact.raw || Boolean(node?.loading) !== desiredLoading;
15999
+ const needsExpansion = currentContent !== nextContent || currentRaw !== exact.raw || Boolean(node.loading) !== desiredLoading;
15911
16000
  const exactOpenEnd = findTagCloseIndexOutsideQuotes(exact.raw);
15912
16001
  const exactOpenTag = exactOpenEnd === -1 ? "" : exact.raw.slice(0, exactOpenEnd + 1);
15913
16002
  const exactAttrs = exactOpenTag ? parseTagAttrs(exactOpenTag) : [];
@@ -17359,9 +17448,8 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
17359
17448
  if (Array.isArray(options.plugin)) for (const p of options.plugin) {
17360
17449
  const pluginItem = p;
17361
17450
  if (Array.isArray(pluginItem)) {
17362
- const fn = pluginItem[0];
17363
- const opts = pluginItem[1];
17364
- if (typeof fn === "function") md.use(fn, opts);
17451
+ const [fn, ...params] = pluginItem;
17452
+ if (typeof fn === "function") md.use(fn, ...params);
17365
17453
  } else if (typeof pluginItem === "function") md.use(pluginItem);
17366
17454
  }
17367
17455
  if (Array.isArray(options.apply)) for (const fn of options.apply) try {
@@ -17371,9 +17459,8 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
17371
17459
  }
17372
17460
  if (_registeredMarkdownPlugins.length) {
17373
17461
  for (const p of _registeredMarkdownPlugins) if (Array.isArray(p)) {
17374
- const fn = p[0];
17375
- const opts = p[1];
17376
- if (typeof fn === "function") md.use(fn, opts);
17462
+ const [fn, ...params] = p;
17463
+ if (typeof fn === "function") md.use(fn, ...params);
17377
17464
  } else if (typeof p === "function") md.use(p);
17378
17465
  }
17379
17466
  md.use(sub_plugin);