@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.
package/dist/index.js CHANGED
@@ -174,7 +174,199 @@ var defaultUrlTransform = (value) => {
174
174
 
175
175
  // src/components/incrementalParse/computeFreezeBoundary.ts
176
176
  import { htmlBlockNames } from "micromark-util-html-tag-name";
177
+
178
+ // src/components/incrementalParse/mdLineText.ts
179
+ var MD_BLANK_RE = /^[ \t\r]*$/;
180
+ var isMdBlank = (text) => MD_BLANK_RE.test(text);
181
+ var mdTrim = (text) => text.replace(/^[ \t\r]+|[ \t\r]+$/g, "");
182
+ var mdTrimStart = (text) => text.replace(/^[ \t\r]+/, "");
183
+
184
+ // src/components/incrementalParse/referenceTaint.ts
177
185
  import { normalizeIdentifier } from "micromark-util-normalize-identifier";
186
+ var FOOTNOTE_DEF_RE = /^ {0,3}\[\^[^\]]*\]:/;
187
+ var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
188
+ var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
189
+ function firstUnescaped(text, ch) {
190
+ for (let i = 0; i < text.length; i++) {
191
+ if (text[i] === "\\") i += 1;
192
+ else if (text[i] === ch) return i;
193
+ }
194
+ return -1;
195
+ }
196
+ function lastUnclosedBracket(text) {
197
+ let open = -1;
198
+ for (let i = 0; i < text.length; i++) {
199
+ const c = text[i];
200
+ if (c === "\\") i += 1;
201
+ else if (c === "[") open = i;
202
+ else if (c === "]") open = -1;
203
+ }
204
+ return open;
205
+ }
206
+ function normalizeLabel(label) {
207
+ const collapsed = label.replace(/[ \t\r\n]+/g, " ").replace(/^ | $/g, "");
208
+ return collapsed ? normalizeIdentifier(collapsed) : "";
209
+ }
210
+ function isPlausibleLinkDefRest(rest) {
211
+ const t = mdTrim(rest);
212
+ if (t === "") return false;
213
+ const destEnd = linkDestinationEnd(t);
214
+ if (destEnd === -1) return false;
215
+ const after = mdTrim(t.slice(destEnd));
216
+ if (after === "") return true;
217
+ const opener = after[0];
218
+ if (opener !== '"' && opener !== "'" && opener !== "(") return false;
219
+ const closer = opener === "(" ? ")" : opener;
220
+ for (let i = 1; i < after.length; i++) {
221
+ if (after[i] === "\\") {
222
+ i += 1;
223
+ continue;
224
+ }
225
+ if (after[i] === closer) return isMdBlank(after.slice(i + 1));
226
+ }
227
+ return false;
228
+ }
229
+ function linkDestinationEnd(t) {
230
+ if (t.startsWith("<")) {
231
+ for (let i2 = 1; i2 < t.length; i2++) {
232
+ const ch = t[i2];
233
+ if (ch === "\\" && (t[i2 + 1] === "<" || t[i2 + 1] === ">" || t[i2 + 1] === "\\")) {
234
+ i2 += 1;
235
+ continue;
236
+ }
237
+ if (ch === ">") return i2 + 1;
238
+ if (ch === "<") return -1;
239
+ }
240
+ return -1;
241
+ }
242
+ let balance = 0;
243
+ let i = 0;
244
+ for (; i < t.length; i++) {
245
+ const code = t.charCodeAt(i);
246
+ if (code === 32 || code === 9) break;
247
+ if (code < 32 || code === 127) return -1;
248
+ const ch = t[i];
249
+ if (ch === "\\" && (t[i + 1] === "(" || t[i + 1] === ")" || t[i + 1] === "\\")) {
250
+ i += 1;
251
+ continue;
252
+ }
253
+ if (ch === "(") balance += 1;
254
+ else if (ch === ")") {
255
+ if (balance === 0) break;
256
+ balance -= 1;
257
+ }
258
+ }
259
+ if (balance !== 0 || i === 0) return -1;
260
+ return i;
261
+ }
262
+ function inlineResourceEnd(text, openIdx) {
263
+ let i = openIdx + 1;
264
+ const skipWs = () => {
265
+ while (i < text.length && (text[i] === " " || text[i] === " ")) i += 1;
266
+ };
267
+ skipWs();
268
+ if (text[i] === ")") return i + 1;
269
+ const destEnd = linkDestinationEnd(text.slice(i));
270
+ if (destEnd === -1) return -1;
271
+ i += destEnd;
272
+ const beforeWs = i;
273
+ skipWs();
274
+ if (text[i] === ")") return i + 1;
275
+ if (i === beforeWs) return -1;
276
+ const opener = text[i];
277
+ if (opener !== '"' && opener !== "'" && opener !== "(") return -1;
278
+ const closer = opener === "(" ? ")" : opener;
279
+ for (i += 1; i < text.length; i++) {
280
+ if (text[i] === "\\") {
281
+ i += 1;
282
+ continue;
283
+ }
284
+ if (text[i] === closer) {
285
+ i += 1;
286
+ skipWs();
287
+ return text[i] === ")" ? i + 1 : -1;
288
+ }
289
+ }
290
+ return -1;
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;
295
+ const defLineStart = isBlockStart || !cp.prevLineWasText || cp.prevLineWasValidDef;
296
+ const validDef = def !== null && defLineStart;
297
+ if (validDef) {
298
+ const label = def[1];
299
+ if (label.startsWith("^")) {
300
+ const key = normalizeLabel(label.slice(1));
301
+ if (key && !cp.footnoteDefs.has(key)) cp.footnoteDefs.set(key, lnEnd);
302
+ } else {
303
+ const key = normalizeLabel(label);
304
+ if (key && !cp.defs.has(key)) cp.defs.set(key, lnEnd);
305
+ }
306
+ }
307
+ if (cp.referenceTaint) {
308
+ const pushRef = (offset, inner, followAt) => {
309
+ const follow = scanText[followAt];
310
+ if (follow === "(" && inlineResourceEnd(scanText, followAt) !== -1) return;
311
+ let label;
312
+ let footnote = false;
313
+ if (inner.startsWith("^")) {
314
+ footnote = true;
315
+ label = normalizeLabel(inner.slice(1));
316
+ } else if (follow === "[") {
317
+ const explicit = /^\[((?:[^[\]\\]|\\.)*)\]/.exec(scanText.slice(followAt));
318
+ label = normalizeLabel(explicit && explicit[1] ? explicit[1] : inner);
319
+ } else {
320
+ label = normalizeLabel(inner);
321
+ }
322
+ if (label) cp.unresolvedRefs.push({ offset, label, footnote });
323
+ };
324
+ const pending = cp.openBracket;
325
+ cp.openBracket = null;
326
+ if (pending) {
327
+ const close = firstUnescaped(scanText, "]");
328
+ const open = firstUnescaped(scanText, "[");
329
+ const cont = (t) => t.replace(/^ {0,3}>[ \t]?/, "");
330
+ if (close !== -1 && (open === -1 || close < open)) {
331
+ pushRef(pending.offset, `${pending.text}
332
+ ${cont(scanText.slice(0, close))}`, close + 1);
333
+ } else if (close === -1 && open === -1) {
334
+ cp.openBracket = { offset: pending.offset, text: `${pending.text}
335
+ ${cont(scanText)}` };
336
+ }
337
+ }
338
+ if (scanText.includes("[")) {
339
+ const defBracket = validDef ? def.index + def[0].indexOf("[") : -1;
340
+ REF_RE.lastIndex = 0;
341
+ let m;
342
+ while ((m = REF_RE.exec(scanText)) !== null) {
343
+ const followAt = m.index + m[0].length;
344
+ if (scanText[followAt] === ":" && m.index === defBracket) continue;
345
+ pushRef(lnStart + m.index, m[1], followAt);
346
+ }
347
+ const trailingOpen = lastUnclosedBracket(scanText);
348
+ if (trailingOpen !== -1) {
349
+ cp.openBracket = { offset: lnStart + trailingOpen, text: scanText.slice(trailingOpen + 1) };
350
+ }
351
+ }
352
+ }
353
+ return { validDef, validLinkDef: validDef && !def[1].startsWith("^") };
354
+ }
355
+ function settleRefsAndEarliestUnresolved(cp) {
356
+ if (cp.unresolvedRefs.length > 0) {
357
+ const settled = (defEnd) => cp.lastBlankStart >= defEnd;
358
+ cp.unresolvedRefs = cp.unresolvedRefs.filter((ref) => {
359
+ const table = ref.footnote ? cp.footnoteDefs : cp.defs;
360
+ const defEnd = table.get(ref.label);
361
+ return defEnd === void 0 || !settled(defEnd);
362
+ });
363
+ }
364
+ let earliestUnresolved = Infinity;
365
+ for (const ref of cp.unresolvedRefs) earliestUnresolved = Math.min(earliestUnresolved, ref.offset);
366
+ return earliestUnresolved;
367
+ }
368
+
369
+ // src/components/incrementalParse/computeFreezeBoundary.ts
178
370
  var TYPE6_NAMES = new Set(htmlBlockNames);
