@ai-react-markdown/engine 2.4.3 → 2.4.5

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
@@ -176,6 +176,11 @@ var defaultUrlTransform = (value) => {
176
176
  import { htmlBlockNames } from "micromark-util-html-tag-name";
177
177
  import { normalizeIdentifier } from "micromark-util-normalize-identifier";
178
178
  var TYPE6_NAMES = new Set(htmlBlockNames);
179
+ var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
180
+ var TYPE1_NAMES = /* @__PURE__ */ new Set(["script", "pre", "style", "textarea"]);
181
+ var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
182
+ var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
183
+ var TYPE7_LINE_RE = /^<(\/?)([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r][^>]*|\/)?>[ \t\r]*$/;
179
184
  var VOID_TAGS = /* @__PURE__ */ new Set([
180
185
  "area",
181
186
  "base",
@@ -314,7 +319,11 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
314
319
  htmlFlowSinceBlank: false,
315
320
  htmlSeamPending: false,
316
321
  phasePoisonedAt: Infinity,
317
- pendingTruncatedTags: []
322
+ pendingTruncatedTags: [],
323
+ pendingTruncatedCloses: [],
324
+ tagAcrossLines: false,
325
+ tagAcrossLinesIndent: 0,
326
+ htmlFlowReal: false
318
327
  };
319
328
  }
320
329
  function isPlausibleLinkDefRest(rest) {
@@ -611,6 +620,8 @@ function processConfirmedLine(cp, ln, text) {
611
620
  for (const tag of cp.pendingTruncatedTags) applyTag(tag, true);
612
621
  cp.pendingTruncatedTags = [];
613
622
  }
623
+ cp.pendingTruncatedCloses = [];
624
+ cp.tagAcrossLines = false;
614
625
  cp.blankRun += 1;
615
626
  cp.lastBlankStart = ln.start;
616
627
  cp.candidates.push({
@@ -624,6 +635,7 @@ function processConfirmedLine(cp, ln, text) {
624
635
  cp.paragraphHasUnpairedRun = false;
625
636
  cp.openBracket = null;
626
637
  cp.htmlFlowSinceBlank = false;
638
+ cp.htmlFlowReal = false;
627
639
  cp.prevLineBlank = true;
628
640
  cp.prevLineWasText = false;
629
641
  cp.prevLineWasValidDef = false;
@@ -639,6 +651,16 @@ function processConfirmedLine(cp, ln, text) {
639
651
  if (tagStart) {
640
652
  cp.htmlFlowSinceBlank = true;
641
653
  if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
654
+ if (!cp.htmlFlowReal) {
655
+ const t = mdTrimStart(ln.text);
656
+ const t6 = TYPE6_START_RE.exec(t);
657
+ const t7 = TYPE7_LINE_RE.exec(t);
658
+ if (t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase()) || TYPE1_START_RE.test(t) || // Type 7 cannot interrupt a paragraph, and excludes the raw-text
659
+ // names (those are type 1 as start tags, paragraph as end tags).
660
+ t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7[2].toLowerCase())) {
661
+ cp.htmlFlowReal = true;
662
+ }
663
+ }
642
664
  }
643
665
  const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
644
666
  const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
@@ -779,7 +801,21 @@ ${cont(scanText)}` };
779
801
  for (const [from, to] of rawSpans) {
780
802
  tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
781
803
  }
782
- {
804
+ let skipTagScan = false;
805
+ if (cp.tagAcrossLines) {
806
+ if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
807
+ const gt = ln.text.indexOf(">");
808
+ if (gt === -1) {
809
+ skipTagScan = true;
810
+ } else {
811
+ if (/["']/.test(ln.text.slice(0, gt))) poisonRawDivergence();
812
+ for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
813
+ cp.pendingTruncatedCloses = [];
814
+ cp.tagAcrossLines = false;
815
+ tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
816
+ }
817
+ }
818
+ if (!skipTagScan) {
783
819
  TAG_OR_COMMENT_RE.lastIndex = 0;
784
820
  let m;
785
821
  let lastCommentOpenerIdx = -1;
@@ -809,6 +845,7 @@ ${cont(scanText)}` };
809
845
  if (cp.commentOpen) continue;
810
846
  const closing = m[1] === "/";
811
847
  const tag = m[2].toLowerCase();
848
+ if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
812
849
  const selfClosing = m[3] !== void 0 && /\/\s*$/.test(m[3]);
813
850
  if (VOID_TAGS.has(tag) || selfClosing) continue;
814
851
  applyTag(tag, closing);
@@ -829,6 +866,7 @@ ${cont(scanText)}` };
829
866
  if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
830
867
  const closing = mr[1] === "/";
831
868
  const tag = mr[2].toLowerCase();
869
+ if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
832
870
  const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
833
871
  if (VOID_TAGS.has(tag) || selfClosing) continue;
834
872
  applyTag(tag, closing);
@@ -844,7 +882,14 @@ ${cont(scanText)}` };
844
882
  if (m2) {
845
883
  const closing = m2[1] === "/";
846
884
  const tag = m2[2].toLowerCase();
847
- if (!VOID_TAGS.has(tag)) {
885
+ if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
886
+ if (cp.htmlFlowReal) {
887
+ cp.tagAcrossLines = true;
888
+ cp.tagAcrossLinesIndent = ln.indent;
889
+ }
890
+ if (closing) {
891
+ if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
892
+ } else if (!VOID_TAGS.has(tag)) {
848
893
  applyTag(tag, closing);
849
894
  const rawLastLt = ln.text.lastIndexOf("<");
850
895
  const rawTruncated = rawLastLt !== -1 && !ln.text.includes(">", rawLastLt);
@@ -1387,6 +1432,9 @@ function countTrailingNewlines(value) {
1387
1432
  function countNewlines(text, end = text.length) {
1388
1433
  let count = 0;
1389
1434
  for (let i = text.indexOf("\n"); i !== -1 && i < end; i = text.indexOf("\n", i + 1)) count += 1;
1435
+ for (let i = text.indexOf("\r"); i !== -1 && i < end; i = text.indexOf("\r", i + 1)) {
1436
+ if (text.charCodeAt(i + 1) !== 10) count += 1;
1437
+ }
1390
1438
  return count;
1391
1439
  }
1392
1440
 
@@ -1506,7 +1554,7 @@ function normalizeId(s) {
1506
1554
  return normalizeIdentifier3(s);
1507
1555
  }
1508
1556
  function normalizeForMatch(s) {
1509
- return normalizeIdentifier3(s.replace(/\\(.)/g, "$1"));
1557
+ return normalizeIdentifier3(s.replace(/\\([!-/:-@[-`{-~])/g, "$1"));
1510
1558
  }
1511
1559
 
1512
1560
  // src/components/collectDefLabels.ts
@@ -3932,10 +3980,16 @@ function lineIndentBefore(content, pos) {
3932
3980
  function findClosingBacktickRun(content, start, n) {
3933
3981
  let i = start;
3934
3982
  while (i < content.length) {
3935
- if (content[i] === "`") {
3983
+ const ch = content[i];
3984
+ if (ch === "`") {
3936
3985
  const runLen = getRepeatedMarkerLength(content, i, "`");
3937
3986
  if (runLen === n) return i;
3938
3987
  i += runLen;
3988
+ } else if (ch === "\n") {
3989
+ let j = i + 1;
3990
+ while (j < content.length && (content[j] === " " || content[j] === " " || content[j] === "\r")) j += 1;
3991
+ if (j >= content.length || content[j] === "\n") return -1;
3992
+ i += 1;
3939
3993
  } else {
3940
3994
  i += 1;
3941
3995
  }
@@ -4057,16 +4111,20 @@ function escapeCurrencyDollarSigns(text) {
4057
4111
  currentLineProcessed += segment;
4058
4112
  }
4059
4113
  let needEscape = true;
4060
- let restBeforeNextMatchOrEnd = "";
4061
- if (i < currencyMatches.length - 1) {
4062
- const nextMatch = currencyMatches[i + 1];
4063
- if (nextMatch.index - match.index > 1) {
4064
- restBeforeNextMatchOrEnd = text.substring(match.index + 1, nextMatch.index);
4114
+ const restStart = match.index + 1;
4115
+ const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
4116
+ let firstLineBeforeNextMatch = "";
4117
+ if (restEnd - restStart > 0) {
4118
+ let eol = restEnd;
4119
+ for (let k = restStart; k < restEnd; k++) {
4120
+ const c = text.charCodeAt(k);
4121
+ if (c === 10 || c === 13) {
4122
+ eol = k;
4123
+ break;
4124
+ }
4065
4125
  }
4066
- } else {
4067
- restBeforeNextMatchOrEnd = text.substring(match.index + 1);
4126
+ firstLineBeforeNextMatch = text.substring(restStart, eol);
4068
4127
  }
4069
- const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
4070
4128
  if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
4071
4129
  const wholeLineBeforeNextMatchWithoutCurrentDollar = currentLineProcessed + firstLineBeforeNextMatch;
4072
4130
  if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
@@ -4232,39 +4290,49 @@ function hasUnclosedTextCommand(text) {
4232
4290
  return false;
4233
4291
  }
4234
4292
  var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
4235
- function processSliceInstrumented(slice) {
4293
+ var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
4294
+ function processSliceInstrumented(slice, probe = true) {
4236
4295
  const segments = splitByProtectedRegions(slice);
4237
- let out = "";
4296
+ const parts = [];
4238
4297
  let quiescent = true;
4239
4298
  let truncatedAtSeamStart = false;
4240
4299
  for (let index = 0; index < segments.length; index++) {
4241
4300
  const segment = segments[index];
4242
4301
  if (segment.isCode) {
4243
- out += segment.text;
4302
+ parts.push(segment.text);
4244
4303
  continue;
4245
4304
  }
4246
4305
  let text = segment.text;
4247
4306
  text = escapeMhchemCommands(text);
4248
4307
  text = escapeCurrencyDollarSigns(text);
4249
4308
  text = convertLatexDelimiters(text);
4250
- if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
4309
+ if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
4251
4310
  text = escapeLatexPipes(text);
4252
- if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
4311
+ if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
4253
4312
  text = escapeLatexPipesInUnclosed(text);
4254
- if (hasUnclosedTextCommand(text)) quiescent = false;
4313
+ if (probe && hasUnclosedTextCommand(text)) quiescent = false;
4255
4314
  text = escapeTextUnderscores(text);
4256
4315
  text = convertSingleToDoubleDollar(text);
4257
- const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
4258
- if (unclosedDouble !== -1) {
4259
- quiescent = false;
4260
- if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
4261
- truncatedAtSeamStart = true;
4316
+ if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
4317
+ const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
4318
+ if (unclosedDouble !== -1) {
4319
+ quiescent = false;
4320
+ if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
4321
+ truncatedAtSeamStart = true;
4322
+ }
4262
4323
  }
4263
4324
  }
4264
4325
  text = truncateUnclosedLatexBlock(text);
4265
- out += text;
4326
+ parts.push(text);
4266
4327
  }
4267
- return { out, quiescent, truncatedAtSeamStart };
4328
+ return { out: parts.join(""), quiescent, truncatedAtSeamStart };
4329
+ }
4330
+ function isBlankRawLine(text, from, to) {
4331
+ for (let i = from; i < to; i++) {
4332
+ const c = text.charCodeAt(i);
4333
+ if (c !== 32 && c !== 9 && c !== 13) return false;
4334
+ }
4335
+ return true;
4268
4336
  }
4269
4337
  function findRawSafeCut(active) {
4270
4338
  const segments = splitByProtectedRegions(active);
@@ -4279,10 +4347,12 @@ function findRawSafeCut(active) {
4279
4347
  continue;
4280
4348
  }
4281
4349
  const text = segment.text;
4350
+ let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
4282
4351
  let lineStart = 0;
4283
4352
  while (lineStart <= text.length) {
4284
4353
  const nl = text.indexOf("\n", lineStart);
4285
4354
  const lineEnd = nl === -1 ? text.length : nl;
4355
+ if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
4286
4356
  for (let i = lineStart; i < lineEnd; i++) {
4287
4357
  const ch = text[i];
4288
4358
  if (ch === "`") backtickHazard = true;
@@ -4295,6 +4365,7 @@ function findRawSafeCut(active) {
4295
4365
  if (nl === -1) break;
4296
4366
  if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
4297
4367
  lineStart = nl + 1;
4368
+ atLineStart = true;
4298
4369
  }
4299
4370
  offset += text.length;
4300
4371
  }
@@ -4303,11 +4374,14 @@ function findRawSafeCut(active) {
4303
4374
  var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
4304
4375
  function createIncrementalLatexPreprocessor(options) {
4305
4376
  const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
4377
+ const onAttempt = options?.onAttempt;
4378
+ const backoff = options?.backoff ?? true;
4306
4379
  let prevSource = "";
4307
4380
  let prevOutput = "";
4308
4381
  let frozenSrcEnd = 0;
4309
4382
  let frozenOut = "";
4310
4383
  let triggered = false;
4384
+ let nextAttemptLen = 0;
4311
4385
  return function incrementalPreprocessLaTeX(source) {
4312
4386
  if (source === prevSource) return prevOutput;
4313
4387
  const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
@@ -4315,6 +4389,7 @@ function createIncrementalLatexPreprocessor(options) {
4315
4389
  frozenSrcEnd = 0;
4316
4390
  frozenOut = "";
4317
4391
  triggered = false;
4392
+ nextAttemptLen = 0;
4318
4393
  }
4319
4394
  if (!triggered) {
4320
4395
  const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
@@ -4326,18 +4401,26 @@ function createIncrementalLatexPreprocessor(options) {
4326
4401
  triggered = true;
4327
4402
  }
4328
4403
  let active = source.slice(frozenSrcEnd);
4329
- if (active.length > freezeThreshold) {
4404
+ if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
4405
+ const activeLength = active.length;
4406
+ let advanced = false;
4407
+ let frozenBytes = 0;
4408
+ const freeze = (cut2, slice) => {
4409
+ frozenOut += slice.out;
4410
+ frozenSrcEnd += cut2;
4411
+ active = source.slice(frozenSrcEnd);
4412
+ advanced = true;
4413
+ frozenBytes = cut2;
4414
+ };
4330
4415
  const cut = findRawSafeCut(active);
4331
4416
  if (cut > 0) {
4332
4417
  const candidate = processSliceInstrumented(active.slice(0, cut));
4333
- if (candidate.quiescent) {
4334
- frozenOut += candidate.out;
4335
- frozenSrcEnd += cut;
4336
- active = source.slice(frozenSrcEnd);
4337
- }
4418
+ if (candidate.quiescent) freeze(cut, candidate);
4338
4419
  }
4420
+ nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
4421
+ onAttempt?.({ activeLength, frozenBytes });
4339
4422
  }
4340
- const tail = processSliceInstrumented(active);
4423
+ const tail = processSliceInstrumented(active, false);
4341
4424
  const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
4342
4425
  const out = head + tail.out;
4343
4426
  prevSource = source;