@ai-react-markdown/engine 2.6.0 → 2.7.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.
@@ -267,7 +267,199 @@ var defaultUrlTransform = (value) => {
267
267
 
268
268
  // src/components/incrementalParse/computeFreezeBoundary.ts
269
269
  var import_micromark_util_html_tag_name = require("micromark-util-html-tag-name");
270
+
271
+ // src/components/incrementalParse/mdLineText.ts
272
+ var MD_BLANK_RE = /^[ \t\r]*$/;
273
+ var isMdBlank = (text) => MD_BLANK_RE.test(text);
274
+ var mdTrim = (text) => text.replace(/^[ \t\r]+|[ \t\r]+$/g, "");
275
+ var mdTrimStart = (text) => text.replace(/^[ \t\r]+/, "");
276
+
277
+ // src/components/incrementalParse/referenceTaint.ts
270
278
  var import_micromark_util_normalize_identifier = require("micromark-util-normalize-identifier");
279
+ var FOOTNOTE_DEF_RE = /^ {0,3}\[\^[^\]]*\]:/;
280
+ var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
281
+ var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
282
+ function firstUnescaped(text, ch) {
283
+ for (let i = 0; i < text.length; i++) {
284
+ if (text[i] === "\\") i += 1;
285
+ else if (text[i] === ch) return i;
286
+ }
287
+ return -1;
288
+ }
289
+ function lastUnclosedBracket(text) {
290
+ let open = -1;
291
+ for (let i = 0; i < text.length; i++) {
292
+ const c = text[i];
293
+ if (c === "\\") i += 1;
294
+ else if (c === "[") open = i;
295
+ else if (c === "]") open = -1;
296
+ }
297
+ return open;
298
+ }
299
+ function normalizeLabel(label) {
300
+ const collapsed = label.replace(/[ \t\r\n]+/g, " ").replace(/^ | $/g, "");
301
+ return collapsed ? (0, import_micromark_util_normalize_identifier.normalizeIdentifier)(collapsed) : "";
302
+ }
303
+ function isPlausibleLinkDefRest(rest) {
304
+ const t = mdTrim(rest);
305
+ if (t === "") return false;
306
+ const destEnd = linkDestinationEnd(t);
307
+ if (destEnd === -1) return false;
308
+ const after = mdTrim(t.slice(destEnd));
309
+ if (after === "") return true;
310
+ const opener = after[0];
311
+ if (opener !== '"' && opener !== "'" && opener !== "(") return false;
312
+ const closer = opener === "(" ? ")" : opener;
313
+ for (let i = 1; i < after.length; i++) {
314
+ if (after[i] === "\\") {
315
+ i += 1;
316
+ continue;
317
+ }
318
+ if (after[i] === closer) return isMdBlank(after.slice(i + 1));
319
+ }
320
+ return false;
321
+ }
322
+ function linkDestinationEnd(t) {
323
+ if (t.startsWith("<")) {
324
+ for (let i2 = 1; i2 < t.length; i2++) {
325
+ const ch = t[i2];
326
+ if (ch === "\\" && (t[i2 + 1] === "<" || t[i2 + 1] === ">" || t[i2 + 1] === "\\")) {
327
+ i2 += 1;
328
+ continue;
329
+ }
330
+ if (ch === ">") return i2 + 1;
331
+ if (ch === "<") return -1;
332
+ }
333
+ return -1;
334
+ }
335
+ let balance = 0;
336
+ let i = 0;
337
+ for (; i < t.length; i++) {
338
+ const code = t.charCodeAt(i);
339
+ if (code === 32 || code === 9) break;
340
+ if (code < 32 || code === 127) return -1;
341
+ const ch = t[i];
342
+ if (ch === "\\" && (t[i + 1] === "(" || t[i + 1] === ")" || t[i + 1] === "\\")) {
343
+ i += 1;
344
+ continue;
345
+ }
346
+ if (ch === "(") balance += 1;
347
+ else if (ch === ")") {
348
+ if (balance === 0) break;
349
+ balance -= 1;
350
+ }
351
+ }
352
+ if (balance !== 0 || i === 0) return -1;
353
+ return i;
354
+ }
355
+ function inlineResourceEnd(text, openIdx) {
356
+ let i = openIdx + 1;
357
+ const skipWs = () => {
358
+ while (i < text.length && (text[i] === " " || text[i] === " ")) i += 1;
359
+ };
360
+ skipWs();
361
+ if (text[i] === ")") return i + 1;
362
+ const destEnd = linkDestinationEnd(text.slice(i));
363
+ if (destEnd === -1) return -1;
364
+ i += destEnd;
365
+ const beforeWs = i;
366
+ skipWs();
367
+ if (text[i] === ")") return i + 1;
368
+ if (i === beforeWs) return -1;
369
+ const opener = text[i];
370
+ if (opener !== '"' && opener !== "'" && opener !== "(") return -1;
371
+ const closer = opener === "(" ? ")" : opener;
372
+ for (i += 1; i < text.length; i++) {
373
+ if (text[i] === "\\") {
374
+ i += 1;
375
+ continue;
376
+ }
377
+ if (text[i] === closer) {
378
+ i += 1;
379
+ skipWs();
380
+ return text[i] === ")" ? i + 1 : -1;
381
+ }
382
+ }
383
+ return -1;
384
+ }
385
+ function collectRefLine(cp, lnStart, lnEnd, scanText, inRawText, isBlockStart) {
386
+ const defShaped = inRawText ? null : DEF_RE.exec(scanText);
387
+ const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(scanText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
388
+ const defLineStart = isBlockStart || !cp.prevLineWasText || cp.prevLineWasValidDef;
389
+ const validDef = def !== null && defLineStart;
390
+ if (validDef) {
391
+ const label = def[1];
392
+ if (label.startsWith("^")) {
393
+ const key = normalizeLabel(label.slice(1));
394
+ if (key && !cp.footnoteDefs.has(key)) cp.footnoteDefs.set(key, lnEnd);
395
+ } else {
396
+ const key = normalizeLabel(label);
397
+ if (key && !cp.defs.has(key)) cp.defs.set(key, lnEnd);
398
+ }
399
+ }
400
+ if (cp.referenceTaint) {
401
+ const pushRef = (offset, inner, followAt) => {
402
+ const follow = scanText[followAt];
403
+ if (follow === "(" && inlineResourceEnd(scanText, followAt) !== -1) return;
404
+ let label;
405
+ let footnote = false;
406
+ if (inner.startsWith("^")) {
407
+ footnote = true;
408
+ label = normalizeLabel(inner.slice(1));
409
+ } else if (follow === "[") {
410
+ const explicit = /^\[((?:[^[\]\\]|\\.)*)\]/.exec(scanText.slice(followAt));
411
+ label = normalizeLabel(explicit && explicit[1] ? explicit[1] : inner);
412
+ } else {
413
+ label = normalizeLabel(inner);
414
+ }
415
+ if (label) cp.unresolvedRefs.push({ offset, label, footnote });
416
+ };
417
+ const pending = cp.openBracket;
418
+ cp.openBracket = null;
419
+ if (pending) {
420
+ const close = firstUnescaped(scanText, "]");
421
+ const open = firstUnescaped(scanText, "[");
422
+ const cont = (t) => t.replace(/^ {0,3}>[ \t]?/, "");
423
+ if (close !== -1 && (open === -1 || close < open)) {
424
+ pushRef(pending.offset, `${pending.text}
425
+ ${cont(scanText.slice(0, close))}`, close + 1);
426
+ } else if (close === -1 && open === -1) {
427
+ cp.openBracket = { offset: pending.offset, text: `${pending.text}
428
+ ${cont(scanText)}` };
429
+ }
430
+ }
431
+ if (scanText.includes("[")) {
432
+ const defBracket = validDef ? def.index + def[0].indexOf("[") : -1;
433
+ REF_RE.lastIndex = 0;
434
+ let m;
435
+ while ((m = REF_RE.exec(scanText)) !== null) {
436
+ const followAt = m.index + m[0].length;
437
+ if (scanText[followAt] === ":" && m.index === defBracket) continue;
438
+ pushRef(lnStart + m.index, m[1], followAt);
439
+ }
440
+ const trailingOpen = lastUnclosedBracket(scanText);
441
+ if (trailingOpen !== -1) {
442
+ cp.openBracket = { offset: lnStart + trailingOpen, text: scanText.slice(trailingOpen + 1) };
443
+ }
444
+ }
445
+ }
446
+ return { validDef, validLinkDef: validDef && !def[1].startsWith("^") };
447
+ }
448
+ function settleRefsAndEarliestUnresolved(cp) {
449
+ if (cp.unresolvedRefs.length > 0) {
450
+ const settled = (defEnd) => cp.lastBlankStart >= defEnd;
451
+ cp.unresolvedRefs = cp.unresolvedRefs.filter((ref) => {
452
+ const table = ref.footnote ? cp.footnoteDefs : cp.defs;
453
+ const defEnd = table.get(ref.label);
454
+ return defEnd === void 0 || !settled(defEnd);
455
+ });
456
+ }
457
+ let earliestUnresolved = Infinity;
458
+ for (const ref of cp.unresolvedRefs) earliestUnresolved = Math.min(earliestUnresolved, ref.offset);
459
+ return earliestUnresolved;
460
+ }
461
+
462
+ // src/components/incrementalParse/computeFreezeBoundary.ts
271
463
  var TYPE6_NAMES = new Set(import_micromark_util_html_tag_name.htmlBlockNames);
272
464
  var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
273
465
  var DOCUMENT_STRUCTURE_NAMES = /* @__PURE__ */ new Set(["html", "head", "body", "frameset"]);
@@ -290,53 +482,6 @@ function tailCarriesRetroactive(text) {
290
482
  }
291
483
  return false;
292
484
  }