179
371
  var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
180
372
  var DOCUMENT_STRUCTURE_NAMES = /* @__PURE__ */ new Set(["html", "head", "body", "frameset"]);
@@ -197,53 +389,6 @@ function tailCarriesRetroactive(text) {
197
389
  }
198
390
  return false;
199
391
  }
200
- var HTML_BREAKOUT_TAGS = /* @__PURE__ */ new Set([
201
- "b",
202
- "big",
203
- "blockquote",
204
- "body",
205
- "br",
206
- "center",
207
- "code",
208
- "dd",
209
- "div",
210
- "dl",
211
- "dt",
212
- "em",
213
- "embed",
214
- "h1",
215
- "h2",
216
- "h3",
217
- "h4",
218
- "h5",
219
- "h6",
220
- "head",
221
- "hr",
222
- "i",
223
- "img",
224
- "li",
225
- "listing",
226
- "menu",
227
- "meta",
228
- "nobr",
229
- "ol",
230
- "p",
231
- "pre",
232
- "ruby",
233
- "s",
234
- "small",
235
- "span",
236
- "strong",
237
- "strike",
238
- "sub",
239
- "sup",
240
- "table",
241
- "tt",
242
- "u",
243
- "ul",
244
- "var"
245
- ]);
246
- var HTML_INTEGRATION_POINTS = ["foreignobject", "desc", "title", "mi", "mo", "mn", "ms", "mtext", "annotation-xml"];
247
392
  var SCOPE_BARRIER_NAMES = /* @__PURE__ */ new Set([
248
393
  "applet",
249
394
  "caption",
@@ -286,6 +431,11 @@ var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
286
431
  var TYPE1_CLOSE_RE = /<\/(?:script|pre|style|textarea)>/i;
287
432
  var TYPE7_LINE_RE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\r][^>]*|\/)?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\r]*>)[ \t\r]*$/;
288
433
  var t7Name = (line) => /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(line)[1];
434
+ var mdHtml = (b, type) => b.kind === "html" && b.type === type;
435
+ var mdHtml25 = (b) => b.kind === "html" && b.type >= 2 && b.type <= 5;
436
+ var commentEitherOpen = (md, p5) => mdHtml(md, 2) || p5.kind === "comment";
437
+ var inRawTextTok = (t) => t.kind === "rawText" || t.kind === "script";
438
+ var rawTextElement = (t) => t.kind === "rawText" ? t.element : t.kind === "script" ? "script" : null;
289
439
  var VOID_TAGS = /* @__PURE__ */ new Set([
290
440
  "area",
291
441
  "base",
@@ -303,9 +453,7 @@ var VOID_TAGS = /* @__PURE__ */ new Set([
303
453
  "wbr"
304
454
  ]);
305
455
  var LIST_MARKER_RE = /^ {0,3}(?:[-*+]|\d{1,9}[.)])(?:[ \t]|$)/;
306
- var FOOTNOTE_DEF_RE = /^ {0,3}\[\^[^\]]*\]:/;
307
456
  var DEF_LIST_DD_RE = /^ {0,3}:[ \t]/;
308
- var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
309
457
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
310
458
  var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
311
459
  var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
@@ -338,12 +486,7 @@ function scanTagAttrs(text, from, to, out) {
338
486
  out.state = st;
339
487
  return -1;
340
488
  }
