@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.js CHANGED
@@ -289,9 +289,9 @@ function inlineResourceEnd(text, openIdx) {
289
289
  }
290
290
  return -1;
291
291
  }
292
- function collectRefLine(cp, lnStart, lnEnd, scanText, inRawText, isBlockStart) {
293
- const defShaped = inRawText ? null : DEF_RE.exec(scanText);
294
- const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(scanText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
292
+ function collectRefLine(cp, lnStart, lnEnd, scanText, rawText, inRawText, isBlockStart) {
293
+ const defShaped = inRawText ? null : DEF_RE.exec(rawText);
294
+ const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(rawText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
295
295
  const defLineStart = isBlockStart || !cp.prevLineWasText || cp.prevLineWasValidDef;
296
296
  const validDef = def !== null && defLineStart;
297
297
  if (validDef) {
@@ -509,12 +509,15 @@ var rawTextElement = (t) => t.kind === "rawText" ? t.element : t.kind === "scrip
509
509
  var VOID_TAGS = /* @__PURE__ */ new Set([
510
510
  "area",
511
511
  "base",
512
+ "basefont",
513
+ "bgsound",
512
514
  "br",
513
515
  "col",
514
516
  "embed",
515
517
  "hr",
516
518
  "img",
517
519
  "input",
520
+ "keygen",
518
521
  "link",
519
522
  "meta",
520
523
  "param",
@@ -529,7 +532,6 @@ var THEMATIC_BREAK_RE = /^(?:(?:-[ \t]*){3,}|(?:\*[ \t]*){3,}|(?:_[ \t]*){3,})$/
529
532
  var BARE_MARKER_RE = /^(?:[-*+]|\d{1,9}[.)])[ \t]*$/;
530
533
  var SETEXT_LEFTOVER_RE = /^(?:=+|--)[ \t]*$/;
531
534
  var DEF_LIST_DD_RE = /^ {0,3}:[ \t]/;
532
- var CLOSE_TAG_ONLY_RE = /^[ \t]*<\/[A-Za-z][A-Za-z0-9-]*[ \t]*>[ \t\r]*$/;
533
535
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
534
536
  var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
535
537
  var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
@@ -766,6 +768,19 @@ function floatingResidue(text, commentOpenAtStart) {
766
768
  if (!open) out += text.slice(last);
767
769
  return out;
768
770
  }
771
+ var RAW_CONSTRUCT_START_RE = /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/;
772
+ var sealResumableAbove = (cp) => cp.defBlockMaybeOpen || cp.fnDefResumable || cp.containerMaybeOpen;
773
+ function sealReleaseDerived(cp, ln, isBlockStart) {
774
+ if (sealResumableAbove(cp) && !(isBlockStart && ln.indent <= 3)) return false;
775
+ if (cp.prevLineOpenContent) return false;
776
+ if (cp.tableMaybeOpen) return false;
777
+ const head = mdTrimStart(ln.text);
778
+ if (RAW_CONSTRUCT_START_RE.test(head) || TYPE1_START_RE.test(head) || isType7Line(head)) return false;
779
+ const t6 = TYPE6_START_RE.exec(head);
780
+ if (t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase())) return false;
781
+ if (DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text)) return false;
782
+ return true;
783
+ }
769
784
  function processConfirmedLine(cp, ln, text) {
770
785
  const newest = cp.candidates[cp.candidates.length - 1];
771
786
  if (newest && newest.defListSettled === null) {
@@ -773,16 +788,19 @@ function processConfirmedLine(cp, ln, text) {
773
788
  }
774
789
  const isBlockStart = cp.prevLineBlank;
775
790
  if (cp.p5SealPending && !ln.blank && cp.mdBlock.kind !== "html" && !(cp.p5Tok.kind === "comment" || cp.p5Tok.kind === "bogus")) {
776
- const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text) || cp.defBlockMaybeOpen || cp.fnDefResumable && ln.indent >= 4;
777
- const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
778
- const closeTagOnly = CLOSE_TAG_ONLY_RE.test(ln.text);
779
- if (!defShapedLine && !commentOnly && !closeTagOnly) {
791
+ if (sealReleaseDerived(cp, ln, isBlockStart)) {
780
792
  cp.p5SealPending = false;
793
+ if (false) {
794
+ console.error(
795
+ `[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))}).`
796
+ );
797
+ }
781
798
  }
782
799
  }
783
800
  const possiblyInsideForeign = () => FOREIGN_ROOT_NAMES.some((name) => (cp.tagBalance.get(name) ?? 0) > 0);
784
801
  const honoursSelfClosing = (tag) => tag === "svg" || tag === "math";
785
802
  const foreignRawTextSwitchUnknowable = () => possiblyInsideForeign();
803
+ let discardedEndTag = false;
786
804
  const applyTag = (tag, closing) => {
787
805
  if (inRawTextTok(cp.p5Tok)) {
788
806
  if (cp.p5Tok.kind === "script" && cp.p5Tok.escaped && !closing && tag === "script") {
@@ -815,7 +833,10 @@ function processConfirmedLine(cp, ln, text) {
815
833
  }
816
834
  if (SCOPE_BARRIER_NAMES.has(cp.openStack[i])) break;
817
835
  }
818
- if (idx === -1) return;
836
+ if (idx === -1) {
837
+ discardedEndTag = true;
838
+ return;
839
+ }
819
840
  cp.openStack.splice(idx, 1);
820
841
  const count = cp.tagBalance.get(tag) ?? 0;
821
842
  if (count > 0) {
@@ -934,6 +955,9 @@ function processConfirmedLine(cp, ln, text) {
934
955
  cp.p5Tok = { kind: "data" };
935
956
  }
936
957
  }
958
+ if (cp.p5Tok.kind === "comment" && !mdHtml(cp.mdBlock, 2)) {
959
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
960
+ }
937
961
  if (cp.mdBlock.kind === "html" && cp.mdBlock.type >= 6) cp.mdBlock = { kind: "none" };
938
962
  cp.blankRun += 1;
939
963
  cp.lastBlankStart = ln.start;
@@ -977,7 +1001,7 @@ function processConfirmedLine(cp, ln, text) {
977
1001
  if (tagStart) {
978
1002
  const noRealBlockOpen = cp.mdBlock.kind !== "html";
979
1003
  const t1 = noRealBlockOpen ? TYPE1_START_RE.exec(mdTrimStart(ln.text)) : null;
980
- if (t1) cp.mdBlock = { kind: "html", type: 1, raw: RAW_TEXT_ELEMENTS.has(t1[1].toLowerCase()) };
1004
+ if (t1) cp.mdBlock = { kind: "html", type: 1, raw: RAW_TEXT_ELEMENTS.has(t1[1].toLowerCase()), indent: ln.indent };
981
1005
  if (cp.mdBlock.kind !== "html") {
982
1006
  const t = mdTrimStart(ln.text);
983
1007
  const t6 = TYPE6_START_RE.exec(t);
@@ -992,7 +1016,7 @@ function processConfirmedLine(cp, ln, text) {
992
1016
  // raw-text names (`</style>` alone is type 7, measured) and
993
1017
  // quoted-`>` attribute values.
994
1018
  !cp.prevLineOpenContent && type7Shaped) {
995
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: realT6 ? 6 : 7 };
1019
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: realT6 ? 6 : 7, indent: ln.indent };
996
1020
  } else if (cp.prevLineOpenContent && cp.tableMaybeOpen && type7Shaped) {
997
1021
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
998
1022
  }
@@ -1001,14 +1025,14 @@ function processConfirmedLine(cp, ln, text) {
1001
1025
  }
1002
1026
  }
1003
1027
  }
1004
- const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
1028
+ const rawFlowStart = ln.indent <= 3 && RAW_CONSTRUCT_START_RE.test(mdTrimStart(ln.text));
1005
1029
  const htmlOwnedLine = cp.mdBlock.kind === "html" || rawOpenAtLineStart || rawFlowStart;
1006
1030
  const maskingSuppressed = htmlOwnedLine || inRawTextTok(cp.p5Tok);
1007
1031
  const { masked, unpaired } = maskingSuppressed ? { masked: null, unpaired: false } : maskIntraLineCodeSpans(ln.text, cp.paragraphHasUnpairedRun);
1008
1032
  if (unpaired) cp.paragraphHasUnpairedRun = true;
1009
1033
  const scanText = masked ?? ln.text;
1010
1034
  const defRawToMicromark = cp.mdBlock.kind === "html" || rawOpenAtLineStart || inRawTextTok(cp.p5Tok);
1011
- const { validLinkDef } = collectRefLine(cp, ln.start, ln.end, scanText, defRawToMicromark, isBlockStart);
1035
+ const { validLinkDef } = collectRefLine(cp, ln.start, ln.end, scanText, ln.text, defRawToMicromark, isBlockStart);
1012
1036
  const rawSpans = [];
1013
1037
  let pos = 0;
1014
1038
  const poisonRawDivergence = () => {
@@ -1084,7 +1108,7 @@ function processConfirmedLine(cp, ln, text) {
1084
1108
  pos = bogus + 2;
1085
1109
  } else if (first === cd) {
1086
1110
  rawSpans.push([cd, cd + 9]);
1087
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 5 };
1111
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 5, indent: ln.indent };
1088
1112
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1089
1113
  if (!isMdBlank(scanText.slice(0, cd)) || ln.indent > 3) inlineRawOpenerIdx = cd;
1090
1114
  pos = cd + 9;
@@ -1096,14 +1120,14 @@ function processConfirmedLine(cp, ln, text) {
1096
1120
  continue;
1097
1121
  }
1098
1122
  rawSpans.push([pi, pi + 2]);
1099
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 3 };
1123
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 3, indent: ln.indent };
1100
1124
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1101
1125
  if (!isMdBlank(scanText.slice(0, pi)) || ln.indent > 3) inlineRawOpenerIdx = pi;
1102
1126
  pos = pi + 2;
1103
1127
  } else {
1104
1128
  rawSpans.push([decl, decl + 2]);
1105
1129
  if (ln.indent <= 3 && /^doctype/i.test(scanText.slice(decl + 2))) cp.phasePoisonedAt = 0;
1106
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 4 };
1130
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 4, indent: ln.indent };
1107
1131
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1108
1132
  if (!isMdBlank(scanText.slice(0, decl)) || ln.indent > 3) inlineRawOpenerIdx = decl;
1109
1133
  pos = decl + 2;
@@ -1162,7 +1186,7 @@ function processConfirmedLine(cp, ln, text) {
1162
1186
  if (next.startsWith(">") || next === "->") {
1163
1187
  continue;
1164
1188
  }
1165
- if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 2 };
1189
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 2, indent: ln.indent };
1166
1190
  if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "comment" };
1167
1191
  lastCommentOpenerIdx = m.index;
1168
1192
  continue;
@@ -1283,7 +1307,7 @@ function processConfirmedLine(cp, ln, text) {
1283
1307
  cursor = to;
1284
1308
  }
1285
1309
  masked2 += scanText.slice(cursor);
1286
- if (floatingResidue(masked2, bothCommentsOpenAtLineStart).length > 0) {
1310
+ if (floatingResidue(masked2, bothCommentsOpenAtLineStart).length > 0 || discardedEndTag) {
1287
1311
  cp.p5SealPending = true;
1288
1312
  }
1289
1313
  }
@@ -1322,7 +1346,30 @@ function processConfirmedLine(cp, ln, text) {
1322
1346
  cp.defBlockMaybeOpen = cp.defBlockMaybeOpen || DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
1323
1347
  if (FOOTNOTE_DEF_RE.test(ln.text)) cp.fnDefResumable = true;
1324
1348
  else if (isBlockStart && ln.indent <= 3) cp.fnDefResumable = false;
1349
+ const isBarrier = (name) => SCOPE_BARRIER_NAMES.has(name);
1350
+ const topLevelHtmlBlock = cp.mdBlock.kind === "html" && cp.mdBlock.indent === 0;
1351
+ const confirmedBarriers = cp.openStack.filter(isBarrier).length - cp.pendingTruncatedTags.filter(isBarrier).length;
1352
+ if (!topLevelHtmlBlock && confirmedBarriers > 0) {
1353
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1354
+ }
1355
+ const maskUnbacked = mdType1RawText(cp.mdBlock) && !inRawTextTok(cp.p5Tok);
1356
+ if (maskUnbacked) {
1357
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1358
+ if (tailCarriesRetroactive(ln.text) || /<template(?![a-z0-9-])/i.test(ln.text)) {
1359
+ cp.phasePoisonedAt = 0;
1360
+ }
1361
+ }
1325
1362
  }
1363
+ var SCANNER_NAME_LISTS = [
1364
+ ["type1", TYPE1_NAMES],
1365
+ ["rawText", RAW_TEXT_ELEMENTS],
1366
+ ["type6", TYPE6_NAMES],
1367
+ ["void", VOID_TAGS],
1368
+ ["documentStructure", DOCUMENT_STRUCTURE_NAMES],
1369
+ ["tablePart", TABLE_PART_NAMES],
1370
+ ["scopeBarrier", SCOPE_BARRIER_NAMES],
1371
+ ["foreignRoot", new Set(FOREIGN_ROOT_NAMES)]
1372
+ ];
1326
1373
 
1327
1374
  // src/components/incrementalParse/spliceParse.ts
1328
1375
  import { normalizeIdentifier as normalizeIdentifier2 } from "micromark-util-normalize-identifier";