293
- var HTML_BREAKOUT_TAGS = /* @__PURE__ */ new Set([
294
- "b",
295
- "big",
296
- "blockquote",
297
- "body",
298
- "br",
299
- "center",
300
- "code",
301
- "dd",
302
- "div",
303
- "dl",
304
- "dt",
305
- "em",
306
- "embed",
307
- "h1",
308
- "h2",
309
- "h3",
310
- "h4",
311
- "h5",
312
- "h6",
313
- "head",
314
- "hr",
315
- "i",
316
- "img",
317
- "li",
318
- "listing",
319
- "menu",
320
- "meta",
321
- "nobr",
322
- "ol",
323
- "p",
324
- "pre",
325
- "ruby",
326
- "s",
327
- "small",
328
- "span",
329
- "strong",
330
- "strike",
331
- "sub",
332
- "sup",
333
- "table",
334
- "tt",
335
- "u",
336
- "ul",
337
- "var"
338
- ]);
339
- var HTML_INTEGRATION_POINTS = ["foreignobject", "desc", "title", "mi", "mo", "mn", "ms", "mtext", "annotation-xml"];
340
485
  var SCOPE_BARRIER_NAMES = /* @__PURE__ */ new Set([
341
486
  "applet",
342
487
  "caption",
@@ -379,6 +524,11 @@ var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
379
524
  var TYPE1_CLOSE_RE = /<\/(?:script|pre|style|textarea)>/i;
380
525
  var TYPE7_LINE_RE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\r][^>]*|\/)?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\r]*>)[ \t\r]*$/;
381
526
  var t7Name = (line) => /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(line)[1];
527
+ var mdHtml = (b, type) => b.kind === "html" && b.type === type;
528
+ var mdHtml25 = (b) => b.kind === "html" && b.type >= 2 && b.type <= 5;
529
+ var commentEitherOpen = (md, p5) => mdHtml(md, 2) || p5.kind === "comment";
530
+ var inRawTextTok = (t) => t.kind === "rawText" || t.kind === "script";
531
+ var rawTextElement = (t) => t.kind === "rawText" ? t.element : t.kind === "script" ? "script" : null;
382
532
  var VOID_TAGS = /* @__PURE__ */ new Set([
383
533
  "area",
384
534
  "base",
@@ -396,9 +546,7 @@ var VOID_TAGS = /* @__PURE__ */ new Set([
396
546
  "wbr"
397
547
  ]);
398
548
  var LIST_MARKER_RE = /^ {0,3}(?:[-*+]|\d{1,9}[.)])(?:[ \t]|$)/;
399
- var FOOTNOTE_DEF_RE = /^ {0,3}\[\^[^\]]*\]:/;
400
549
  var DEF_LIST_DD_RE = /^ {0,3}:[ \t]/;
401
- var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
402
550
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
403
551
  var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
404
552
  var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
@@ -431,12 +579,7 @@ function scanTagAttrs(text, from, to, out) {
431
579
  out.state = st;
432
580
  return -1;
433
581
  }