341
- var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
342
489
  var BACKTICK_RUN_RE = /`+/g;
343
- var MD_BLANK_RE = /^[ \t\r]*$/;
344
- var isMdBlank = (text) => MD_BLANK_RE.test(text);
345
- var mdTrim = (text) => text.replace(/^[ \t\r]+|[ \t\r]+$/g, "");
346
- var mdTrimStart = (text) => text.replace(/^[ \t\r]+/, "");
347
490
  function computeIndent(text) {
348
491
  let indent = 0;
349
492
  for (const ch of text) {
@@ -353,27 +496,6 @@ function computeIndent(text) {
353
496
  }
354
497
  return indent;
355
498
  }
356
- function firstUnescaped(text, ch) {
357
- for (let i = 0; i < text.length; i++) {
358
- if (text[i] === "\\") i += 1;
359
- else if (text[i] === ch) return i;
360
- }
361
- return -1;
362
- }
363
- function lastUnclosedBracket(text) {
364
- let open = -1;
365
- for (let i = 0; i < text.length; i++) {
366
- const c = text[i];
367
- if (c === "\\") i += 1;
368
- else if (c === "[") open = i;
369
- else if (c === "]") open = -1;
370
- }
371
- return open;
372
- }
373
- function normalizeLabel(label) {
374
- const collapsed = label.replace(/[ \t\r\n]+/g, " ").replace(/^ | $/g, "");
375
- return collapsed ? normalizeIdentifier(collapsed) : "";
376
- }
377
499
  function canBecomeDdLine(text, confirmed) {
378
500
  let i = 0;
379
501
  while (i < text.length && text[i] === " ") i += 1;
@@ -430,20 +552,9 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
430
552
  unresolvedRefs: [],
431
553
  tagBalance: /* @__PURE__ */ new Map(),
432
554
  openTotal: 0,
433
- commentOpen: false,
434
- piOpen: false,
435
- bogusOpen: false,
436
- rawTextOpen: null,
555
+ p5Tok: { kind: "data" },
437
556
  openStack: [],
438
- scriptDataEscaped: false,
439
- declOpen: false,
440
- cdataOpen: false,
441
- inFence: false,
442
- fenceChar: "",
443
- fenceLen: 0,
444
- inMath: false,
445
- mathFenceLen: 0,
446
- openIndent: 0,
557
+ mdBlock: { kind: "none" },
447
558
  blankRun: 0,
448
559
  lastBlankStart: -1,
449
560
  hazardVerdict: false,
@@ -453,100 +564,13 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
453
564
  prevLineWasValidDef: false,
454
565
  paragraphHasUnpairedRun: false,
455
566
  openBracket: null,
456
- htmlFlowSinceBlank: false,
457
- htmlSeamPending: false,
567
+ mayBeRawToMicromark: false,
568
+ p5SealPending: false,
458
569
  phasePoisonedAt: Infinity,
459
570
  pendingTruncatedTags: [],
460
571
  pendingTruncatedCloses: [],
461
- tagAcrossLines: false,
462
- tagAcrossLinesIndent: 0,
463
- tagAcrossLinesState: "outside",
464
- htmlFlowReal: false,
465
- type1FlowOpen: false,
466
- rawTextInline: false
467
- };
468
- }
469
- function isPlausibleLinkDefRest(rest) {
470
- const t = mdTrim(rest);
471
- if (t === "") return false;
472
- const destEnd = linkDestinationEnd(t);
473
- if (destEnd === -1) return false;
474
- const after = mdTrim(t.slice(destEnd));
475
- if (after === "") return true;
476
- const opener = after[0];
477
- if (opener !== '"' && opener !== "'" && opener !== "(") return false;
478
- const closer = opener === "(" ? ")" : opener;
479
- for (let i = 1; i < after.length; i++) {
480
- if (after[i] === "\\") {
481
- i += 1;
482
- continue;
483
- }
484
- if (after[i] === closer) return isMdBlank(after.slice(i + 1));
485
- }
486
- return false;
487
- }
488
- function linkDestinationEnd(t) {
489
- if (t.startsWith("<")) {
490
- for (let i2 = 1; i2 < t.length; i2++) {
491
- const ch = t[i2];
492
- if (ch === "\\" && (t[i2 + 1] === "<" || t[i2 + 1] === ">" || t[i2 + 1] === "\\")) {
493
- i2 += 1;
494
- continue;
495
- }
496
- if (ch === ">") return i2 + 1;
497
- if (ch === "<") return -1;
498
- }
499
- return -1;
500
- }
501
- let balance = 0;
502
- let i = 0;
503
- for (; i < t.length; i++) {
504
- const code = t.charCodeAt(i);
505
- if (code === 32 || code === 9) break;
506
- if (code < 32 || code === 127) return -1;
507
- const ch = t[i];
508
- if (ch === "\\" && (t[i + 1] === "(" || t[i + 1] === ")" || t[i + 1] === "\\")) {
509
- i += 1;
510
- continue;
511
- }
512
- if (ch === "(") balance += 1;
513
- else if (ch === ")") {
514
- if (balance === 0) break;
515
- balance -= 1;
516
- }
517
- }
518
- if (balance !== 0 || i === 0) return -1;
519
- return i;
520
- }
521
- function inlineResourceEnd(text, openIdx) {
522
- let i = openIdx + 1;
523
- const skipWs = () => {
524
- while (i < text.length && (text[i] === " " || text[i] === " ")) i += 1;
572
+ pendingTag: null
525
573
  };
526
- skipWs();
527
- if (text[i] === ")") return i + 1;
528
- const destEnd = linkDestinationEnd(text.slice(i));
529
- if (destEnd === -1) return -1;
530
- i += destEnd;
531
- const beforeWs = i;
532
- skipWs();
533
- if (text[i] === ")") return i + 1;
534
- if (i === beforeWs) return -1;
535
- const opener = text[i];
536
- if (opener !== '"' && opener !== "'" && opener !== "(") return -1;
537
- const closer = opener === "(" ? ")" : opener;
538
- for (i += 1; i < text.length; i++) {
539
- if (text[i] === "\\") {
540
- i += 1;
541
- continue;
542
- }
543
- if (text[i] === closer) {
544
- i += 1;
545
- skipWs();
546
- return text[i] === ")" ? i + 1 : -1;
547
- }
548
- }
549
- return -1;
550
574
  }
551
575
  function classifyBlockStart(text, indent, defListEnabled) {
552
576
  if (indent >= 4) return true;
@@ -593,16 +617,7 @@ function computeFreezeBoundary(text, options, resume) {
593
617
  cp.confirmedOffset = end + 1;
594
618
  start = end + 1;
595
619
  }
596
- if (cp.unresolvedRefs.length > 0) {
597
- const settled = (defEnd) => cp.lastBlankStart >= defEnd;
598
- cp.unresolvedRefs = cp.unresolvedRefs.filter((ref) => {
599
- const table = ref.footnote ? cp.footnoteDefs : cp.defs;
600
- const defEnd = table.get(ref.label);
601
- return defEnd === void 0 || !settled(defEnd);
602
- });
603
- }
604
- let earliestUnresolved = Infinity;
605
- for (const ref of cp.unresolvedRefs) earliestUnresolved = Math.min(earliestUnresolved, ref.offset);
620
+ const earliestUnresolved = settleRefsAndEarliestUnresolved(cp);
606
621
  const defListSettled = (c) => {
607
622
  if (!options.defListEnabled || c.blankRun >= 2) return true;
608
623
  if (c.defListSettled !== null) return c.defListSettled;
@@ -625,9 +640,8 @@ function computeFreezeBoundary(text, options, resume) {
625
640
  function pendingFenceCloser(checkpoint) {
626
641
  const cp = checkpoint;
627
642
  if (cp.phasePoisonedAt !== Infinity) return "";
628
- if (cp.openIndent !== 0) return "";
629
- if (cp.inFence) return cp.fenceChar.repeat(cp.fenceLen);
630
- if (cp.inMath) return "$".repeat(cp.mathFenceLen);
643
+ if (cp.mdBlock.kind === "fence" && cp.mdBlock.indent === 0) return cp.mdBlock.char.repeat(cp.mdBlock.len);
644
+ if (cp.mdBlock.kind === "math" && cp.mdBlock.indent === 0) return "$".repeat(cp.mdBlock.len);
631
645
  return "";
632
646
  }
633
647
  function floatingResidue(text, commentOpenAtStart) {
@@ -678,53 +692,30 @@ function processConfirmedLine(cp, ln, text) {
678
692
  newest.defListSettled = ln.blank ? true : !canBecomeDdLine(ln.text, true);
679
693
  }
680
694
  const isBlockStart = cp.prevLineBlank;
681
- if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen)) {
695
+ if (cp.p5SealPending && !ln.blank && !cp.mayBeRawToMicromark && !(mdHtml25(cp.mdBlock) || cp.p5Tok.kind === "comment" || cp.p5Tok.kind === "bogus")) {
682
696
  const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
683
697
  const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
684
698
  if (!defShapedLine && !commentOnly) {
685
- cp.htmlSeamPending = false;
699
+ cp.p5SealPending = false;
686
700
  }
687
701
  }
688
- const inForeignContent = () => FOREIGN_ROOT_NAMES.some((name) => (cp.tagBalance.get(name) ?? 0) > 0);
689
- const honoursSelfClosing = (tag) => {
690
- if (tag === "svg" || tag === "math") return true;
691
- if (!inForeignContent() || HTML_BREAKOUT_TAGS.has(tag)) return false;
692
- for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return false;
693
- return true;
694
- };
695
- const htmlRulesApply = () => {
696
- if (!inForeignContent()) return true;
697
- for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return true;
698
- return false;
699
- };
700
- const popForeignRoots = () => {
701
- for (const name of FOREIGN_ROOT_NAMES) {
702
- const count = cp.tagBalance.get(name) ?? 0;
703
- if (count > 0) {
704
- cp.tagBalance.set(name, 0);
705
- cp.openTotal -= count;
706
- }
707
- }
708
- if (cp.openStack.length > 0) cp.openStack = cp.openStack.filter((n) => !FOREIGN_ROOT_NAMES.includes(n));
709
- };
710
- const noteBreakout = (tag, closing) => {
711
- if (closing || cp.rawTextOpen !== null) return;
712
- if (HTML_BREAKOUT_TAGS.has(tag) && !htmlRulesApply()) popForeignRoots();
713
- };
702
+ const possiblyInsideForeign = () => FOREIGN_ROOT_NAMES.some((name) => (cp.tagBalance.get(name) ?? 0) > 0);
703
+ const honoursSelfClosing = (tag) => tag === "svg" || tag === "math";
704
+ const foreignRawTextSwitchUnknowable = () => possiblyInsideForeign();
714
705
  const applyTag = (tag, closing) => {
715
- if (cp.rawTextOpen !== null) {
716
- if (cp.scriptDataEscaped && !closing && tag === "script") {
706
+ if (inRawTextTok(cp.p5Tok)) {
707
+ if (cp.p5Tok.kind === "script" && cp.p5Tok.escaped && !closing && tag === "script") {
717
708
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
718
709
  }
719
- if (!(closing && tag === cp.rawTextOpen)) return;
720
- cp.rawTextOpen = null;
721
- cp.scriptDataEscaped = false;
710
+ if (!(closing && tag === rawTextElement(cp.p5Tok))) return;
711
+ cp.p5Tok = { kind: "data" };
722
712
  } else {
723
- noteBreakout(tag, closing);
724
- if (!closing && RAW_TEXT_ELEMENTS.has(tag) && htmlRulesApply()) {
725
- cp.rawTextOpen = tag;
726
- cp.scriptDataEscaped = false;
727
- cp.rawTextInline = !cp.htmlFlowReal;
713
+ if (!closing && RAW_TEXT_ELEMENTS.has(tag) && foreignRawTextSwitchUnknowable()) {
714
+ cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
715
+ } else if (!closing && RAW_TEXT_ELEMENTS.has(tag)) {
716
+ if (cp.p5Tok.kind !== "data") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
717
+ const openedInline = cp.mdBlock.kind !== "html";
718
+ cp.p5Tok = tag === "script" ? { kind: "script", escaped: false, openedInline } : { kind: "rawText", element: tag, openedInline };
728
719
  if (tag === "plaintext") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
729
720
  }
730
721
  }
@@ -752,15 +743,14 @@ function processConfirmedLine(cp, ln, text) {
752
743
  cp.openTotal += 1;
753
744
  }
754
745
  };
755
- const strayTablePart = (tag) => TABLE_PART_NAMES.has(tag) && (cp.tagBalance.get("table") ?? 0) === 0;
756
- const commentOpenAtLineStart = cp.commentOpen;
757
- const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
758
- if (cp.inFence) {
746
+ const definitelyInsideTable = () => (cp.tagBalance.get("table") ?? 0) > 0;
747
+ const strayTablePart = (tag) => TABLE_PART_NAMES.has(tag) && !definitelyInsideTable();
748
+ const commentOpenAtLineStart = commentEitherOpen(cp.mdBlock, cp.p5Tok);
749
+ const rawOpenAtLineStart = mdHtml25(cp.mdBlock) || cp.p5Tok.kind === "comment" || cp.p5Tok.kind === "bogus";
750
+ if (cp.mdBlock.kind === "fence") {
759
751
  const close = FENCE_RE.exec(ln.text);
760
- if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
761
- cp.inFence = false;
762
- cp.fenceChar = "";
763
- cp.fenceLen = 0;
752
+ if (close && close[1][0] === cp.mdBlock.char && close[1].length >= cp.mdBlock.len && isMdBlank(ln.text.slice(close[0].length))) {
753
+ cp.mdBlock = { kind: "none" };
764
754
  }
765
755
  cp.blankRun = 0;
766
756
  cp.paragraphHasUnpairedRun = false;
@@ -770,20 +760,17 @@ function processConfirmedLine(cp, ln, text) {
770
760
  cp.prevLineWasValidDef = false;
771
761
  return;
772
762
  }
773
- if (!cp.inMath && !rawOpenAtLineStart) {
763
+ if (cp.mdBlock.kind !== "math" && !rawOpenAtLineStart) {
774
764
  const open = FENCE_RE.exec(ln.text);
775
765
  const bogusInfo = open !== null && open[1][0] === "`" && ln.text.slice(ln.text.indexOf(open[1]) + open[1].length).includes("`");
776
- if (open && !bogusInfo && cp.htmlFlowSinceBlank) {
766
+ if (open && !bogusInfo && cp.mayBeRawToMicromark) {
777
767
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
778
768
  } else if (open && !bogusInfo) {
779
769
  if (isBlockStart) {
780
770
  const verdict = classifyBlockStart(ln.text, ln.indent, cp.defListEnabled);
781
771
  if (verdict !== null) cp.hazardVerdict = verdict;
782
772
  }
783
- cp.inFence = true;
784
- cp.fenceChar = open[1][0];
785
- cp.fenceLen = open[1].length;
786
- cp.openIndent = ln.indent;
773
+ cp.mdBlock = { kind: "fence", char: open[1][0], len: open[1].length, indent: ln.indent };
787
774
  cp.blankRun = 0;
788
775
  cp.paragraphHasUnpairedRun = false;
789
776
  cp.openBracket = null;
@@ -793,11 +780,10 @@ function processConfirmedLine(cp, ln, text) {
793
780
  return;
794
781
  }
795
782
  }
796
- if (cp.inMath) {
783
+ if (cp.mdBlock.kind === "math") {
797
784
  const close = MATH_RUN_RE.exec(ln.text);
798
- if (close && close[1].length >= cp.mathFenceLen && isMdBlank(ln.text.slice(close[0].length))) {
799
- cp.inMath = false;
800
- cp.mathFenceLen = 0;
785
+ if (close && close[1].length >= cp.mdBlock.len && isMdBlank(ln.text.slice(close[0].length))) {
786
+ cp.mdBlock = { kind: "none" };
801
787
  }
802
788
  cp.blankRun = 0;
803
789
  cp.paragraphHasUnpairedRun = false;
@@ -811,16 +797,14 @@ function processConfirmedLine(cp, ln, text) {
811
797
  if (mathRun) {
812
798
  const rest = ln.text.slice(ln.text.indexOf(mathRun[1]) + mathRun[1].length);
813
799
  if (!rest.includes("$")) {
814
- if (cp.htmlFlowSinceBlank) {
800
+ if (cp.mayBeRawToMicromark) {
815
801
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
816
802
  } else {
817
803
  if (isBlockStart) {
818
804
  const verdict = classifyBlockStart(ln.text, ln.indent, cp.defListEnabled);
819
805
  if (verdict !== null) cp.hazardVerdict = verdict;
820
806
  }
821
- cp.inMath = true;
822
- cp.mathFenceLen = mathRun[1].length;
823
- cp.openIndent = ln.indent;
807
+ cp.mdBlock = { kind: "math", len: mathRun[1].length, indent: ln.indent };
824
808
  cp.blankRun = 0;
825
809
  cp.paragraphHasUnpairedRun = false;
826
810
  cp.openBracket = null;
@@ -837,36 +821,36 @@ function processConfirmedLine(cp, ln, text) {
837
821
  cp.pendingTruncatedTags = [];
838
822
  }
839
823
  cp.pendingTruncatedCloses = [];
840
- if (cp.tagAcrossLines && (cp.tagAcrossLinesState === '"' || cp.tagAcrossLinesState === "'")) {
824
+ if (cp.pendingTag !== null && (cp.pendingTag.attr === '"' || cp.pendingTag.attr === "'")) {
841
825
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
842
826
  }
843
- cp.tagAcrossLines = false;
844
- cp.tagAcrossLinesState = "outside";
845
- if (cp.bogusOpen) {
827
+ cp.pendingTag = null;
828
+ if (cp.p5Tok.kind === "bogus") {
846
829
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
847
- cp.bogusOpen = false;
830
+ cp.p5Tok = { kind: "data" };
848
831
  }
832
+ if (cp.mdBlock.kind === "html" && cp.mdBlock.type >= 6) cp.mdBlock = { kind: "none" };
849
833
  cp.blankRun += 1;
850
834
  cp.lastBlankStart = ln.start;
851
835
  cp.candidates.push({
852
836
  offset: Math.min(ln.end + 1, text.length),
853
837
  blankRun: cp.blankRun,
854
- // `type1FlowOpen`: an unterminated type-1 block swallows this blank
855
- // and everything after it as RAW content, so nothing here is a block
856
- // boundary at all. Its tags are invisible to the balance scan
857
- // (`rawTextOpen` suppresses them), which is exactly why `openTotal`
858
- // reads 0 and the candidate looked safe.
859
- htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen && !cp.type1FlowOpen,
838
+ // The html member covers types 1-5 in one check: an unterminated
839
+ // type-1 block swallows this blank and everything after it as RAW
840
+ // content (its tags are invisible to the balance scan — the raw-text
841
+ // mask suppresses them which is exactly why `openTotal` reads 0
842
+ // and the candidate looked safe), and the 2-5 interiors are the
843
+ // same construct to both grammars.
844
+ htmlBalanced: cp.openTotal === 0 && cp.mdBlock.kind !== "html" && cp.p5Tok.kind !== "bogus",
860
845
  hazard: cp.hazardVerdict,
861
- seamRisk: cp.htmlSeamPending,
846
+ seamRisk: cp.p5SealPending,
862
847
  defListSettled: null
863
848
  });
864
849
  cp.paragraphHasUnpairedRun = false;
865
850
  cp.openBracket = null;
866
- if (!cp.type1FlowOpen) {
867
- cp.htmlFlowSinceBlank = false;
868
- cp.htmlFlowReal = false;
869
- if (cp.rawTextOpen !== null && !cp.rawTextInline) {
851
+ if (!mdHtml(cp.mdBlock, 1)) {
852
+ cp.mayBeRawToMicromark = false;
853
+ if (inRawTextTok(cp.p5Tok) && !cp.p5Tok.openedInline) {
870
854
  cp.phasePoisonedAt = 0;
871
855
  }
872
856
  }
@@ -883,86 +867,29 @@ function processConfirmedLine(cp, ln, text) {
883
867
  }
884
868
  const tagStart = ln.indent <= 3 ? /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(mdTrimStart(ln.text)) : null;
885
869
  if (tagStart) {
886
- const noRealBlockOpen = !cp.htmlFlowReal;
887
- cp.htmlFlowSinceBlank = true;
888
- if (noRealBlockOpen && TYPE1_START_RE.test(mdTrimStart(ln.text))) cp.type1FlowOpen = true;
870
+ const noRealBlockOpen = cp.mdBlock.kind !== "html";
871
+ cp.mayBeRawToMicromark = true;
872
+ if (noRealBlockOpen && TYPE1_START_RE.test(mdTrimStart(ln.text))) cp.mdBlock = { kind: "html", type: 1 };
889
873
  if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
890
- if (!cp.htmlFlowReal) {
874
+ if (cp.mdBlock.kind !== "html") {
891
875
  const t = mdTrimStart(ln.text);
892
876
  const t6 = TYPE6_START_RE.exec(t);
893
877
  const t7 = TYPE7_LINE_RE.exec(t);
894
- 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
878
+ const realT6 = t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase());
879
+ if (realT6 || TYPE1_START_RE.test(t) || // Type 7 cannot interrupt a paragraph, and excludes the raw-text
895
880
  // names (those are type 1 as start tags, paragraph as end tags).
896
881
  t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7Name(t).toLowerCase())) {
897
- cp.htmlFlowReal = true;
882
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: realT6 ? 6 : 7 };
898
883
  }
899
884
  }
900
885
  }
901
- const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
886
+ const inRawText = cp.mayBeRawToMicromark || rawOpenAtLineStart;
902
887
  const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
903
888
  const { masked, unpaired } = inRawText ? { masked: null, unpaired: false } : maskIntraLineCodeSpans(ln.text, cp.paragraphHasUnpairedRun);
904
889
  if (unpaired) cp.paragraphHasUnpairedRun = true;
905
890
  const scanText = masked ?? ln.text;
906
- const defShaped = inRawText ? null : DEF_RE.exec(scanText);
907
- const def = defShaped !== null && (defShaped[1].startsWith("^") || isPlausibleLinkDefRest(scanText.slice(defShaped.index + defShaped[0].length))) ? defShaped : null;
908
- const defLineStart = isBlockStart || !cp.prevLineWasText || cp.prevLineWasValidDef;
909
- const validDef = def !== null && defLineStart;
910
- if (validDef) {
911
- const label = def[1];
912
- if (label.startsWith("^")) {
913
- const key = normalizeLabel(label.slice(1));
914
- if (key && !cp.footnoteDefs.has(key)) cp.footnoteDefs.set(key, ln.end);
915
- } else {
916
- const key = normalizeLabel(label);
917
- if (key && !cp.defs.has(key)) cp.defs.set(key, ln.end);
918
- }
919
- }
920
- if (cp.referenceTaint) {
921
- const pushRef = (offset, inner, followAt) => {
922
- const follow = scanText[followAt];
923
- if (follow === "(" && inlineResourceEnd(scanText, followAt) !== -1) return;
924
- let label;
925
- let footnote = false;
926
- if (inner.startsWith("^")) {
927
- footnote = true;
928
- label = normalizeLabel(inner.slice(1));
929
- } else if (follow === "[") {
930
- const explicit = /^\[((?:[^[\]\\]|\\.)*)\]/.exec(scanText.slice(followAt));
931
- label = normalizeLabel(explicit && explicit[1] ? explicit[1] : inner);
932
- } else {
933
- label = normalizeLabel(inner);
934
- }
935
- if (label) cp.unresolvedRefs.push({ offset, label, footnote });
936
- };
937
- const pending = cp.openBracket;
938
- cp.openBracket = null;
939
- if (pending) {
940
- const close = firstUnescaped(scanText, "]");
941
- const open = firstUnescaped(scanText, "[");
942
- const cont = (t) => t.replace(/^ {0,3}>[ \t]?/, "");
943
- if (close !== -1 && (open === -1 || close < open)) {
944
- pushRef(pending.offset, `${pending.text}
945
- ${cont(scanText.slice(0, close))}`, close + 1);
946
- } else if (close === -1 && open === -1) {
947
- cp.openBracket = { offset: pending.offset, text: `${pending.text}
948
- ${cont(scanText)}` };
949
- }
950
- }
951
- if (scanText.includes("[")) {
952
- const defBracket = validDef ? def.index + def[0].indexOf("[") : -1;
953
- REF_RE.lastIndex = 0;
954
- let m;
955
- while ((m = REF_RE.exec(scanText)) !== null) {
956
- const followAt = m.index + m[0].length;
957
- if (scanText[followAt] === ":" && m.index === defBracket) continue;
958
- pushRef(ln.start + m.index, m[1], followAt);
959
- }
960
- const trailingOpen = lastUnclosedBracket(scanText);
961
- if (trailingOpen !== -1) {
962
- cp.openBracket = { offset: ln.start + trailingOpen, text: scanText.slice(trailingOpen + 1) };
963
- }
964
- }
965
- }
891
+ const defRawToMicromark = cp.mdBlock.kind === "html" || rawOpenAtLineStart || inRawTextTok(cp.p5Tok);
892
+ const { validLinkDef } = collectRefLine(cp, ln.start, ln.end, scanText, defRawToMicromark, isBlockStart);
966
893
  const rawSpans = [];
967
894
  let pos = 0;
968
895
  const poisonRawDivergence = () => {
@@ -970,7 +897,7 @@ ${cont(scanText)}` };
970
897
  };
