@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.dev.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
@@ -3944,10 +3992,16 @@ function lineIndentBefore(content, pos) {
3944
3992
  function findClosingBacktickRun(content, start, n) {
3945
3993
  let i = start;
3946
3994
  while (i < content.length) {
3947
- if (content[i] === "`") {
3995
+ const ch = content[i];
3996
+ if (ch === "`") {
3948
3997
  const runLen = getRepeatedMarkerLength(content, i, "`");
3949
3998
  if (runLen === n) return i;
3950
3999
  i += runLen;
4000
+ } else if (ch === "\n") {
4001
+ let j = i + 1;
4002
+ while (j < content.length && (content[j] === " " || content[j] === " " || content[j] === "\r")) j += 1;
4003
+ if (j >= content.length || content[j] === "\n") return -1;
4004
+ i += 1;
3951
4005
  } else {
3952
4006
  i += 1;
3953
4007
  }
@@ -4069,16 +4123,20 @@ function escapeCurrencyDollarSigns(text) {
4069
4123
  currentLineProcessed += segment;
4070
4124
  }
4071
4125
  let needEscape = true;
4072
- let restBeforeNextMatchOrEnd = "";
4073
- if (i < currencyMatches.length - 1) {
4074
- const nextMatch = currencyMatches[i + 1];
4075
- if (nextMatch.index - match.index > 1) {
4076
- restBeforeNextMatchOrEnd = text.substring(match.index + 1, nextMatch.index);
4126
+ const restStart = match.index + 1;
4127
+ const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
4128
+ let firstLineBeforeNextMatch = "";
4129
+ if (restEnd - restStart > 0) {
4130
+ let eol = restEnd;
4131
+ for (let k = restStart; k < restEnd; k++) {
4132
+ const c = text.charCodeAt(k);
4133
+ if (c === 10 || c === 13) {
4134
+ eol = k;
4135
+ break;
4136
+ }
4077
4137
  }
4078
- } else {
4079
- restBeforeNextMatchOrEnd = text.substring(match.index + 1);
4138
+ firstLineBeforeNextMatch = text.substring(restStart, eol);
4080
4139
  }
4081
- const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
4082
4140
  if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
4083
4141
  const wholeLineBeforeNextMatchWithoutCurrentDollar = currentLineProcessed + firstLineBeforeNextMatch;
4084
4142
  if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
@@ -4244,39 +4302,49 @@ function hasUnclosedTextCommand(text) {
4244
4302
  return false;
4245
4303
  }
4246
4304
  var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
4247
- function processSliceInstrumented(slice) {
4305
+ var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
4306
+ function processSliceInstrumented(slice, probe = true) {
4248
4307
  const segments = splitByProtectedRegions(slice);
4249
- let out = "";
4308
+ const parts = [];
4250
4309
  let quiescent = true;
4251
4310
  let truncatedAtSeamStart = false;
4252
4311
  for (let index = 0; index < segments.length; index++) {
4253
4312
  const segment = segments[index];
4254
4313
  if (segment.isCode) {
4255
- out += segment.text;
4314
+ parts.push(segment.text);
4256
4315
  continue;
4257
4316
  }
4258
4317
  let text = segment.text;
4259
4318
  text = escapeMhchemCommands(text);
4260
4319
  text = escapeCurrencyDollarSigns(text);
4261
4320
  text = convertLatexDelimiters(text);
4262
- if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
4321
+ if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
4263
4322
  text = escapeLatexPipes(text);
4264
- if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
4323
+ if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
4265
4324
  text = escapeLatexPipesInUnclosed(text);
4266
- if (hasUnclosedTextCommand(text)) quiescent = false;
4325
+ if (probe && hasUnclosedTextCommand(text)) quiescent = false;
4267
4326
  text = escapeTextUnderscores(text);
4268
4327
  text = convertSingleToDoubleDollar(text);
4269
- const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
4270
- if (unclosedDouble !== -1) {
4271
- quiescent = false;
4272
- if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
4273
- truncatedAtSeamStart = true;
4328
+ if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
4329
+ const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
4330
+ if (unclosedDouble !== -1) {
4331
+ quiescent = false;
4332
+ if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
4333
+ truncatedAtSeamStart = true;
4334
+ }
4274
4335
  }
4275
4336
  }
4276
4337
  text = truncateUnclosedLatexBlock(text);
4277
- out += text;
4338
+ parts.push(text);
4278
4339
  }
4279
- return { out, quiescent, truncatedAtSeamStart };
4340
+ return { out: parts.join(""), quiescent, truncatedAtSeamStart };
4341
+ }
4342
+ function isBlankRawLine(text, from, to) {
4343
+ for (let i = from; i < to; i++) {
4344
+ const c = text.charCodeAt(i);
4345
+ if (c !== 32 && c !== 9 && c !== 13) return false;
4346
+ }
4347
+ return true;
4280
4348
  }
4281
4349
  function findRawSafeCut(active) {
4282
4350
  const segments = splitByProtectedRegions(active);
@@ -4291,10 +4359,12 @@ function findRawSafeCut(active) {
4291
4359
  continue;
4292
4360
  }
4293
4361
  const text = segment.text;
4362
+ let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
4294
4363
  let lineStart = 0;
4295
4364
  while (lineStart <= text.length) {
4296
4365
  const nl = text.indexOf("\n", lineStart);
4297
4366
  const lineEnd = nl === -1 ? text.length : nl;
4367
+ if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
4298
4368
  for (let i = lineStart; i < lineEnd; i++) {
4299
4369
  const ch = text[i];
4300
4370
  if (ch === "`") backtickHazard = true;
@@ -4307,6 +4377,7 @@ function findRawSafeCut(active) {
4307
4377
  if (nl === -1) break;
4308
4378
  if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
4309
4379
  lineStart = nl + 1;
4380
+ atLineStart = true;
4310
4381
  }
4311
4382
  offset += text.length;
4312
4383
  }
@@ -4315,11 +4386,14 @@ function findRawSafeCut(active) {
4315
4386
  var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
4316
4387
  function createIncrementalLatexPreprocessor(options) {
4317
4388
  const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
4389
+ const onAttempt = options?.onAttempt;
4390
+ const backoff = options?.backoff ?? true;
4318
4391
  let prevSource = "";
4319
4392
  let prevOutput = "";
4320
4393
  let frozenSrcEnd = 0;
4321
4394
  let frozenOut = "";
4322
4395
  let triggered = false;
4396
+ let nextAttemptLen = 0;
4323
4397
  return function incrementalPreprocessLaTeX(source) {
4324
4398
  if (source === prevSource) return prevOutput;
4325
4399
  const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
@@ -4327,6 +4401,7 @@ function createIncrementalLatexPreprocessor(options) {
4327
4401
  frozenSrcEnd = 0;
4328
4402
  frozenOut = "";
4329
4403
  triggered = false;
4404
+ nextAttemptLen = 0;
4330
4405
  }
4331
4406
  if (!triggered) {
4332
4407
  const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
@@ -4338,18 +4413,26 @@ function createIncrementalLatexPreprocessor(options) {
4338
4413
  triggered = true;
4339
4414
  }
4340
4415
  let active = source.slice(frozenSrcEnd);
4341
- if (active.length > freezeThreshold) {
4416
+ if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
4417
+ const activeLength = active.length;
4418
+ let advanced = false;
4419
+ let frozenBytes = 0;
4420
+ const freeze = (cut2, slice) => {
4421
+ frozenOut += slice.out;
4422
+ frozenSrcEnd += cut2;
4423
+ active = source.slice(frozenSrcEnd);
4424
+ advanced = true;
4425
+ frozenBytes = cut2;
4426
+ };
4342
4427
  const cut = findRawSafeCut(active);
4343
4428
  if (cut > 0) {
4344
4429
  const candidate = processSliceInstrumented(active.slice(0, cut));
4345
- if (candidate.quiescent) {
4346
- frozenOut += candidate.out;
4347
- frozenSrcEnd += cut;
4348
- active = source.slice(frozenSrcEnd);
4349
- }
4430
+ if (candidate.quiescent) freeze(cut, candidate);
4350
4431
  }
4432
+ nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
4433
+ onAttempt?.({ activeLength, frozenBytes });
4351
4434
  }
4352
- const tail = processSliceInstrumented(active);
4435
+ const tail = processSliceInstrumented(active, false);
4353
4436
  const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
4354
4437
  const out = head + tail.out;
4355
4438
  prevSource = source;