434
- var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
435
582
  var BACKTICK_RUN_RE = /`+/g;
436
- var MD_BLANK_RE = /^[ \t\r]*$/;
437
- var isMdBlank = (text) => MD_BLANK_RE.test(text);
438
- var mdTrim = (text) => text.replace(/^[ \t\r]+|[ \t\r]+$/g, "");
439
- var mdTrimStart = (text) => text.replace(/^[ \t\r]+/, "");
440
583
  function computeIndent(text) {
441
584
  let indent = 0;
442
585
  for (const ch of text) {
@@ -446,27 +589,6 @@ function computeIndent(text) {
446
589
  }
447
590
  return indent;
448
591
  }
449
- function firstUnescaped(text, ch) {
450
- for (let i = 0; i < text.length; i++) {
451
- if (text[i] === "\\") i += 1;
452
- else if (text[i] === ch) return i;
453
- }
454
- return -1;
455
- }
456
- function lastUnclosedBracket(text) {
457
- let open = -1;
458
- for (let i = 0; i < text.length; i++) {
459
- const c = text[i];
460
- if (c === "\\") i += 1;
461
- else if (c === "[") open = i;
462
- else if (c === "]") open = -1;
463
- }
464
- return open;
465
- }
466
- function normalizeLabel(label) {
467
- const collapsed = label.replace(/[ \t\r\n]+/g, " ").replace(/^ | $/g, "");
468
- return collapsed ? (0, import_micromark_util_normalize_identifier.normalizeIdentifier)(collapsed) : "";
469
- }
470
592
  function canBecomeDdLine(text, confirmed) {
471
593
  let i = 0;
472
594
  while (i < text.length && text[i] === " ") i += 1;
@@ -523,20 +645,9 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
523
645
  unresolvedRefs: [],
524
646
  tagBalance: /* @__PURE__ */ new Map(),
525
647
  openTotal: 0,
526
- commentOpen: false,
527
- piOpen: false,
528
- bogusOpen: false,
529
- rawTextOpen: null,
648
+ p5Tok: { kind: "data" },
530
649
  openStack: [],
531
- scriptDataEscaped: false,
532
- declOpen: false,
533
- cdataOpen: false,
534
- inFence: false,
535
- fenceChar: "",
536
- fenceLen: 0,
537
- inMath: false,
538
- mathFenceLen: 0,
539
- openIndent: 0,
650
+ mdBlock: { kind: "none" },
540
651
  blankRun: 0,
541
652
  lastBlankStart: -1,
542
653
  hazardVerdict: false,
@@ -546,101 +657,14 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
546
657
  prevLineWasValidDef: false,
547
658
  paragraphHasUnpairedRun: false,
548
659
  openBracket: null,
549
- htmlFlowSinceBlank: false,
550
- htmlSeamPending: false,
660
+ mayBeRawToMicromark: false,
661
+ p5SealPending: false,
551
662
  phasePoisonedAt: Infinity,
552
663
  pendingTruncatedTags: [],
553
664
  pendingTruncatedCloses: [],
554
- tagAcrossLines: false,
555
- tagAcrossLinesIndent: 0,
556
- tagAcrossLinesState: "outside",
557
- htmlFlowReal: false,
558
- type1FlowOpen: false,
559
- rawTextInline: false
665
+ pendingTag: null
560
666
  };
561
667
  }
562
- function isPlausibleLinkDefRest(rest) {
563
- const t = mdTrim(rest);
564
- if (t === "") return false;
565
- const destEnd = linkDestinationEnd(t);
566
- if (destEnd === -1) return false;
567
- const after = mdTrim(t.slice(destEnd));
568
- if (after === "") return true;
569
- const opener = after[0];
570
- if (opener !== '"' && opener !== "'" && opener !== "(") return false;
571
- const closer = opener === "(" ? ")" : opener;
572
- for (let i = 1; i < after.length; i++) {
573
- if (after[i] === "\\") {
574
- i += 1;
575
- continue;
576
- }
577
- if (after[i] === closer) return isMdBlank(after.slice(i + 1));
578
- }
579
- return false;
580
- }
581
- function linkDestinationEnd(t) {
582
- if (t.startsWith("<")) {
583
- for (let i2 = 1; i2 < t.length; i2++) {
584
- const ch = t[i2];
585
- if (ch === "\\" && (t[i2 + 1] === "<" || t[i2 + 1] === ">" || t[i2 + 1] === "\\")) {
586
- i2 += 1;
587
- continue;
588
- }
589
- if (ch === ">") return i2 + 1;
590
- if (ch === "<") return -1;
591
- }
592
- return -1;
593
- }
594
- let balance = 0;
595
- let i = 0;
596
- for (; i < t.length; i++) {
597
- const code = t.charCodeAt(i);
598
- if (code === 32 || code === 9) break;
599
- if (code < 32 || code === 127) return -1;
600
- const ch = t[i];
601
- if (ch === "\\" && (t[i + 1] === "(" || t[i + 1] === ")" || t[i + 1] === "\\")) {
602
- i += 1;
603
- continue;
604
- }
605
- if (ch === "(") balance += 1;
606
- else if (ch === ")") {
607
- if (balance === 0) break;
608
- balance -= 1;
609
- }
610
- }
611
- if (balance !== 0 || i === 0) return -1;
612
- return i;
613
- }
614
- function inlineResourceEnd(text, openIdx) {
615
- let i = openIdx + 1;
616
- const skipWs = () => {
617
- while (i < text.length && (text[i] === " " || text[i] === " ")) i += 1;
618
- };
619
- skipWs();
620
- if (text[i] === ")") return i + 1;
621
- const destEnd = linkDestinationEnd(text.slice(i));
622
- if (destEnd === -1) return -1;
623
- i += destEnd;
624
- const beforeWs = i;
625
- skipWs();
626
- if (text[i] === ")") return i + 1;
627
- if (i === beforeWs) return -1;
628
- const opener = text[i];
629
- if (opener !== '"' && opener !== "'" && opener !== "(") return -1;
630
- const closer = opener === "(" ? ")" : opener;
631
- for (i += 1; i < text.length; i++) {
632
- if (text[i] === "\\") {
633
- i += 1;
634
- continue;
635
- }
636
- if (text[i] === closer) {
637
- i += 1;
638
- skipWs();
639
- return text[i] === ")" ? i + 1 : -1;
640
- }
641
- }
642
- return -1;
643
- }
644
668
  function classifyBlockStart(text, indent, defListEnabled) {
645
669
  if (indent >= 4) return true;
646
670
  if (LIST_MARKER_RE.test(text) || FOOTNOTE_DEF_RE.test(text)) return true;
@@ -686,16 +710,7 @@ function computeFreezeBoundary(text, options, resume) {
686
710
  cp.confirmedOffset = end + 1;
687
711
  start = end + 1;
688
712
  }
689
- if (cp.unresolvedRefs.length > 0) {
690
- const settled = (defEnd) => cp.lastBlankStart >= defEnd;
691
- cp.unresolvedRefs = cp.unresolvedRefs.filter((ref) => {
692
- const table = ref.footnote ? cp.footnoteDefs : cp.defs;
693
- const defEnd = table.get(ref.label);
694
- return defEnd === void 0 || !settled(defEnd);
695
- });
696
- }
697
- let earliestUnresolved = Infinity;
698
- for (const ref of cp.unresolvedRefs) earliestUnresolved = Math.min(earliestUnresolved, ref.offset);
713
+ const earliestUnresolved = settleRefsAndEarliestUnresolved(cp);
699
714
  const defListSettled = (c) => {
700
715
  if (!options.defListEnabled || c.blankRun >= 2) return true;
701
716
  if (c.defListSettled !== null) return c.defListSettled;
@@ -718,9 +733,8 @@ function computeFreezeBoundary(text, options, resume) {
718
733
  function pendingFenceCloser(checkpoint) {
719
734
  const cp = checkpoint;
720
735
  if (cp.phasePoisonedAt !== Infinity) return "";
721
- if (cp.openIndent !== 0) return "";
722
- if (cp.inFence) return cp.fenceChar.repeat(cp.fenceLen);
723
- if (cp.inMath) return "$".repeat(cp.mathFenceLen);
736
+ if (cp.mdBlock.kind === "fence" && cp.mdBlock.indent === 0) return cp.mdBlock.char.repeat(cp.mdBlock.len);
737
+ if (cp.mdBlock.kind === "math" && cp.mdBlock.indent === 0) return "$".repeat(cp.mdBlock.len);
724
738
  return "";
725
739
  }
726
740
  function floatingResidue(text, commentOpenAtStart) {
@@ -771,53 +785,30 @@ function processConfirmedLine(cp, ln, text) {
771
785
  newest.defListSettled = ln.blank ? true : !canBecomeDdLine(ln.text, true);
772
786
  }
773
787
  const isBlockStart = cp.prevLineBlank;
774
- if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen)) {
788
+ if (cp.p5SealPending && !ln.blank && !cp.mayBeRawToMicromark && !(mdHtml25(cp.mdBlock) || cp.p5Tok.kind === "comment" || cp.p5Tok.kind === "bogus")) {
775
789
  const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
776
790
  const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
777
791
  if (!defShapedLine && !commentOnly) {
778
- cp.htmlSeamPending = false;
792
+ cp.p5SealPending = false;
779
793
  }
780
794
  }
781
- const inForeignContent = () => FOREIGN_ROOT_NAMES.some((name) => (cp.tagBalance.get(name) ?? 0) > 0);
782
- const honoursSelfClosing = (tag) => {
783
- if (tag === "svg" || tag === "math") return true;
784
- if (!inForeignContent() || HTML_BREAKOUT_TAGS.has(tag)) return false;
785
- for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return false;
786
- return true;
787
- };
788
- const htmlRulesApply = () => {
789
- if (!inForeignContent()) return true;
790
- for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return true;
791
- return false;
792
- };
793
- const popForeignRoots = () => {
794
- for (const name of FOREIGN_ROOT_NAMES) {
795
- const count = cp.tagBalance.get(name) ?? 0;
796
- if (count > 0) {
797
- cp.tagBalance.set(name, 0);
798
- cp.openTotal -= count;
799
- }
800
- }
801
- if (cp.openStack.length > 0) cp.openStack = cp.openStack.filter((n) => !FOREIGN_ROOT_NAMES.includes(n));
802
- };
803
- const noteBreakout = (tag, closing) => {
804
- if (closing || cp.rawTextOpen !== null) return;
805
- if (HTML_BREAKOUT_TAGS.has(tag) && !htmlRulesApply()) popForeignRoots();
806
- };
795
+ const possiblyInsideForeign = () => FOREIGN_ROOT_NAMES.some((name) => (cp.tagBalance.get(name) ?? 0) > 0);
796
+ const honoursSelfClosing = (tag) => tag === "svg" || tag === "math";
797
+ const foreignRawTextSwitchUnknowable = () => possiblyInsideForeign();
807
798
  const applyTag = (tag, closing) => {
808
- if (cp.rawTextOpen !== null) {
809
- if (cp.scriptDataEscaped && !closing && tag === "script") {
799
+ if (inRawTextTok(cp.p5Tok)) {
800
+ if (cp.p5Tok.kind === "script" && cp.p5Tok.escaped && !closing && tag === "script") {
810
801
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
811
802
  }
812
- if (!(closing && tag === cp.rawTextOpen)) return;
813
- cp.rawTextOpen = null;
814
- cp.scriptDataEscaped = false;
803
+ if (!(closing && tag === rawTextElement(cp.p5Tok))) return;
804
+ cp.p5Tok = { kind: "data" };
815
805
  } else {
816
- noteBreakout(tag, closing);
817
- if (!closing && RAW_TEXT_ELEMENTS.has(tag) && htmlRulesApply()) {
818
- cp.rawTextOpen = tag;
819
- cp.scriptDataEscaped = false;
820
- cp.rawTextInline = !cp.htmlFlowReal;
806
+ if (!closing && RAW_TEXT_ELEMENTS.has(tag) && foreignRawTextSwitchUnknowable()) {
807
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
808
+ } else if (!closing && RAW_TEXT_ELEMENTS.has(tag)) {
809
+ if (cp.p5Tok.kind !== "data") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
810
+ const openedInline = cp.mdBlock.kind !== "html";
811
+ cp.p5Tok = tag === "script" ? { kind: "script", escaped: false, openedInline } : { kind: "rawText", element: tag, openedInline };
821
812
  if (tag === "plaintext") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
822
813
  }
823
814
  }
@@ -845,15 +836,14 @@ function processConfirmedLine(cp, ln, text) {
845
836
  cp.openTotal += 1;
846
837
  }
847
838
  };
848
- const strayTablePart = (tag) => TABLE_PART_NAMES.has(tag) && (cp.tagBalance.get("table") ?? 0) === 0;
849
- const commentOpenAtLineStart = cp.commentOpen;
850
- const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
851
- if (cp.inFence) {
839
+ const definitelyInsideTable = () => (cp.tagBalance.get("table") ?? 0) > 0;
840
+ const strayTablePart = (tag) => TABLE_PART_NAMES.has(tag) && !definitelyInsideTable();
841
+ const commentOpenAtLineStart = commentEitherOpen(cp.mdBlock, cp.p5Tok);
842
+ const rawOpenAtLineStart = mdHtml25(cp.mdBlock) || cp.p5Tok.kind === "comment" || cp.p5Tok.kind === "bogus";
843
+ if (cp.mdBlock.kind === "fence") {
852
844
  const close = FENCE_RE.exec(ln.text);
853
- if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
854
- cp.inFence = false;
855
- cp.fenceChar = "";
856
- cp.fenceLen = 0;
845
+ if (close && close[1][0] === cp.mdBlock.char && close[1].length >= cp.mdBlock.len && isMdBlank(ln.text.slice(close[0].length))) {
846
+ cp.mdBlock = { kind: "none" };
857
847
  }
858
848
  cp.blankRun = 0;
859
849
  cp.paragraphHasUnpairedRun = false;
@@ -863,20 +853,17 @@ function processConfirmedLine(cp, ln, text) {
863
853
  cp.prevLineWasValidDef = false;
864
854
  return;
865
855
  }
866
- if (!cp.inMath && !rawOpenAtLineStart) {
856
+ if (cp.mdBlock.kind !== "math" && !rawOpenAtLineStart) {
867
857
  const open = FENCE_RE.exec(ln.text);
868
858
  const bogusInfo = open !== null && open[1][0] === "`" && ln.text.slice(ln.text.indexOf(open[1]) + open[1].length).includes("`");
869
- if (open && !bogusInfo && cp.htmlFlowSinceBlank) {
859
+ if (open && !bogusInfo && cp.mayBeRawToMicromark) {
870
860
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
871
861
  } else if (open && !bogusInfo) {
872
862
  if (isBlockStart) {
873
863
  const verdict = classifyBlockStart(ln.text, ln.indent, cp.defListEnabled);
874
864
  if (verdict !== null) cp.hazardVerdict = verdict;
875
865
  }
876
- cp.inFence = true;
877
- cp.fenceChar = open[1][0];
878
- cp.fenceLen = open[1].length;
879
- cp.openIndent = ln.indent;
866
+ cp.mdBlock = { kind: "fence", char: open[1][0], len: open[1].length, indent: ln.indent };
880
867
  cp.blankRun = 0;
881
868
  cp.paragraphHasUnpairedRun = false;
882
869
  cp.openBracket = null;
@@ -886,11 +873,10 @@ function processConfirmedLine(cp, ln, text) {
886
873
  return;
887
874
  }
888
875
  }
889
- if (cp.inMath) {
876
+ if (cp.mdBlock.kind === "math") {
890
877
  const close = MATH_RUN_RE.exec(ln.text);
891
- if (close && close[1].length >= cp.mathFenceLen && isMdBlank(ln.text.slice(close[0].length))) {
892
- cp.inMath = false;
893
- cp.mathFenceLen = 0;
878
+ if (close && close[1].length >= cp.mdBlock.len && isMdBlank(ln.text.slice(close[0].length))) {
879
+ cp.mdBlock = { kind: "none" };
894
880
  }
895
881
  cp.blankRun = 0;
896
882
  cp.paragraphHasUnpairedRun = false;
@@ -904,16 +890,14 @@ function processConfirmedLine(cp, ln, text) {
904
890
  if (mathRun) {
905
891
  const rest = ln.text.slice(ln.text.indexOf(mathRun[1]) + mathRun[1].length);
906
892
  if (!rest.includes("$")) {
907
- if (cp.htmlFlowSinceBlank) {
893
+ if (cp.mayBeRawToMicromark) {
908
894
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
909
895
  } else {
910
896
  if (isBlockStart) {
911
897
  const verdict = classifyBlockStart(ln.text, ln.indent, cp.defListEnabled);
912
898
  if (verdict !== null) cp.hazardVerdict = verdict;
913
899
  }
914
- cp.inMath = true;
915
- cp.mathFenceLen = mathRun[1].length;
916
- cp.openIndent = ln.indent;
900
+ cp.mdBlock = { kind: "math", len: mathRun[1].length, indent: ln.indent };
917
901
  cp.blankRun = 0;
918
902
  cp.paragraphHasUnpairedRun = false;
919
903
  cp.openBracket = null;
@@ -930,36 +914,36 @@ function processConfirmedLine(cp, ln, text) {
930
914
  cp.pendingTruncatedTags = [];
931
915
  }
932
916
  cp.pendingTruncatedCloses = [];
933
- if (cp.tagAcrossLines && (cp.tagAcrossLinesState === '"' || cp.tagAcrossLinesState === "'")) {
917
+ if (cp.pendingTag !== null && (cp.pendingTag.attr === '"' || cp.pendingTag.attr === "'")) {
934
918
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
935
919
  }
936
- cp.tagAcrossLines = false;
937
- cp.tagAcrossLinesState = "outside";
938
- if (cp.bogusOpen) {
920
+ cp.pendingTag = null;
921
+ if (cp.p5Tok.kind === "bogus") {
939
922
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
940
- cp.bogusOpen = false;
923
+ cp.p5Tok = { kind: "data" };
941
924
  }
925
+ if (cp.mdBlock.kind === "html" && cp.mdBlock.type >= 6) cp.mdBlock = { kind: "none" };
942
926
  cp.blankRun += 1;
943
927
  cp.lastBlankStart = ln.start;
944
928
  cp.candidates.push({
945
929
  offset: Math.min(ln.end + 1, text.length),
946
930
  blankRun: cp.blankRun,
947
- // `type1FlowOpen`: an unterminated type-1 block swallows this blank
948
- // and everything after it as RAW content, so nothing here is a block
949
- // boundary at all. Its tags are invisible to the balance scan
950
- // (`rawTextOpen` suppresses them), which is exactly why `openTotal`
951
- // reads 0 and the candidate looked safe.
952
- htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen && !cp.type1FlowOpen,
931
+ // The html member covers types 1-5 in one check: an unterminated
932
+ // type-1 block swallows this blank and everything after it as RAW
933
+ // content (its tags are invisible to the balance scan — the raw-text
934
+ // mask suppresses them which is exactly why `openTotal` reads 0
935
+ // and the candidate looked safe), and the 2-5 interiors are the
936
+ // same construct to both grammars.
937
+ htmlBalanced: cp.openTotal === 0 && cp.mdBlock.kind !== "html" && cp.p5Tok.kind !== "bogus",
953
938
  hazard: cp.hazardVerdict,
954
- seamRisk: cp.htmlSeamPending,
939
+ seamRisk: cp.p5SealPending,
955
940
  defListSettled: null
956
941
  });
957
942
  cp.paragraphHasUnpairedRun = false;
958
943
  cp.openBracket = null;
959
- if (!cp.type1FlowOpen) {
960
- cp.htmlFlowSinceBlank = false;
961
- cp.htmlFlowReal = false;
962
- if (cp.rawTextOpen !== null && !cp.rawTextInline) {
944
+ if (!mdHtml(cp.mdBlock, 1)) {
945
+ cp.mayBeRawToMicromark = false;
946
+ if (inRawTextTok(cp.p5Tok) && !cp.p5Tok.openedInline) {
963
947
  cp.phasePoisonedAt = 0;
964
948
  }
965
949
  }
@@ -976,86 +960,29 @@ function processConfirmedLine(cp, ln, text) {
976
960
  }
977
961
  const tagStart = ln.indent <= 3 ? /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(mdTrimStart(ln.text)) : null;
978
962
  if (tagStart) {
979
- const noRealBlockOpen = !cp.htmlFlowReal;
980
- cp.htmlFlowSinceBlank = true;
981
- if (noRealBlockOpen && TYPE1_START_RE.test(mdTrimStart(ln.text))) cp.type1FlowOpen = true;
963
+ const noRealBlockOpen = cp.mdBlock.kind !== "html";
964
+ cp.mayBeRawToMicromark = true;
965
+ if (noRealBlockOpen && TYPE1_START_RE.test(mdTrimStart(ln.text))) cp.mdBlock = { kind: "html", type: 1 };
982
966
  if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
983
- if (!cp.htmlFlowReal) {
967
+ if (cp.mdBlock.kind !== "html") {
984
968
  const t = mdTrimStart(ln.text);
985
969
  const t6 = TYPE6_START_RE.exec(t);
986
970
  const t7 = TYPE7_LINE_RE.exec(t);
987
- 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
971
+ const realT6 = t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase());
972
+ if (realT6 || TYPE1_START_RE.test(t) || // Type 7 cannot interrupt a paragraph, and excludes the raw-text
988
973
  // names (those are type 1 as start tags, paragraph as end tags).
989
974
  t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7Name(t).toLowerCase())) {
990
- cp.htmlFlowReal = true;
975
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: realT6 ? 6 : 7 };
991
976
  }
992
977
  }
993
978
  }
994
- const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
979
+ const inRawText = cp.mayBeRawToMicromark || rawOpenAtLineStart;
995
980
  const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
996
981
  const { masked, unpaired } = inRawText ? { masked: null, unpaired: false } : maskIntraLineCodeSpans(ln.text, cp.paragraphHasUnpairedRun);
997
982
  if (unpaired) cp.paragraphHasUnpairedRun = true;
998
983
  const scanText = masked ?? ln.text;
999
- const defShaped = inRawText ? null : DEF_RE.exec(scanText);
1000
- const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(scanText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
1001
- const defLineStart = isBlockStart || !cp.prevLineWasText || cp.prevLineWasValidDef;
1002
- const validDef = def !== null && defLineStart;
1003
- if (validDef) {
1004
- const label = def[1];
1005
- if (label.startsWith("^")) {
1006
- const key = normalizeLabel(label.slice(1));
1007
- if (key && !cp.footnoteDefs.has(key)) cp.footnoteDefs.set(key, ln.end);
1008
- } else {
1009
- const key = normalizeLabel(label);
1010
- if (key && !cp.defs.has(key)) cp.defs.set(key, ln.end);
1011
- }
1012
- }
1013
- if (cp.referenceTaint) {
1014
- const pushRef = (offset, inner, followAt) => {
1015
- const follow = scanText[followAt];
1016
- if (follow === "(" && inlineResourceEnd(scanText, followAt) !== -1) return;
1017
- let label;
1018
- let footnote = false;
1019
- if (inner.startsWith("^")) {
1020
- footnote = true;
1021
- label = normalizeLabel(inner.slice(1));
1022
- } else if (follow === "[") {
1023
- const explicit = /^\[((?:[^[\]\\]|\\.)*)\]/.exec(scanText.slice(followAt));
1024
- label = normalizeLabel(explicit && explicit[1] ? explicit[1] : inner);
1025
- } else {
1026
- label = normalizeLabel(inner);
1027
- }
1028
- if (label) cp.unresolvedRefs.push({ offset, label, footnote });
1029
- };
1030
- const pending = cp.openBracket;
1031
- cp.openBracket = null;
1032
- if (pending) {
1033
- const close = firstUnescaped(scanText, "]");
1034
- const open = firstUnescaped(scanText, "[");
1035
- const cont = (t) => t.replace(/^ {0,3}>[ \t]?/, "");
1036
- if (close !== -1 && (open === -1 || close < open)) {
1037
- pushRef(pending.offset, `${pending.text}
1038
- ${cont(scanText.slice(0, close))}`, close + 1);
1039
- } else if (close === -1 && open === -1) {
1040
- cp.openBracket = { offset: pending.offset, text: `${pending.text}
1041
- ${cont(scanText)}` };
1042
- }
1043
- }
1044
- if (scanText.includes("[")) {
1045
- const defBracket = validDef ? def.index + def[0].indexOf("[") : -1;
1046
- REF_RE.lastIndex = 0;
1047
- let m;
1048
- while ((m = REF_RE.exec(scanText)) !== null) {
1049
- const followAt = m.index + m[0].length;
1050
- if (scanText[followAt] === ":" && m.index === defBracket) continue;
1051
- pushRef(ln.start + m.index, m[1], followAt);
1052
- }
1053
- const trailingOpen = lastUnclosedBracket(scanText);
1054
- if (trailingOpen !== -1) {
1055
- cp.openBracket = { offset: ln.start + trailingOpen, text: scanText.slice(trailingOpen + 1) };
1056
- }
1057
- }
1058
- }
984
+ const defRawToMicromark = cp.mdBlock.kind === "html" || rawOpenAtLineStart || inRawTextTok(cp.p5Tok);
985
+ const { validLinkDef } = collectRefLine(cp, ln.start, ln.end, scanText, defRawToMicromark, isBlockStart);
1059
986
  const rawSpans = [];
1060
987
  let pos = 0;
1061
988
  const poisonRawDivergence = () => {
@@ -1063,7 +990,7 @@ ${cont(scanText)}` };
1063
990
  };