971
898
  let inlineRawOpenerIdx = -1;
972
899
  while (pos < scanText.length) {
973
- if (cp.piOpen) {
900
+ if (mdHtml(cp.mdBlock, 3)) {
974
901
  const c = scanText.indexOf("?>", pos);
975
902
  const gt = scanText.indexOf(">", pos);
976
903
  if (gt !== -1 && (c === -1 || gt !== c + 1)) poisonRawDivergence();
@@ -979,11 +906,11 @@ ${cont(scanText)}` };
979
906
  break;
980
907
  }
981
908
  rawSpans.push([pos, c + 2]);
982
- cp.piOpen = false;
909
+ cp.mdBlock = { kind: "none" };
983
910
  pos = c + 2;
984
911
  continue;
985
912
  }
986
- if (cp.cdataOpen) {
913
+ if (mdHtml(cp.mdBlock, 5)) {
987
914
  const c = scanText.indexOf("]]>", pos);
988
915
  const gt = scanText.indexOf(">", pos);
989
916
  if (gt !== -1 && (c === -1 || gt !== c + 2)) poisonRawDivergence();
@@ -992,38 +919,51 @@ ${cont(scanText)}` };
992
919
  break;
993
920
  }
994
921
  rawSpans.push([pos, c + 3]);
995
- cp.cdataOpen = false;
922
+ cp.mdBlock = { kind: "none" };
996
923
  pos = c + 3;
997
924
  continue;
998
925
  }
