@ai-react-markdown/engine 2.8.1 → 2.9.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/dist/index.cjs CHANGED
@@ -378,9 +378,9 @@ function inlineResourceEnd(text, openIdx) {
378
378
  }
379
379
  return -1;
380
380
  }
381
- function collectRefLine(cp, lnStart, lnEnd, scanText, inRawText, isBlockStart) {
382
- const defShaped = inRawText ? null : DEF_RE.exec(scanText);
383
- const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(scanText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
381
+ function collectRefLine(cp, lnStart, lnEnd, scanText, rawText, inRawText, isBlockStart) {
382
+ const defShaped = inRawText ? null : DEF_RE.exec(rawText);
383
+ const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(rawText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
384
384
  const defLineStart = isBlockStart || !cp.prevLineWasText || cp.prevLineWasValidDef;
385
385
  const validDef = def !== null && defLineStart;
386
386
  if (validDef) {
@@ -598,12 +598,15 @@ var rawTextElement = (t) => t.kind === "rawText" ? t.element : t.kind === "scrip
598
598
  var VOID_TAGS = /* @__PURE__ */ new Set([
599
599
  "area",
600
600
  "base",
601
+ "basefont",
602
+ "bgsound",
601
603
  "br",
602
604
  "col",
603
605
  "embed",
604
606
  "hr",
605
607
  "img",
606
608
  "input",
609
+ "keygen",
607
610
  "link",
608
611
  "meta",
609
612
  "param",
@@ -618,7 +621,6 @@ var THEMATIC_BREAK_RE = /^(?:(?:-[ \t]*){3,}|(?:\*[ \t]*){3,}|(?:_[ \t]*){3,})$/
618
621
  var BARE_MARKER_RE = /^(?:[-*+]|\d{1,9}[.)])[ \t]*$/;
619
622
  var SETEXT_LEFTOVER_RE = /^(?:=+|--)[ \t]*$/;
620
623
  var DEF_LIST_DD_RE = /^ {0,3}:[ \t]/;
621
- var CLOSE_TAG_ONLY_RE = /^[ \t]*<\/[A-Za-z][A-Za-z0-9-]*[ \t]*>[ \t\r]*$/;
622
624
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
623
625
  var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
624
626
  var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
@@ -855,6 +857,19 @@ function floatingResidue(text, commentOpenAtStart) {
855
857
  if (!open) out += text.slice(last);
856
858
  return out;
857
859
  }
860
+ var RAW_CONSTRUCT_START_RE = /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/;
861
+ var sealResumableAbove = (cp) => cp.defBlockMaybeOpen || cp.fnDefResumable || cp.containerMaybeOpen;
862
+ function sealReleaseDerived(cp, ln, isBlockStart) {
863
+ if (sealResumableAbove(cp) && !(isBlockStart && ln.indent <= 3)) return false;
864
+ if (cp.prevLineOpenContent) return false;
865
+ if (cp.tableMaybeOpen) return false;
866
+ const head = mdTrimStart(ln.text);
867
+ if (RAW_CONSTRUCT_START_RE.test(head) || TYPE1_START_RE.test(head) || isType7Line(head)) return false;
868
+ const t6 = TYPE6_START_RE.exec(head);
869
+ if (t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase())) return false;
870
+ if (DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text)) return false;
871
+ return true;
872
+ }
858
873
  function processConfirmedLine(cp, ln, text) {
859
874
  const newest = cp.candidates[cp.candidates.length - 1];
860
875
  if (newest && newest.defListSettled === null) {
@@ -862,16 +877,19 @@ function processConfirmedLine(cp, ln, text) {
862
877
  }
863
878
  const isBlockStart = cp.prevLineBlank;
864
879
  if (cp.p5SealPending && !ln.blank && cp.mdBlock.kind !== "html" && !(cp.p5Tok.kind === "comment" || cp.p5Tok.kind === "bogus")) {
865
- const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text) || cp.defBlockMaybeOpen || cp.fnDefResumable && ln.indent >= 4;
866
- const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
867
- const closeTagOnly = CLOSE_TAG_ONLY_RE.test(ln.text);
868
- if (!defShapedLine && !commentOnly && !closeTagOnly) {
880
+ if (sealReleaseDerived(cp, ln, isBlockStart)) {
869
881
  cp.p5SealPending = false;
882
+ if (false) {
883
+ console.error(
884
+ `[ai-react-markdown] seal-release containment broken at offset ${ln.start}: the derived predicate released a line the retired enumeration withheld (${JSON.stringify(ln.text.slice(0, 80))}).`
885
+ );
886
+ }
870
887
  }
871
888
  }
872
889
  const possiblyInsideForeign = () => FOREIGN_ROOT_NAMES.some((name) => (cp.tagBalance.get(name) ?? 0) > 0);
873
890
  const honoursSelfClosing = (tag) => tag === "svg" || tag === "math";
874
891
  const foreignRawTextSwitchUnknowable = () => possiblyInsideForeign();
892
+ let discardedEndTag = false;
875
893
  const applyTag = (tag, closing) => {
876
894
  if (inRawTextTok(cp.p5Tok)) {
877
895
  if (cp.p5Tok.kind === "script" && cp.p5Tok.escaped && !closing && tag === "script") {
@@ -904,7 +922,10 @@ function processConfirmedLine(cp, ln, text) {
904
922
  }
905
923
  if (SCOPE_BARRIER_NAMES.has(cp.openStack[i])) break;
906
924
  }
907
- if (idx === -1) return;
925
+ if (idx === -1) {
926
+ discardedEndTag = true;
927
+ return;
928
+ }
908
929
  cp.openStack.splice(idx, 1);
909
930
  const count = cp.tagBalance.get(tag) ?? 0;
910
931
  if (count > 0) {
@@ -1023,6 +1044,9 @@ function processConfirmedLine(cp, ln, text) {
1023
1044
  cp.p5Tok = { kind: "data" };
1024
1045
  }
1025
1046
  }
1047
+ if (cp.p5Tok.kind === "comment" && !mdHtml(cp.mdBlock, 2)) {
1048
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1049
+ }
1026
1050
  if (cp.mdBlock.kind === "html" && cp.mdBlock.type >= 6) cp.mdBlock = { kind: "none" };
1027
1051
  cp.blankRun += 1;
1028
1052
  cp.lastBlankStart = ln.start;
@@ -1066,7 +1090,7 @@ function processConfirmedLine(cp, ln, text) {
1066
1090
  if (tagStart) {
1067
1091
  const noRealBlockOpen = cp.mdBlock.kind !== "html";
1068
1092
  const t1 = noRealBlockOpen ? TYPE1_START_RE.exec(mdTrimStart(ln.text)) : null;
1069
- if (t1) cp.mdBlock = { kind: "html", type: 1, raw: RAW_TEXT_ELEMENTS.has(t1[1].toLowerCase()) };
1093
+ if (t1) cp.mdBlock = { kind: "html", type: 1, raw: RAW_TEXT_ELEMENTS.has(t1[1].toLowerCase()), indent: ln.indent };
1070
1094
  if (cp.mdBlock.kind !== "html") {
1071
1095
  const t = mdTrimStart(ln.text);
1072
1096
  const t6 = TYPE6_START_RE.exec(t);
@@ -1081,7 +1105,7 @@ function processConfirmedLine(cp, ln, text) {
1081
1105
  // raw-text names (`</style>` alone is type 7, measured) and
1082
1106
  // quoted-`>` attribute values.
1083
1107
  !cp.prevLineOpenContent && type7Shaped) {
1084
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: realT6 ? 6 : 7 };
1108
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: realT6 ? 6 : 7, indent: ln.indent };
1085
1109
  } else if (cp.prevLineOpenContent && cp.tableMaybeOpen && type7Shaped) {
1086
1110
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1087
1111
  }
@@ -1090,14 +1114,14 @@ function processConfirmedLine(cp, ln, text) {
1090
1114
  }
1091
1115
  }
1092
1116
  }
1093
- const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
1117
+ const rawFlowStart = ln.indent <= 3 && RAW_CONSTRUCT_START_RE.test(mdTrimStart(ln.text));
1094
1118
  const htmlOwnedLine = cp.mdBlock.kind === "html" || rawOpenAtLineStart || rawFlowStart;
1095
1119
  const maskingSuppressed = htmlOwnedLine || inRawTextTok(cp.p5Tok);
1096
1120
  const { masked, unpaired } = maskingSuppressed ? { masked: null, unpaired: false } : maskIntraLineCodeSpans(ln.text, cp.paragraphHasUnpairedRun);
1097
1121
  if (unpaired) cp.paragraphHasUnpairedRun = true;
1098
1122
  const scanText = masked ?? ln.text;
1099
1123
  const defRawToMicromark = cp.mdBlock.kind === "html" || rawOpenAtLineStart || inRawTextTok(cp.p5Tok);
1100
- const { validLinkDef } = collectRefLine(cp, ln.start, ln.end, scanText, defRawToMicromark, isBlockStart);
1124
+ const { validLinkDef } = collectRefLine(cp, ln.start, ln.end, scanText, ln.text, defRawToMicromark, isBlockStart);
1101
1125
  const rawSpans = [];
1102
1126
  let pos = 0;
1103
1127
  const poisonRawDivergence = () => {
@@ -1173,7 +1197,7 @@ function processConfirmedLine(cp, ln, text) {
1173
1197
  pos = bogus + 2;
1174
1198
  } else if (first === cd) {
1175
1199
  rawSpans.push([cd, cd + 9]);
1176
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 5 };
1200
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 5, indent: ln.indent };
1177
1201
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1178
1202
  if (!isMdBlank(scanText.slice(0, cd)) || ln.indent > 3) inlineRawOpenerIdx = cd;
1179
1203
  pos = cd + 9;
@@ -1185,14 +1209,14 @@ function processConfirmedLine(cp, ln, text) {
1185
1209
  continue;
1186
1210
  }
1187
1211
  rawSpans.push([pi, pi + 2]);
1188
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 3 };
1212
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 3, indent: ln.indent };
1189
1213
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1190
1214
  if (!isMdBlank(scanText.slice(0, pi)) || ln.indent > 3) inlineRawOpenerIdx = pi;
1191
1215
  pos = pi + 2;
1192
1216
  } else {
1193
1217
  rawSpans.push([decl, decl + 2]);
1194
1218
  if (ln.indent <= 3 && /^doctype/i.test(scanText.slice(decl + 2))) cp.phasePoisonedAt = 0;
1195
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 4 };
1219
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 4, indent: ln.indent };
1196
1220
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1197
1221
  if (!isMdBlank(scanText.slice(0, decl)) || ln.indent > 3) inlineRawOpenerIdx = decl;
1198
1222
  pos = decl + 2;
@@ -1251,7 +1275,7 @@ function processConfirmedLine(cp, ln, text) {
1251
1275
  if (next.startsWith(">") || next === "->") {
1252
1276
  continue;
1253
1277
  }
1254
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 2 };
1278
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 2, indent: ln.indent };
1255
1279
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "comment" };
1256
1280
  lastCommentOpenerIdx = m.index;
1257
1281
  continue;
@@ -1372,7 +1396,7 @@ function processConfirmedLine(cp, ln, text) {
1372
1396
  cursor = to;
1373
1397
  }
1374
1398
  masked2 += scanText.slice(cursor);
1375
- if (floatingResidue(masked2, bothCommentsOpenAtLineStart).length > 0) {
1399
+ if (floatingResidue(masked2, bothCommentsOpenAtLineStart).length > 0 || discardedEndTag) {
1376
1400
  cp.p5SealPending = true;
1377
1401
  }
1378
1402
  }
@@ -1411,7 +1435,30 @@ function processConfirmedLine(cp, ln, text) {
1411
1435
  cp.defBlockMaybeOpen = cp.defBlockMaybeOpen || DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
1412
1436
  if (FOOTNOTE_DEF_RE.test(ln.text)) cp.fnDefResumable = true;
1413
1437
  else if (isBlockStart && ln.indent <= 3) cp.fnDefResumable = false;
1438
+ const isBarrier = (name) => SCOPE_BARRIER_NAMES.has(name);
1439
+ const topLevelHtmlBlock = cp.mdBlock.kind === "html" && cp.mdBlock.indent === 0;
1440
+ const confirmedBarriers = cp.openStack.filter(isBarrier).length - cp.pendingTruncatedTags.filter(isBarrier).length;
1441
+ if (!topLevelHtmlBlock && confirmedBarriers > 0) {
1442
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1443
+ }
1444
+ const maskUnbacked = mdType1RawText(cp.mdBlock) && !inRawTextTok(cp.p5Tok);
1445
+ if (maskUnbacked) {
1446
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1447
+ if (tailCarriesRetroactive(ln.text) || /<template(?![a-z0-9-])/i.test(ln.text)) {
1448
+ cp.phasePoisonedAt = 0;
1449
+ }
1450
+ }
1414
1451
  }
1452
+ var SCANNER_NAME_LISTS = [
1453
+ ["type1", TYPE1_NAMES],
1454
+ ["rawText", RAW_TEXT_ELEMENTS],
1455
+ ["type6", TYPE6_NAMES],
1456
+ ["void", VOID_TAGS],
1457
+ ["documentStructure", DOCUMENT_STRUCTURE_NAMES],
1458
+ ["tablePart", TABLE_PART_NAMES],
1459
+ ["scopeBarrier", SCOPE_BARRIER_NAMES],
1460
+ ["foreignRoot", new Set(FOREIGN_ROOT_NAMES)]
1461
+ ];
1415
1462
 
1416
1463
  // src/components/incrementalParse/spliceParse.ts
1417
1464
  var import_micromark_util_normalize_identifier2 = require("micromark-util-normalize-identifier");