1064
991
  let inlineRawOpenerIdx = -1;
1065
992
  while (pos < scanText.length) {
1066
- if (cp.piOpen) {
993
+ if (mdHtml(cp.mdBlock, 3)) {
1067
994
  const c = scanText.indexOf("?>", pos);
1068
995
  const gt = scanText.indexOf(">", pos);
1069
996
  if (gt !== -1 && (c === -1 || gt !== c + 1)) poisonRawDivergence();
@@ -1072,11 +999,11 @@ ${cont(scanText)}` };
1072
999
  break;
1073
1000
  }
1074
1001
  rawSpans.push([pos, c + 2]);
1075
- cp.piOpen = false;
1002
+ cp.mdBlock = { kind: "none" };
1076
1003
  pos = c + 2;
1077
1004
  continue;
1078
1005
  }
1079
- if (cp.cdataOpen) {
1006
+ if (mdHtml(cp.mdBlock, 5)) {
1080
1007
  const c = scanText.indexOf("]]>", pos);
1081
1008
  const gt = scanText.indexOf(">", pos);
1082
1009
  if (gt !== -1 && (c === -1 || gt !== c + 2)) poisonRawDivergence();
@@ -1085,38 +1012,51 @@ ${cont(scanText)}` };
1085
1012
  break;
1086
1013
  }
1087
1014
  rawSpans.push([pos, c + 3]);
1088
- cp.cdataOpen = false;
1015
+ cp.mdBlock = { kind: "none" };
1089
1016
  pos = c + 3;
1090
1017
  continue;
1091
1018
  }