999
- if (cp.declOpen || cp.bogusOpen) {
926
+ if (mdHtml(cp.mdBlock, 4)) {
927
+ const c = scanText.indexOf(">", pos);
928
+ if (c === -1) {
929
+ rawSpans.push([pos, scanText.length]);
930
+ break;
931
+ }
932
+ rawSpans.push([pos, c + 1]);
933
+ cp.mdBlock = { kind: "none" };
934
+ if (cp.p5Tok.kind === "bogus") cp.p5Tok = { kind: "data" };
935
+ pos = c + 1;
936
+ continue;
937
+ }
938
+ if (cp.p5Tok.kind === "bogus") {
1000
939
  const c = scanText.indexOf(">", pos);
1001
940
  if (c === -1) {
1002
941
  rawSpans.push([pos, scanText.length]);
1003
942
  break;
1004
943
  }
1005
944
  rawSpans.push([pos, c + 1]);
1006
- cp.declOpen = false;
1007
- cp.bogusOpen = false;
945
+ cp.p5Tok = { kind: "data" };
1008
946
  pos = c + 1;
1009
947
  continue;
1010
948
  }
949
+ if (commentOpenAtLineStart || inRawTextTok(cp.p5Tok) || mdHtml(cp.mdBlock, 1)) break;
1011
950
  const pi = scanText.indexOf("<?", pos);
1012
951
  const cd = scanText.indexOf("<![CDATA[", pos);
1013
952
  const dm = scanText.slice(pos).search(/<![A-Za-z]/);
1014
953
  const decl = dm === -1 ? -1 : pos + dm;
1015
- const bm = cp.htmlFlowReal ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
954
+ const bm = cp.mdBlock.kind === "html" ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
1016
955
  const bogus = bm === -1 ? -1 : pos + bm;
1017
956
  const starts = [pi, cd, decl, bogus].filter((x) => x !== -1);
1018
957
  if (starts.length === 0) break;
1019
958
  const first = Math.min(...starts);
1020
959
  if (first === bogus) {
1021
960
  rawSpans.push([bogus, bogus + 2]);
1022
- cp.bogusOpen = true;
961
+ if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "bogus" };
962
+ else cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1023
963
  pos = bogus + 2;
1024
964
  } else if (first === cd) {
1025
965
  rawSpans.push([cd, cd + 9]);
1026
- cp.cdataOpen = true;
966
+ cp.mdBlock = { kind: "html", type: 5 };
1027
967
  if (!isMdBlank(scanText.slice(0, cd)) || ln.indent > 3) inlineRawOpenerIdx = cd;
1028
968
  pos = cd + 9;
1029
969
  } else if (first === pi) {
@@ -1034,18 +974,18 @@ ${cont(scanText)}` };
1034
974
  continue;
1035
975
  }
1036
976
  rawSpans.push([pi, pi + 2]);
1037
- cp.piOpen = true;
977
+ cp.mdBlock = { kind: "html", type: 3 };
1038
978
  if (!isMdBlank(scanText.slice(0, pi)) || ln.indent > 3) inlineRawOpenerIdx = pi;
1039
979
  pos = pi + 2;
1040
980
  } else {
1041
981
  rawSpans.push([decl, decl + 2]);
1042
982
  if (ln.indent <= 3 && /^doctype/i.test(scanText.slice(decl + 2))) cp.phasePoisonedAt = 0;
1043
- cp.declOpen = true;
983
+ cp.mdBlock = { kind: "html", type: 4 };
1044
984
  if (!isMdBlank(scanText.slice(0, decl)) || ln.indent > 3) inlineRawOpenerIdx = decl;
1045
985
  pos = decl + 2;
1046
986
  }
1047
987
  }
1048
- if (inlineRawOpenerIdx !== -1 && (cp.piOpen || cp.declOpen || cp.cdataOpen)) {
988
+ if (inlineRawOpenerIdx !== -1 && cp.mdBlock.kind === "html" && cp.mdBlock.type >= 3) {
1049
989
  cp.phasePoisonedAt = 0;
1050
990
  }
1051
991
  let tagText = scanText;
@@ -1053,19 +993,18 @@ ${cont(scanText)}` };
1053
993
  tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