1092
- if (cp.declOpen || cp.bogusOpen) {
1019
+ if (mdHtml(cp.mdBlock, 4)) {
1020
+ const c = scanText.indexOf(">", pos);
1021
+ if (c === -1) {
1022
+ rawSpans.push([pos, scanText.length]);
1023
+ break;
1024
+ }
1025
+ rawSpans.push([pos, c + 1]);
1026
+ cp.mdBlock = { kind: "none" };
1027
+ if (cp.p5Tok.kind === "bogus") cp.p5Tok = { kind: "data" };
1028
+ pos = c + 1;
1029
+ continue;
1030
+ }
1031
+ if (cp.p5Tok.kind === "bogus") {
1093
1032
  const c = scanText.indexOf(">", pos);
1094
1033
  if (c === -1) {
1095
1034
  rawSpans.push([pos, scanText.length]);
1096
1035
  break;
1097
1036
  }
1098
1037
  rawSpans.push([pos, c + 1]);
1099
- cp.declOpen = false;
1100
- cp.bogusOpen = false;
1038
+ cp.p5Tok = { kind: "data" };
1101
1039
  pos = c + 1;
1102
1040
  continue;
1103
1041
  }
1042
+ if (commentOpenAtLineStart || inRawTextTok(cp.p5Tok) || mdHtml(cp.mdBlock, 1)) break;
1104
1043
  const pi = scanText.indexOf("<?", pos);
1105
1044
  const cd = scanText.indexOf("<![CDATA[", pos);
1106
1045
  const dm = scanText.slice(pos).search(/<![A-Za-z]/);
1107
1046
  const decl = dm === -1 ? -1 : pos + dm;
1108
- const bm = cp.htmlFlowReal ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
1047
+ const bm = cp.mdBlock.kind === "html" ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
1109
1048
  const bogus = bm === -1 ? -1 : pos + bm;
1110
1049
  const starts = [pi, cd, decl, bogus].filter((x) => x !== -1);
1111
1050
  if (starts.length === 0) break;
1112
1051
  const first = Math.min(...starts);
1113
1052
  if (first === bogus) {
1114
1053
  rawSpans.push([bogus, bogus + 2]);
1115
- cp.bogusOpen = true;
1054
+ if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
1055
+ else cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1116
1056
  pos = bogus + 2;
1117
1057
  } else if (first === cd) {
1118
1058
  rawSpans.push([cd, cd + 9]);
1119
- cp.cdataOpen = true;
1059
+ cp.mdBlock = { kind: "html", type: 5 };
1120
1060
  if (!isMdBlank(scanText.slice(0, cd)) || ln.indent > 3) inlineRawOpenerIdx = cd;
1121
1061
  pos = cd + 9;
1122
1062
  } else if (first === pi) {
@@ -1127,18 +1067,18 @@ ${cont(scanText)}` };
1127
1067
  continue;
1128
1068
  }
1129
1069
  rawSpans.push([pi, pi + 2]);
1130
- cp.piOpen = true;
1070
+ cp.mdBlock = { kind: "html", type: 3 };
1131
1071
  if (!isMdBlank(scanText.slice(0, pi)) || ln.indent > 3) inlineRawOpenerIdx = pi;
1132
1072
  pos = pi + 2;
1133
1073
  } else {
1134
1074
  rawSpans.push([decl, decl + 2]);
1135
1075
  if (ln.indent <= 3 && /^doctype/i.test(scanText.slice(decl + 2))) cp.phasePoisonedAt = 0;
1136
- cp.declOpen = true;
1076
+ cp.mdBlock = { kind: "html", type: 4 };
1137
1077
  if (!isMdBlank(scanText.slice(0, decl)) || ln.indent > 3) inlineRawOpenerIdx = decl;
1138
1078
  pos = decl + 2;
1139
1079
  }
1140
1080
  }
1141
- if (inlineRawOpenerIdx !== -1 && (cp.piOpen || cp.declOpen || cp.cdataOpen)) {
1081
+ if (inlineRawOpenerIdx !== -1 && cp.mdBlock.kind === "html" && cp.mdBlock.type >= 3) {
1142
1082
  cp.phasePoisonedAt = 0;
1143
1083
  }
1144
1084
  let tagText = scanText;
@@ -1146,19 +1086,18 @@ ${cont(scanText)}` };
1146
1086
  tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
1147
1087
  }
1148
1088
  let skipTagScan = false;
1149
- if (cp.tagAcrossLines) {
1150
- if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
1151
- const attrs = { state: cp.tagAcrossLinesState };
1089
+ if (cp.pendingTag !== null) {
1090
+ if (ln.indent < cp.pendingTag.indent) poisonRawDivergence();
1091
+ const attrs = { state: cp.pendingTag.attr };
1152
1092
  const gt = scanTagAttrs(ln.text, 0, ln.text.length, attrs);
1153
1093
  if (gt === -1) {
1154
1094
  scanTagAttrs("\n", 0, 1, attrs);
1155
- cp.tagAcrossLinesState = attrs.state;
1095
+ cp.pendingTag = { attr: attrs.state, indent: cp.pendingTag.indent };
1156
1096
  skipTagScan = true;
1157
1097
  } else {
1158
1098
  for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
1159
1099
  cp.pendingTruncatedCloses = [];
1160
- cp.tagAcrossLines = false;
1161
- cp.tagAcrossLinesState = "outside";
1100
+ cp.pendingTag = null;
1162
1101
  tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
1163
1102
  }
1164
1103
  }
@@ -1168,38 +1107,49 @@ ${cont(scanText)}` };
1168
1107
  let m;
1169
1108
  let lastCommentOpenerIdx = -1;
1170
1109
  while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
1171
- if (cp.rawTextOpen !== null && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) {
1172
- if (cp.rawTextOpen === "script" && m[0] === "<!--") cp.scriptDataEscaped = true;
1110
+ if (inRawTextTok(cp.p5Tok) && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) {
1111
+ if (cp.p5Tok.kind === "script") {
1112
+ if (m[0] === "<!--") cp.p5Tok = { ...cp.p5Tok, escaped: true };
1113
+ if (m[0] === "-->") cp.p5Tok = { ...cp.p5Tok, escaped: false };
1114
+ }
1173
1115
  continue;
1174
1116
  }
1175
1117
  if (m[0] === "<!--") {
1176
1118
  const next = tagText.slice(m.index + 4, m.index + 6);
1177
- if (cp.commentOpen) {
1178
- if (next.startsWith(">") || next === "->") cp.commentOpen = false;
1179
- else if (next === "!>" || next === "-!") poisonRawDivergence();
1119
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok)) {
1120
+ if (next.startsWith(">") || next === "->") {
1121
+ if (mdHtml(cp.mdBlock, 2)) cp.mdBlock = { kind: "none" };
1122
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1123
+ } else if (next === "!>" || next === "-!") {
1124
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1125
+ poisonRawDivergence();
1126
+ }
1180
1127
  continue;
1181
1128
  }
1182
1129
  if (next.startsWith(">") || next === "->") {
1183
1130
  continue;
1184
1131
  }
1185
- cp.commentOpen = true;
1132
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 2 };
1133
+ if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "comment" };
1186
1134
  lastCommentOpenerIdx = m.index;
1187
1135
  continue;
1188
1136
  }
1189
1137
  if (m[0] === "-->") {
1190
- cp.commentOpen = false;
1138
+ if (mdHtml(cp.mdBlock, 2)) cp.mdBlock = { kind: "none" };
1139
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1191
1140
  continue;
1192
1141
  }
1193
1142
  if (m[0] === "--!>") {
1194
- if (cp.commentOpen) poisonRawDivergence();
1143
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok)) poisonRawDivergence();
1144
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1195
1145
  continue;
1196
1146
  }
1197
- if (cp.commentOpen) continue;
1147
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok)) continue;
1198
1148
  const closing = m[1] === "/";
1199
1149
  const tag = m[2].toLowerCase();
1200
1150
  if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
1201
1151
  let attrs = m[3] ?? "";
1202
- if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
1152
+ if (cp.mdBlock.kind === "html" && (!inRawTextTok(cp.p5Tok) || closing && tag === rawTextElement(cp.p5Tok))) {
1203
1153
  const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
1204
1154
  const st = { state: "outside" };
1205
1155
  const gt = scanTagAttrs(tagText, attrStart, tagText.length, st);
@@ -1209,9 +1159,7 @@ ${cont(scanText)}` };
1209
1159
  else applyTag(tag, false);