1054
994
  }
1055
995
  let skipTagScan = false;
1056
- if (cp.tagAcrossLines) {
1057
- if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
1058
- const attrs = { state: cp.tagAcrossLinesState };
996
+ if (cp.pendingTag !== null) {
997
+ if (ln.indent < cp.pendingTag.indent) poisonRawDivergence();
998
+ const attrs = { state: cp.pendingTag.attr };
1059
999
  const gt = scanTagAttrs(ln.text, 0, ln.text.length, attrs);
1060
1000
  if (gt === -1) {
1061
1001
  scanTagAttrs("\n", 0, 1, attrs);
1062
- cp.tagAcrossLinesState = attrs.state;
1002
+ cp.pendingTag = { attr: attrs.state, indent: cp.pendingTag.indent };
1063
1003
  skipTagScan = true;
1064
1004
  } else {
1065
1005
  for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
1066
1006
  cp.pendingTruncatedCloses = [];
1067
- cp.tagAcrossLines = false;
1068
- cp.tagAcrossLinesState = "outside";
1007
+ cp.pendingTag = null;
1069
1008
  tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
1070
1009
  }
1071
1010
  }
@@ -1075,38 +1014,49 @@ ${cont(scanText)}` };
1075
1014
  let m;
1076
1015
  let lastCommentOpenerIdx = -1;
1077
1016
  while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
1078
- if (cp.rawTextOpen !== null && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) {
1079
- if (cp.rawTextOpen === "script" && m[0] === "<!--") cp.scriptDataEscaped = true;
1017
+ if (inRawTextTok(cp.p5Tok) && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) {
1018
+ if (cp.p5Tok.kind === "script") {
1019
+ if (m[0] === "<!--") cp.p5Tok = { ...cp.p5Tok, escaped: true };
1020
+ if (m[0] === "-->") cp.p5Tok = { ...cp.p5Tok, escaped: false };
1021
+ }
1080
1022
  continue;
1081
1023
  }
1082
1024
  if (m[0] === "<!--") {
1083
1025
  const next = tagText.slice(m.index + 4, m.index + 6);
1084
- if (cp.commentOpen) {
1085
- if (next.startsWith(">") || next === "->") cp.commentOpen = false;
1086
- else if (next === "!>" || next === "-!") poisonRawDivergence();
1026
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok)) {
1027
+ if (next.startsWith(">") || next === "->") {
1028
+ if (mdHtml(cp.mdBlock, 2)) cp.mdBlock = { kind: "none" };
1029
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1030
+ } else if (next === "!>" || next === "-!") {
1031
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1032
+ poisonRawDivergence();
1033
+ }
1087
1034
  continue;
1088
1035
  }
1089
1036
  if (next.startsWith(">") || next === "->") {
1090
1037
  continue;
1091
1038
  }
1092
- cp.commentOpen = true;
1039
+ if (cp.mdBlock.kind === "none") cp.mdBlock = { kind: "html", type: 2 };
1040
+ if (cp.p5Tok.kind === "data") cp.p5Tok = { kind: "comment" };
1093
1041
  lastCommentOpenerIdx = m.index;
1094
1042
  continue;
1095
1043
  }
1096
1044
  if (m[0] === "-->") {
1097
- cp.commentOpen = false;
1045
+ if (mdHtml(cp.mdBlock, 2)) cp.mdBlock = { kind: "none" };
1046
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1098
1047
  continue;
1099
1048
  }
1100
1049
  if (m[0] === "--!>") {
1101
- if (cp.commentOpen) poisonRawDivergence();
1050
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok)) poisonRawDivergence();
1051
+ if (cp.p5Tok.kind === "comment") cp.p5Tok = { kind: "data" };
1102
1052
  continue;
1103
1053
  }
1104
- if (cp.commentOpen) continue;
1054
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok)) continue;
1105
1055
  const closing = m[1] === "/";
1106
1056
  const tag = m[2].toLowerCase();
1107
1057
  if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
1108
1058
  let attrs = m[3] ?? "";
1109
- if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
1059
+ if (cp.mdBlock.kind === "html" && (!inRawTextTok(cp.p5Tok) || closing && tag === rawTextElement(cp.p5Tok))) {
1110
1060
  const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
1111
1061
  const st = { state: "outside" };
1112
1062
  const gt = scanTagAttrs(tagText, attrStart, tagText.length, st);
@@ -1116,9 +1066,7 @@ ${cont(scanText)}` };
1116
1066
  else applyTag(tag, false);