1210
1160
  }
1211
1161
  scanTagAttrs("\n", 0, 1, st);
1212
- cp.tagAcrossLines = true;
1213
- cp.tagAcrossLinesIndent = ln.indent;
1214
- cp.tagAcrossLinesState = st.state;
1162
+ cp.pendingTag = { attr: st.state, indent: ln.indent };
1215
1163
  tagHandledAsTruncated = true;
1216
1164
  break;
1217
1165
  }
@@ -1220,16 +1168,15 @@ ${cont(scanText)}` };
1220
1168
  TAG_OR_COMMENT_RE.lastIndex = gt + 1;
1221
1169
  }
1222
1170
  }
1223
- if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) {
1171
+ if (closing && cp.mdBlock.kind !== "html" && !/^\s*$/.test(attrs)) {
1224
1172
  TAG_OR_COMMENT_RE.lastIndex = m.index + 2 + m[2].length;
1225
1173
  continue;
1226
1174
  }
1227
1175
  const selfClosing = /\/\s*$/.test(attrs);
1228
- noteBreakout(tag, closing);
1229
1176
  if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
1230
1177
  applyTag(tag, closing);
1231
1178
  }
1232
- if (cp.commentOpen && lastCommentOpenerIdx !== -1) {
1179
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok) && lastCommentOpenerIdx !== -1) {
1233
1180
  if (!isMdBlank(tagText.slice(0, lastCommentOpenerIdx)) || ln.indent > 3) {
1234
1181
  cp.phasePoisonedAt = 0;
1235
1182
  }
@@ -1242,13 +1189,12 @@ ${cont(scanText)}` };
1242
1189
  if (mr[0] === "<!--" || mr[0] === "-->" || mr[0] === "--!>") continue;