1117
1067
  }
1118
1068
  scanTagAttrs("\n", 0, 1, st);
1119
- cp.tagAcrossLines = true;
1120
- cp.tagAcrossLinesIndent = ln.indent;
1121
- cp.tagAcrossLinesState = st.state;
1069
+ cp.pendingTag = { attr: st.state, indent: ln.indent };
1122
1070
  tagHandledAsTruncated = true;
1123
1071
  break;
1124
1072
  }
@@ -1127,16 +1075,15 @@ ${cont(scanText)}` };
1127
1075
  TAG_OR_COMMENT_RE.lastIndex = gt + 1;
1128
1076
  }
1129
1077
  }
1130
- if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) {
1078
+ if (closing && cp.mdBlock.kind !== "html" && !/^\s*$/.test(attrs)) {
1131
1079
  TAG_OR_COMMENT_RE.lastIndex = m.index + 2 + m[2].length;
1132
1080
  continue;
1133
1081
  }
1134
1082
  const selfClosing = /\/\s*$/.test(attrs);
1135
- noteBreakout(tag, closing);
1136
1083
  if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
1137
1084
  applyTag(tag, closing);
1138
1085
  }
1139
- if (cp.commentOpen && lastCommentOpenerIdx !== -1) {
1086
+ if (commentEitherOpen(cp.mdBlock, cp.p5Tok) && lastCommentOpenerIdx !== -1) {
1140
1087
  if (!isMdBlank(tagText.slice(0, lastCommentOpenerIdx)) || ln.indent > 3) {
1141
1088
  cp.phasePoisonedAt = 0;
1142
1089
  }
@@ -1149,13 +1096,12 @@ ${cont(scanText)}` };
1149
1096
  if (mr[0] === "<!--" || mr[0] === "-->" || mr[0] === "--!>") continue;