1243
1190
  const startMasked = masked[mr.index] !== ln.text[mr.index];
1244
1191
  const wholeVisible = masked.slice(mr.index, mr.index + mr[0].length) === mr[0];
1245
- if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
1192
+ if (startMasked || wholeVisible || inRaw(mr.index) || commentEitherOpen(cp.mdBlock, cp.p5Tok)) continue;
1246
1193
  const closing = mr[1] === "/";
1247
1194
  const tag = mr[2].toLowerCase();
1248
1195
  if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
1249
1196
  if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
1250
1197
  const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
1251
- noteBreakout(tag, closing);
1252
1198
  if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
1253
1199
  applyTag(tag, closing);
1254
1200
  }
@@ -1259,7 +1205,7 @@ ${cont(scanText)}` };
1259
1205
  }
1260
1206
  cp.pendingTruncatedTags = [];
1261
1207
  }
1262
- if (!cp.commentOpen && !tagHandledAsTruncated) {
1208
+ if (!commentEitherOpen(cp.mdBlock, cp.p5Tok) && !tagHandledAsTruncated) {
1263
1209
  let lastLt = -1;
1264
1210
  TAG_START_LT_RE.lastIndex = 0;
1265
1211
  for (let ms = TAG_START_LT_RE.exec(tagText); ms !== null; ms = TAG_START_LT_RE.exec(tagText)) {
@@ -1271,18 +1217,16 @@ ${cont(scanText)}` };
1271
1217
  if (m2) {
1272
1218
  const closing = m2[1] === "/";
1273
1219
  const tag = m2[2].toLowerCase();
1274
- if (strayTablePart(tag) && cp.htmlFlowReal) {
1220
+ if (strayTablePart(tag) && cp.mdBlock.kind === "html") {
1275
1221
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
1276
1222
  }
1277
- if (cp.htmlFlowReal) {
1278
- cp.tagAcrossLines = true;
1279
- cp.tagAcrossLinesIndent = ln.indent;
1223
+ if (cp.mdBlock.kind === "html") {
1280
1224
  const attrs = { state: "outside" };
1281
1225
  scanTagAttrs(m2[3] + "\n", 0, m2[3].length + 1, attrs);
1282
- cp.tagAcrossLinesState = attrs.state;
1226
+ cp.pendingTag = { attr: attrs.state, indent: ln.indent };
1283
1227
  }
1284
1228
  if (closing) {
1285
- if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
1229
+ if (!VOID_TAGS.has(tag) && cp.mdBlock.kind === "html") cp.pendingTruncatedCloses.push(tag);
1286
1230
  } else if (!VOID_TAGS.has(tag)) {
1287
1231
  applyTag(tag, closing);
1288
1232
  const rawLastLt = ln.text.lastIndexOf("<");
@@ -1303,21 +1247,20 @@ ${cont(scanText)}` };
1303
1247
  }
1304
1248
  masked2 += scanText.slice(cursor);
1305
1249
  if (floatingResidue(masked2, commentOpenAtLineStart).length > 0) {
1306
- cp.htmlSeamPending = true;
1250
+ cp.p5SealPending = true;
1307
1251
  }
1308
1252
  }
1309
- if (cp.rawTextOpen !== null && cp.rawTextInline) {
1253
+ if (inRawTextTok(cp.p5Tok) && cp.p5Tok.openedInline) {
1310
1254
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1311
1255
  }
1312
- if (cp.type1FlowOpen && TYPE1_CLOSE_RE.test(ln.text)) {
1313
- cp.type1FlowOpen = false;
1314
- cp.htmlFlowSinceBlank = false;
1315
- cp.htmlFlowReal = false;
1256
+ if (mdHtml(cp.mdBlock, 1) && TYPE1_CLOSE_RE.test(ln.text)) {
1257
+ cp.mdBlock = { kind: "none" };
1258
+ cp.mayBeRawToMicromark = false;
1316
1259
  }
1317
1260
  cp.blankRun = 0;
1318
1261
  cp.prevLineBlank = false;
1319
1262
  cp.prevLineWasText = true;
1320
- cp.prevLineWasValidDef = validDef && !def[1].startsWith("^");
1263
+ cp.prevLineWasValidDef = validLinkDef;
1321
1264
  }
1322
1265
 
1323
1266
  // src/components/incrementalParse/spliceParse.ts