1150
1097
  const startMasked = masked[mr.index] !== ln.text[mr.index];
1151
1098
  const wholeVisible = masked.slice(mr.index, mr.index + mr[0].length) === mr[0];
1152
- if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
1099
+ if (startMasked || wholeVisible || inRaw(mr.index) || commentEitherOpen(cp.mdBlock, cp.p5Tok)) continue;
1153
1100
  const closing = mr[1] === "/";
1154
1101
  const tag = mr[2].toLowerCase();
1155
1102
  if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
1156
1103
  if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
1157
1104
  const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
1158
- noteBreakout(tag, closing);
1159
1105
  if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
1160
1106
  applyTag(tag, closing);
1161
1107
  }
@@ -1166,7 +1112,7 @@ ${cont(scanText)}` };
1166
1112
  }
1167
1113
  cp.pendingTruncatedTags = [];
1168
1114
  }
1169
- if (!cp.commentOpen && !tagHandledAsTruncated) {
1115
+ if (!commentEitherOpen(cp.mdBlock, cp.p5Tok) && !tagHandledAsTruncated) {
1170
1116
  let lastLt = -1;
1171
1117
  TAG_START_LT_RE.lastIndex = 0;
1172
1118
  for (let ms = TAG_START_LT_RE.exec(tagText); ms !== null; ms = TAG_START_LT_RE.exec(tagText)) {
@@ -1178,18 +1124,16 @@ ${cont(scanText)}` };
1178
1124
  if (m2) {
1179
1125
  const closing = m2[1] === "/";
1180
1126
  const tag = m2[2].toLowerCase();
1181
- if (strayTablePart(tag) && cp.htmlFlowReal) {
1127
+ if (strayTablePart(tag) && cp.mdBlock.kind === "html") {
1182
1128
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
1183
1129
  }
1184
- if (cp.htmlFlowReal) {
1185
- cp.tagAcrossLines = true;
1186
- cp.tagAcrossLinesIndent = ln.indent;
1130
+ if (cp.mdBlock.kind === "html") {
1187
1131
  const attrs = { state: "outside" };
1188
1132
  scanTagAttrs(m2[3] + "\n", 0, m2[3].length + 1, attrs);
1189
- cp.tagAcrossLinesState = attrs.state;
1133
+ cp.pendingTag = { attr: attrs.state, indent: ln.indent };
1190
1134
  }
1191
1135
  if (closing) {
1192
- if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
1136
+ if (!VOID_TAGS.has(tag) && cp.mdBlock.kind === "html") cp.pendingTruncatedCloses.push(tag);
1193
1137
  } else if (!VOID_TAGS.has(tag)) {
1194
1138
  applyTag(tag, closing);
1195
1139
  const rawLastLt = ln.text.lastIndexOf("<");
@@ -1210,21 +1154,20 @@ ${cont(scanText)}` };
1210
1154
  }
1211
1155
  masked2 += scanText.slice(cursor);
1212
1156
  if (floatingResidue(masked2, commentOpenAtLineStart).length > 0) {
1213
- cp.htmlSeamPending = true;
1157
+ cp.p5SealPending = true;
1214
1158
  }
1215
1159
  }
1216
- if (cp.rawTextOpen !== null && cp.rawTextInline) {
1160
+ if (inRawTextTok(cp.p5Tok) && cp.p5Tok.openedInline) {
1217
1161
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1218
1162
  }
1219
- if (cp.type1FlowOpen && TYPE1_CLOSE_RE.test(ln.text)) {
1220
- cp.type1FlowOpen = false;
1221
- cp.htmlFlowSinceBlank = false;
1222
- cp.htmlFlowReal = false;
1163
+ if (mdHtml(cp.mdBlock, 1) && TYPE1_CLOSE_RE.test(ln.text)) {
1164
+ cp.mdBlock = { kind: "none" };
1165
+ cp.mayBeRawToMicromark = false;
1223
1166
  }
1224
1167
  cp.blankRun = 0;
1225
1168
  cp.prevLineBlank = false;
1226
1169
  cp.prevLineWasText = true;
1227
- cp.prevLineWasValidDef = validDef && !def[1].startsWith("^");
1170
+ cp.prevLineWasValidDef = validLinkDef;
1228
1171
  }
1229
1172
 
1230
1173
  // src/components/incrementalParse/spliceParse.ts