@readme/markdown 14.11.5 → 14.12.1

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.
@@ -91765,17 +91765,12 @@ const extractScripts = (html = '') => {
91765
91765
  return [cleaned, () => scripts.map(js => window.eval(js))];
91766
91766
  };
91767
91767
  const HTMLBlock = ({ children = '', html: htmlProp, runScripts, safeMode: safeModeRaw = false }) => {
91768
- // Determine HTML source: MDXish uses html prop (from HAST), MDX uses children
91769
- let html = '';
91770
- if (htmlProp !== undefined) {
91771
- html = htmlProp;
91772
- }
91773
- else {
91774
- if (typeof children !== 'string') {
91775
- throw new TypeError('HTMLBlock: children must be a string');
91776
- }
91777
- html = children;
91778
- }
91768
+ // Determine HTML source: MDXish uses html prop (from HAST), MDX uses children.
91769
+ // A non-string child (no html prop) can't be injected as raw HTML — see the
91770
+ // fail-soft fallback below.
91771
+ const htmlSource = htmlProp !== undefined ? htmlProp : children;
91772
+ const nonStringChildren = typeof htmlSource !== 'string';
91773
+ const html = nonStringChildren ? '' : htmlSource;
91779
91774
  // eslint-disable-next-line no-param-reassign
91780
91775
  runScripts = typeof runScripts !== 'boolean' ? runScripts === 'true' : runScripts;
91781
91776
  // In MDX mode, safeMode is passed in as a boolean from JSX parsing
@@ -91786,6 +91781,11 @@ const HTMLBlock = ({ children = '', html: htmlProp, runScripts, safeMode: safeMo
91786
91781
  if (typeof window !== 'undefined' && typeof runScripts === 'boolean' && runScripts)
91787
91782
  exec();
91788
91783
  }, [runScripts, exec]);
91784
+ if (nonStringChildren) {
91785
+ // Fail soft: a non-string child (e.g. JSX that wasn't serialized back to a
91786
+ // raw string) should never throw, so render the child nodes directly
91787
+ return external_react_default().createElement("div", { className: "rdmd-html" }, children);
91788
+ }
91789
91789
  if (safeMode) {
91790
91790
  return (external_react_default().createElement("pre", { className: "html-unsafe" },
91791
91791
  external_react_default().createElement("code", null, html)));
@@ -92855,7 +92855,7 @@ function legacyVariableFromMarkdown() {
92855
92855
  *
92856
92856
  * Unicode basic latin block.
92857
92857
  */
92858
- const codes_codes = /** @type {const} */ ({
92858
+ const codes = /** @type {const} */ ({
92859
92859
  carriageReturn: -5,
92860
92860
  lineFeed: -4,
92861
92861
  carriageReturnLineFeed: -3,
@@ -93003,11 +93003,11 @@ const codes_codes = /** @type {const} */ ({
93003
93003
  function isNameChar(code) {
93004
93004
  if (code === null)
93005
93005
  return false;
93006
- return ((code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ) ||
93007
- (code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) ||
93008
- (code >= codes_codes.digit0 && code <= codes_codes.digit9) ||
93009
- code === codes_codes.dash ||
93010
- code === codes_codes.underscore);
93006
+ return ((code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
93007
+ (code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
93008
+ (code >= codes.digit0 && code <= codes.digit9) ||
93009
+ code === codes.dash ||
93010
+ code === codes.underscore);
93011
93011
  }
93012
93012
  const gemojiConstruct = {
93013
93013
  name: 'gemoji',
@@ -93017,7 +93017,7 @@ function tokenize(effects, ok, nok) {
93017
93017
  let hasName = false;
93018
93018
  // Entry point — expect opening `:`
93019
93019
  const start = (code) => {
93020
- if (code !== codes_codes.colon)
93020
+ if (code !== codes.colon)
93021
93021
  return nok(code);
93022
93022
  effects.enter('gemoji');
93023
93023
  effects.enter('gemojiMarker');
@@ -93028,7 +93028,7 @@ function tokenize(effects, ok, nok) {
93028
93028
  };
93029
93029
  // First char after `:`, branch on `+` for :+1:, otherwise start normal name
93030
93030
  const nameStart = (code) => {
93031
- if (code === codes_codes.plusSign) {
93031
+ if (code === codes.plusSign) {
93032
93032
  effects.consume(code); // +
93033
93033
  return plusOne;
93034
93034
  }
@@ -93043,7 +93043,7 @@ function tokenize(effects, ok, nok) {
93043
93043
  // After `+`, only `1` is valid (for :+1:), anything else rejects
93044
93044
  // this is a special case for :+1: 👍 since + isnt a normal name character
93045
93045
  const plusOne = (code) => {
93046
- if (code === codes_codes.digit1) {
93046
+ if (code === codes.digit1) {
93047
93047
  hasName = true;
93048
93048
  effects.consume(code); // 1
93049
93049
  return nameEnd;
@@ -93052,7 +93052,7 @@ function tokenize(effects, ok, nok) {
93052
93052
  };
93053
93053
  // Consume name characters until we hit closing `:` or an invalid char
93054
93054
  const name = (code) => {
93055
- if (code === codes_codes.colon) {
93055
+ if (code === codes.colon) {
93056
93056
  if (!hasName)
93057
93057
  return nok(code);
93058
93058
  return nameEnd(code);
@@ -93066,7 +93066,7 @@ function tokenize(effects, ok, nok) {
93066
93066
  };
93067
93067
  // Expect closing `:`
93068
93068
  const nameEnd = (code) => {
93069
- if (code !== codes_codes.colon)
93069
+ if (code !== codes.colon)
93070
93070
  return nok(code);
93071
93071
  effects.exit('gemojiName');
93072
93072
  effects.enter('gemojiMarker');
@@ -93079,7 +93079,7 @@ function tokenize(effects, ok, nok) {
93079
93079
  }
93080
93080
  function syntax_gemoji() {
93081
93081
  return {
93082
- text: { [codes_codes.colon]: gemojiConstruct },
93082
+ text: { [codes.colon]: gemojiConstruct },
93083
93083
  };
93084
93084
  }
93085
93085
 
@@ -93094,8 +93094,8 @@ function syntax_gemoji() {
93094
93094
 
93095
93095
  function isAllowedValueChar(code) {
93096
93096
  return (code !== null &&
93097
- code !== codes_codes.lessThan &&
93098
- code !== codes_codes.greaterThan &&
93097
+ code !== codes.lessThan &&
93098
+ code !== codes.greaterThan &&
93099
93099
  !markdownLineEnding(code));
93100
93100
  }
93101
93101
  const legacyVariableConstruct = {
@@ -93105,7 +93105,7 @@ const legacyVariableConstruct = {
93105
93105
  function syntax_tokenize(effects, ok, nok) {
93106
93106
  let hasValue = false;
93107
93107
  const start = (code) => {
93108
- if (code !== codes_codes.lessThan)
93108
+ if (code !== codes.lessThan)
93109
93109
  return nok(code);
93110
93110
  effects.enter('legacyVariable');
93111
93111
  effects.enter('legacyVariableMarkerStart');
@@ -93113,7 +93113,7 @@ function syntax_tokenize(effects, ok, nok) {
93113
93113
  return open2;
93114
93114
  };
93115
93115
  const open2 = (code) => {
93116
- if (code !== codes_codes.lessThan)
93116
+ if (code !== codes.lessThan)
93117
93117
  return nok(code);
93118
93118
  effects.consume(code); // <<
93119
93119
  effects.exit('legacyVariableMarkerStart');
@@ -93121,7 +93121,7 @@ function syntax_tokenize(effects, ok, nok) {
93121
93121
  return value;
93122
93122
  };
93123
93123
  const value = (code) => {
93124
- if (code === codes_codes.greaterThan) {
93124
+ if (code === codes.greaterThan) {
93125
93125
  if (!hasValue)
93126
93126
  return nok(code);
93127
93127
  effects.exit('legacyVariableValue');
@@ -93136,7 +93136,7 @@ function syntax_tokenize(effects, ok, nok) {
93136
93136
  return value;
93137
93137
  };
93138
93138
  const close2 = (code) => {
93139
- if (code !== codes_codes.greaterThan)
93139
+ if (code !== codes.greaterThan)
93140
93140
  return nok(code);
93141
93141
  effects.consume(code); // >>
93142
93142
  effects.exit('legacyVariableMarkerEnd');
@@ -93147,7 +93147,7 @@ function syntax_tokenize(effects, ok, nok) {
93147
93147
  }
93148
93148
  function legacyVariable() {
93149
93149
  return {
93150
- text: { [codes_codes.lessThan]: legacyVariableConstruct },
93150
+ text: { [codes.lessThan]: legacyVariableConstruct },
93151
93151
  };
93152
93152
  }
93153
93153
 
@@ -96621,6 +96621,9 @@ const TOP_LEVEL_TABLE_TAG_RE = /^<(?:table|Table)(?=[\s/>])/;
96621
96621
  * Uses `walkTags` so `<table>`s inside code spans / fenced blocks (masked away)
96622
96622
  * are never matched.
96623
96623
  *
96624
+ * `<table>`s inside an `<HTMLBlock>` body are also ignored: that body is opaque
96625
+ * raw HTML, so lifting a table out of it would corrupt the block.
96626
+ *
96624
96627
  * Note: An implicitly-closed table (no `</table>`, so htmlparser2 synthesizes the
96625
96628
  * close at a later tag) is skipped: splitting there would swallow whatever
96626
96629
  * followed the table into the fragment and drop it, so we leave such a node
@@ -96628,21 +96631,35 @@ const TOP_LEVEL_TABLE_TAG_RE = /^<(?:table|Table)(?=[\s/>])/;
96628
96631
  */
96629
96632
  const findTableRanges = (html) => {
96630
96633
  const ranges = [];
96631
- let depth = 0;
96634
+ let tableDepth = 0;
96635
+ let htmlBlockDepth = 0;
96632
96636
  let start = 0;
96633
96637
  walkTags(html, {
96634
- onOpen: ({ name, start: openStart, isStrayCloser }) => {
96635
- if (name.toLowerCase() !== 'table' || isStrayCloser)
96638
+ onOpen: ({ name, start: openStart, isSelfClosing, isStrayCloser }) => {
96639
+ if (isStrayCloser)
96636
96640
  return;
96637
- if (depth === 0)
96641
+ // `<HTMLBlock/>` has no body to protect; only a real open enters one.
96642
+ if (name === 'HTMLBlock') {
96643
+ if (!isSelfClosing)
96644
+ htmlBlockDepth += 1;
96645
+ return;
96646
+ }
96647
+ if (htmlBlockDepth > 0 || name.toLowerCase() !== 'table')
96648
+ return;
96649
+ if (tableDepth === 0)
96638
96650
  start = openStart;
96639
- depth += 1;
96651
+ tableDepth += 1;
96640
96652
  },
96641
96653
  onClose: ({ name, end, implicit }) => {
96642
- if (implicit || name.toLowerCase() !== 'table' || depth === 0)
96654
+ if (name === 'HTMLBlock') {
96655
+ if (!implicit && htmlBlockDepth > 0)
96656
+ htmlBlockDepth -= 1;
96643
96657
  return;
96644
- depth -= 1;
96645
- if (depth === 0)
96658
+ }
96659
+ if (implicit || htmlBlockDepth > 0 || name.toLowerCase() !== 'table' || tableDepth === 0)
96660
+ return;
96661
+ tableDepth -= 1;
96662
+ if (tableDepth === 0)
96646
96663
  ranges.push({ start, end });
96647
96664
  },
96648
96665
  });
@@ -96662,7 +96679,9 @@ const splitHtmlWithNestedTables = (node) => {
96662
96679
  // This is a top-level table, so we don't need to split it
96663
96680
  if (TOP_LEVEL_TABLE_TAG_RE.test(value))
96664
96681
  return null;
96665
- // No table text anywhere in the value → skip the htmlparser2 walk entirely.
96682
+ // No table text anywhere → skip the htmlparser2 walk entirely. (A `<table>` that
96683
+ // only appears inside an `<HTMLBlock>` body still yields no ranges below, so it's
96684
+ // left whole for `mdxishHtmlBlocks` to convert to an html-block next.)
96666
96685
  if (!/<\/?table/i.test(value))
96667
96686
  return null;
96668
96687
  const ranges = findTableRanges(value);
@@ -109814,63 +109833,6 @@ function rehypeSanitize(options) {
109814
109833
  }
109815
109834
  }
109816
109835
 
109817
- ;// ./node_modules/mdast-util-newline-to-break/lib/index.js
109818
- /**
109819
- * @typedef {import('mdast').Nodes} Nodes
109820
- * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction
109821
- */
109822
-
109823
-
109824
-
109825
- /**
109826
- * Turn normal line endings into hard breaks.
109827
- *
109828
- * @param {Nodes} tree
109829
- * Tree to change.
109830
- * @returns {undefined}
109831
- * Nothing.
109832
- */
109833
- function newlineToBreak(tree) {
109834
- findAndReplace(tree, [/\r?\n|\r/g, lib_replace])
109835
- }
109836
-
109837
- /**
109838
- * Replace line endings.
109839
- *
109840
- * @type {ReplaceFunction}
109841
- */
109842
- function lib_replace() {
109843
- return {type: 'break'}
109844
- }
109845
-
109846
- ;// ./node_modules/remark-breaks/lib/index.js
109847
- /**
109848
- * @typedef {import('mdast').Root} Root
109849
- */
109850
-
109851
-
109852
-
109853
- /**
109854
- * Support hard breaks without needing spaces or escapes (turns enters into
109855
- * `<br>`s).
109856
- *
109857
- * @returns
109858
- * Transform.
109859
- */
109860
- function remarkBreaks() {
109861
- /**
109862
- * Transform.
109863
- *
109864
- * @param {Root} tree
109865
- * Tree.
109866
- * @returns {undefined}
109867
- * Nothing.
109868
- */
109869
- return function (tree) {
109870
- newlineToBreak(tree)
109871
- }
109872
- }
109873
-
109874
109836
  ;// ./errors/mdx-syntax-error.ts
109875
109837
  class MdxSyntaxError extends SyntaxError {
109876
109838
  original = null;
@@ -109892,6 +109854,22 @@ class MdxSyntaxError extends SyntaxError {
109892
109854
  }
109893
109855
  }
109894
109856
 
109857
+ ;// ./processor/plugin/hard-breaks.ts
109858
+
109859
+ /**
109860
+ * Converts LF and CRLF line endings into hard breaks while leaving standalone
109861
+ * carriage returns as soft whitespace.
109862
+ *
109863
+ * Unlike `remark-breaks`, this does not promote a lone `\r` into a `<br>`.
109864
+ * Standalone carriage returns can be left behind by generators that replace
109865
+ * the LF in Windows line endings with an explicit `<br>`, producing input such
109866
+ * as `\r<br>`. Treating both characters as hard breaks doubles the spacing.
109867
+ */
109868
+ const hardBreaks = () => tree => {
109869
+ findAndReplace(tree, [/\r?\n/g, () => ({ type: 'break' })]);
109870
+ };
109871
+ /* harmony default export */ const hard_breaks = (hardBreaks);
109872
+
109895
109873
  ;// ./node_modules/estree-util-value-to-estree/dist/estree-util-value-to-estree.js
109896
109874
  /**
109897
109875
  * Create an ESTree identifier node for a given name.
@@ -112596,7 +112574,7 @@ const compile_compile = (text, { components = {}, missingComponents, copyButtons
112596
112574
  const remarkPlugins = [
112597
112575
  remarkFrontmatter,
112598
112576
  lib_remarkGfm,
112599
- ...(hardBreaks ? [remarkBreaks] : []),
112577
+ ...(hardBreaks ? [hard_breaks] : []),
112600
112578
  ...Object.values(transforms),
112601
112579
  [codeTabsTransformer, { copyButtons }],
112602
112580
  [
@@ -118404,6 +118382,55 @@ function emptyTaskListItemFromMarkdown() {
118404
118382
  };
118405
118383
  }
118406
118384
 
118385
+ ;// ./lib/mdast-util/jsx-table/index.ts
118386
+ const jsx_table_contextMap = new WeakMap();
118387
+ function findJsxTableToken() {
118388
+ const events = this.tokenStack;
118389
+ for (let i = events.length - 1; i >= 0; i -= 1) {
118390
+ if (events[i][0].type === 'jsxTable')
118391
+ return events[i][0];
118392
+ }
118393
+ return undefined;
118394
+ }
118395
+ function enterJsxTable(token) {
118396
+ jsx_table_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
118397
+ this.enter({ type: 'html', value: '' }, token);
118398
+ }
118399
+ function exitJsxTableData(token) {
118400
+ const tableToken = findJsxTableToken.call(this);
118401
+ if (!tableToken)
118402
+ return;
118403
+ const ctx = jsx_table_contextMap.get(tableToken);
118404
+ if (ctx) {
118405
+ const gap = token.start.line - ctx.lastEndLine;
118406
+ if (ctx.chunks.length > 0 && gap > 0) {
118407
+ ctx.chunks.push('\n'.repeat(gap));
118408
+ }
118409
+ ctx.chunks.push(this.sliceSerialize(token));
118410
+ ctx.lastEndLine = token.end.line;
118411
+ }
118412
+ }
118413
+ function exitJsxTable(token) {
118414
+ const ctx = jsx_table_contextMap.get(token);
118415
+ const node = this.stack[this.stack.length - 1];
118416
+ if (ctx) {
118417
+ node.value = ctx.chunks.join('');
118418
+ jsx_table_contextMap.delete(token);
118419
+ }
118420
+ this.exit(token);
118421
+ }
118422
+ function jsx_table_jsxTableFromMarkdown() {
118423
+ return {
118424
+ enter: {
118425
+ jsxTable: enterJsxTable,
118426
+ },
118427
+ exit: {
118428
+ jsxTableData: exitJsxTableData,
118429
+ jsxTable: exitJsxTable,
118430
+ },
118431
+ };
118432
+ }
118433
+
118407
118434
  ;// ./lib/mdast-util/magic-block/index.ts
118408
118435
  const magic_block_contextMap = new WeakMap();
118409
118436
  /**
@@ -118593,867 +118620,16 @@ function mdx_component_mdxComponentFromMarkdown() {
118593
118620
  };
118594
118621
  }
118595
118622
 
118596
- ;// ./lib/micromark/magic-block/syntax.ts
118597
-
118598
-
118599
- /**
118600
- * Known magic block types that the tokenizer will recognize.
118601
- * Unknown types will not be tokenized as magic blocks.
118602
- */
118603
- const KNOWN_BLOCK_TYPES = new Set([
118604
- 'code',
118605
- 'api-header',
118606
- 'image',
118607
- 'callout',
118608
- 'parameters',
118609
- 'table',
118610
- 'embed',
118611
- 'html',
118612
- 'recipe',
118613
- 'tutorial-tile',
118614
- ]);
118615
- /**
118616
- * Check if a character is valid for a magic block type identifier.
118617
- * Types can contain alphanumeric characters and hyphens (e.g., "api-header", "tutorial-tile")
118618
- */
118619
- function isTypeChar(code) {
118620
- return asciiAlphanumeric(code) || code === codes_codes.dash;
118621
- }
118622
- /**
118623
- * Creates the opening marker state machine: [block:
118624
- * Returns the first state function to start parsing.
118625
- */
118626
- function createOpeningMarkerParser(effects, nok, onComplete) {
118627
- const expectB = (code) => {
118628
- if (code !== codes_codes.lowercaseB)
118629
- return nok(code);
118630
- effects.consume(code);
118631
- return expectL;
118632
- };
118633
- const expectL = (code) => {
118634
- if (code !== codes_codes.lowercaseL)
118635
- return nok(code);
118636
- effects.consume(code);
118637
- return expectO;
118638
- };
118639
- const expectO = (code) => {
118640
- if (code !== codes_codes.lowercaseO)
118641
- return nok(code);
118642
- effects.consume(code);
118643
- return expectC;
118644
- };
118645
- const expectC = (code) => {
118646
- if (code !== codes_codes.lowercaseC)
118647
- return nok(code);
118648
- effects.consume(code);
118649
- return expectK;
118650
- };
118651
- const expectK = (code) => {
118652
- if (code !== codes_codes.lowercaseK)
118653
- return nok(code);
118654
- effects.consume(code);
118655
- return expectColon;
118656
- };
118657
- const expectColon = (code) => {
118658
- if (code !== codes_codes.colon)
118659
- return nok(code);
118660
- effects.consume(code);
118661
- effects.exit('magicBlockMarkerStart');
118662
- effects.enter('magicBlockType');
118663
- return onComplete;
118664
- };
118665
- return expectB;
118666
- }
118667
- /**
118668
- * Creates the type capture state machine.
118669
- * Captures type characters until ] and validates against known types.
118670
- */
118671
- function createTypeCaptureParser(effects, nok, onComplete, blockTypeRef) {
118672
- const captureTypeFirst = (code) => {
118673
- // Reject empty type name [block:]
118674
- if (code === codes_codes.rightSquareBracket) {
118675
- return nok(code);
118676
- }
118677
- if (isTypeChar(code)) {
118678
- blockTypeRef.value += String.fromCharCode(code);
118679
- effects.consume(code);
118680
- return captureType;
118681
- }
118682
- return nok(code);
118683
- };
118684
- const captureType = (code) => {
118685
- if (code === codes_codes.rightSquareBracket) {
118686
- if (!KNOWN_BLOCK_TYPES.has(blockTypeRef.value)) {
118687
- return nok(code);
118688
- }
118689
- effects.exit('magicBlockType');
118690
- effects.enter('magicBlockMarkerTypeEnd');
118691
- effects.consume(code);
118692
- effects.exit('magicBlockMarkerTypeEnd');
118693
- return onComplete;
118694
- }
118695
- if (isTypeChar(code)) {
118696
- blockTypeRef.value += String.fromCharCode(code);
118697
- effects.consume(code);
118698
- return captureType;
118699
- }
118700
- return nok(code);
118701
- };
118702
- return { first: captureTypeFirst, remaining: captureType };
118703
- }
118704
- /**
118705
- * Creates the closing marker state machine: /block]
118706
- * Handles partial matches by calling onMismatch to fall back to data capture.
118707
- */
118708
- function createClosingMarkerParser(effects, onSuccess, onMismatch, onEof, jsonState) {
118709
- const handleMismatch = (code) => {
118710
- if (jsonState && code === codes_codes.quotationMark) {
118711
- jsonState.inString = true;
118712
- }
118713
- return onMismatch(code);
118714
- };
118715
- const expectSlash = (code) => {
118716
- if (code === null)
118717
- return onEof(code);
118718
- if (code !== codes_codes.slash)
118719
- return handleMismatch(code);
118720
- effects.consume(code);
118721
- return expectB;
118722
- };
118723
- const expectB = (code) => {
118724
- if (code === null)
118725
- return onEof(code);
118726
- if (code !== codes_codes.lowercaseB)
118727
- return handleMismatch(code);
118728
- effects.consume(code);
118729
- return expectL;
118730
- };
118731
- const expectL = (code) => {
118732
- if (code === null)
118733
- return onEof(code);
118734
- if (code !== codes_codes.lowercaseL)
118735
- return handleMismatch(code);
118736
- effects.consume(code);
118737
- return expectO;
118738
- };
118739
- const expectO = (code) => {
118740
- if (code === null)
118741
- return onEof(code);
118742
- if (code !== codes_codes.lowercaseO)
118743
- return handleMismatch(code);
118744
- effects.consume(code);
118745
- return expectC;
118746
- };
118747
- const expectC = (code) => {
118748
- if (code === null)
118749
- return onEof(code);
118750
- if (code !== codes_codes.lowercaseC)
118751
- return handleMismatch(code);
118752
- effects.consume(code);
118753
- return expectK;
118754
- };
118755
- const expectK = (code) => {
118756
- if (code === null)
118757
- return onEof(code);
118758
- if (code !== codes_codes.lowercaseK)
118759
- return handleMismatch(code);
118760
- effects.consume(code);
118761
- return expectBracket;
118762
- };
118763
- const expectBracket = (code) => {
118764
- if (code === null)
118765
- return onEof(code);
118766
- if (code !== codes_codes.rightSquareBracket)
118767
- return handleMismatch(code);
118768
- effects.consume(code);
118769
- return onSuccess;
118770
- };
118771
- return { expectSlash };
118772
- }
118773
- /**
118774
- * Partial construct for checking non-lazy continuation.
118775
- * This is used by the flow tokenizer to check if we can continue
118776
- * parsing on the next line.
118777
- */
118778
- const syntax_nonLazyContinuation = {
118779
- partial: true,
118780
- tokenize: syntax_tokenizeNonLazyContinuation,
118781
- };
118782
- /**
118783
- * Tokenizer for non-lazy continuation checking.
118784
- * Returns ok if the next line is non-lazy (can continue), nok if lazy.
118785
- */
118786
- function syntax_tokenizeNonLazyContinuation(effects, ok, nok) {
118787
- const lineStart = (code) => {
118788
- // `this` here refers to the micromark parser
118789
- // since we are just passing functions as references and not actually calling them
118790
- // micromarks's internal parser will call this automatically with appropriate arguments
118791
- return this.parser.lazy[this.now().line] ? nok(code) : ok(code);
118792
- };
118793
- const start = (code) => {
118794
- if (code === null) {
118795
- return nok(code);
118796
- }
118797
- if (!markdownLineEnding(code)) {
118798
- return nok(code);
118799
- }
118800
- effects.enter('magicBlockLineEnding');
118801
- effects.consume(code);
118802
- effects.exit('magicBlockLineEnding');
118803
- return lineStart;
118804
- };
118805
- return start;
118806
- }
118623
+ ;// ./node_modules/micromark-util-symbol/lib/types.js
118807
118624
  /**
118808
- * Create a micromark extension for magic block syntax.
118809
- *
118810
- * This extension handles both single-line and multiline magic blocks:
118811
- * - Flow construct (concrete): Handles block-level multiline magic blocks at document level
118812
- * - Text construct: Handles inline magic blocks in lists, paragraphs, etc.
118625
+ * This module is compiled away!
118813
118626
  *
118814
- * The flow construct is marked as "concrete" which prevents it from being
118815
- * interrupted by container markers (like `>` for blockquotes or `-` for lists).
118816
- */
118817
- function syntax_magicBlock() {
118818
- return {
118819
- // Flow construct - handles block-level magic blocks at document root
118820
- // Marked as concrete to prevent interruption by containers
118821
- flow: {
118822
- [codes_codes.leftSquareBracket]: {
118823
- name: 'magicBlock',
118824
- concrete: true,
118825
- tokenize: tokenizeMagicBlockFlow,
118826
- },
118827
- },
118828
- // Text construct - handles magic blocks in inline contexts (lists, paragraphs)
118829
- text: {
118830
- [codes_codes.leftSquareBracket]: {
118831
- name: 'magicBlock',
118832
- tokenize: tokenizeMagicBlockText,
118833
- },
118834
- },
118835
- };
118836
- }
118837
- /**
118838
- * Flow tokenizer for block-level magic blocks (multiline).
118839
- * Uses the continuation checking pattern from code fences.
118840
- */
118841
- function tokenizeMagicBlockFlow(effects, ok, nok) {
118842
- // State for tracking JSON content
118843
- const jsonState = { escapeNext: false, inString: false };
118844
- const blockTypeRef = { value: '' };
118845
- let seenOpenBrace = false;
118846
- // Create shared parsers for opening marker and type capture
118847
- const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
118848
- const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
118849
- return start;
118850
- function start(code) {
118851
- if (code !== codes_codes.leftSquareBracket)
118852
- return nok(code);
118853
- effects.enter('magicBlock');
118854
- effects.enter('magicBlockMarkerStart');
118855
- effects.consume(code);
118856
- return openingMarkerParser;
118857
- }
118858
- /**
118859
- * State before data content - handles line endings or starts data capture.
118860
- */
118861
- function beforeData(code) {
118862
- // EOF - magic block must be closed
118863
- if (code === null) {
118864
- effects.exit('magicBlock');
118865
- return nok(code);
118866
- }
118867
- // Line ending before any data - check continuation
118868
- if (markdownLineEnding(code)) {
118869
- return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
118870
- }
118871
- // Check for closing marker directly (without entering data)
118872
- // This handles cases like [block:type]\n{}\n\n[/block] where there are
118873
- // newlines after the data object
118874
- if (code === codes_codes.leftSquareBracket) {
118875
- effects.enter('magicBlockMarkerEnd');
118876
- effects.consume(code);
118877
- return expectSlashFromContinuation;
118878
- }
118879
- // If we've already seen the opening brace, just continue capturing data
118880
- if (seenOpenBrace) {
118881
- effects.enter('magicBlockData');
118882
- return captureData(code);
118883
- }
118884
- // Skip whitespace (spaces/tabs) before the data - stay in beforeData
118885
- // Don't enter magicBlockData token yet until we confirm there's a '{'
118886
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
118887
- return beforeDataWhitespace(code);
118888
- }
118889
- // Data must start with '{' for valid JSON
118890
- if (code !== codes_codes.leftCurlyBrace) {
118891
- effects.exit('magicBlock');
118892
- return nok(code);
118893
- }
118894
- // We have '{' - enter data token and start capturing
118895
- seenOpenBrace = true;
118896
- effects.enter('magicBlockData');
118897
- return captureData(code);
118898
- }
118899
- /**
118900
- * Consume whitespace before the data without creating a token.
118901
- * Uses a temporary token to satisfy micromark's requirement.
118902
- */
118903
- function beforeDataWhitespace(code) {
118904
- if (code === null) {
118905
- effects.exit('magicBlock');
118906
- return nok(code);
118907
- }
118908
- if (markdownLineEnding(code)) {
118909
- return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
118910
- }
118911
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
118912
- // We need to consume this but can't without a token - use magicBlockData
118913
- // and track that we haven't seen '{' yet
118914
- effects.enter('magicBlockData');
118915
- effects.consume(code);
118916
- return beforeDataWhitespaceContinue;
118917
- }
118918
- if (code === codes_codes.leftCurlyBrace) {
118919
- seenOpenBrace = true;
118920
- effects.enter('magicBlockData');
118921
- return captureData(code);
118922
- }
118923
- effects.exit('magicBlock');
118924
- return nok(code);
118925
- }
118926
- /**
118927
- * Continue consuming whitespace or validate the opening brace.
118928
- */
118929
- function beforeDataWhitespaceContinue(code) {
118930
- if (code === null) {
118931
- effects.exit('magicBlockData');
118932
- effects.exit('magicBlock');
118933
- return nok(code);
118934
- }
118935
- if (markdownLineEnding(code)) {
118936
- effects.exit('magicBlockData');
118937
- return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
118938
- }
118939
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
118940
- effects.consume(code);
118941
- return beforeDataWhitespaceContinue;
118942
- }
118943
- if (code === codes_codes.leftCurlyBrace) {
118944
- seenOpenBrace = true;
118945
- return captureData(code);
118946
- }
118947
- effects.exit('magicBlockData');
118948
- effects.exit('magicBlock');
118949
- return nok(code);
118950
- }
118951
- /**
118952
- * Continuation OK before we've entered data token.
118953
- */
118954
- function continuationOkBeforeData(code) {
118955
- effects.enter('magicBlockLineEnding');
118956
- effects.consume(code);
118957
- effects.exit('magicBlockLineEnding');
118958
- return beforeData; // Stay in beforeData state - don't enter magicBlockData yet
118959
- }
118960
- function captureData(code) {
118961
- // EOF - magic block must be closed
118962
- if (code === null) {
118963
- effects.exit('magicBlockData');
118964
- effects.exit('magicBlock');
118965
- return nok(code);
118966
- }
118967
- // At line ending, check if we can continue on the next line
118968
- if (markdownLineEnding(code)) {
118969
- effects.exit('magicBlockData');
118970
- return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
118971
- }
118972
- if (jsonState.escapeNext) {
118973
- jsonState.escapeNext = false;
118974
- effects.consume(code);
118975
- return captureData;
118976
- }
118977
- if (jsonState.inString) {
118978
- if (code === codes_codes.backslash) {
118979
- jsonState.escapeNext = true;
118980
- effects.consume(code);
118981
- return captureData;
118982
- }
118983
- if (code === codes_codes.quotationMark) {
118984
- jsonState.inString = false;
118985
- }
118986
- effects.consume(code);
118987
- return captureData;
118988
- }
118989
- if (code === codes_codes.quotationMark) {
118990
- jsonState.inString = true;
118991
- effects.consume(code);
118992
- return captureData;
118993
- }
118994
- if (code === codes_codes.leftSquareBracket) {
118995
- effects.exit('magicBlockData');
118996
- effects.enter('magicBlockMarkerEnd');
118997
- effects.consume(code);
118998
- return expectSlash;
118999
- }
119000
- effects.consume(code);
119001
- return captureData;
119002
- }
119003
- /**
119004
- * Called when non-lazy continuation check passes - we can continue parsing.
119005
- */
119006
- function continuationOk(code) {
119007
- // Consume the line ending
119008
- effects.enter('magicBlockLineEnding');
119009
- effects.consume(code);
119010
- effects.exit('magicBlockLineEnding');
119011
- return continuationStart;
119012
- }
119013
- /**
119014
- * Start of continuation line - check for more line endings, closing marker, or start capturing data.
119015
- */
119016
- function continuationStart(code) {
119017
- // Handle consecutive line endings
119018
- if (code === null) {
119019
- effects.exit('magicBlock');
119020
- return nok(code);
119021
- }
119022
- if (markdownLineEnding(code)) {
119023
- return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
119024
- }
119025
- // Check if this is the start of the closing marker [/block]
119026
- // If so, handle it directly without entering magicBlockData
119027
- if (code === codes_codes.leftSquareBracket) {
119028
- effects.enter('magicBlockMarkerEnd');
119029
- effects.consume(code);
119030
- return expectSlashFromContinuation;
119031
- }
119032
- effects.enter('magicBlockData');
119033
- return captureData(code);
119034
- }
119035
- /**
119036
- * Check for closing marker slash when coming from continuation.
119037
- * If not a closing marker, create an empty data token and continue.
119038
- */
119039
- function expectSlashFromContinuation(code) {
119040
- if (code === null) {
119041
- effects.exit('magicBlockMarkerEnd');
119042
- effects.exit('magicBlock');
119043
- return nok(code);
119044
- }
119045
- if (markdownLineEnding(code)) {
119046
- effects.exit('magicBlockMarkerEnd');
119047
- return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
119048
- }
119049
- if (code === codes_codes.slash) {
119050
- effects.consume(code);
119051
- return expectClosingB;
119052
- }
119053
- // Not a closing marker - this is data content
119054
- // Exit marker and enter data
119055
- effects.exit('magicBlockMarkerEnd');
119056
- effects.enter('magicBlockData');
119057
- // The [ was consumed by the marker, so we need to conceptually "have it" in our data
119058
- // But since we already consumed it into the marker, we need a different approach
119059
- // Re-classify: consume this character as data and continue
119060
- if (code === codes_codes.quotationMark)
119061
- jsonState.inString = true;
119062
- effects.consume(code);
119063
- return captureData;
119064
- }
119065
- function expectSlash(code) {
119066
- if (code === null) {
119067
- effects.exit('magicBlockMarkerEnd');
119068
- effects.exit('magicBlock');
119069
- return nok(code);
119070
- }
119071
- // At line ending during marker parsing
119072
- if (markdownLineEnding(code)) {
119073
- effects.exit('magicBlockMarkerEnd');
119074
- return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
119075
- }
119076
- if (code !== codes_codes.slash) {
119077
- effects.exit('magicBlockMarkerEnd');
119078
- effects.enter('magicBlockData');
119079
- if (code === codes_codes.quotationMark)
119080
- jsonState.inString = true;
119081
- effects.consume(code);
119082
- return captureData;
119083
- }
119084
- effects.consume(code);
119085
- return expectClosingB;
119086
- }
119087
- function expectClosingB(code) {
119088
- if (code === null) {
119089
- effects.exit('magicBlockMarkerEnd');
119090
- effects.exit('magicBlock');
119091
- return nok(code);
119092
- }
119093
- if (code !== codes_codes.lowercaseB) {
119094
- effects.exit('magicBlockMarkerEnd');
119095
- effects.enter('magicBlockData');
119096
- if (code === codes_codes.quotationMark)
119097
- jsonState.inString = true;
119098
- effects.consume(code);
119099
- return captureData;
119100
- }
119101
- effects.consume(code);
119102
- return expectClosingL;
119103
- }
119104
- function expectClosingL(code) {
119105
- if (code === null) {
119106
- effects.exit('magicBlockMarkerEnd');
119107
- effects.exit('magicBlock');
119108
- return nok(code);
119109
- }
119110
- if (code !== codes_codes.lowercaseL) {
119111
- effects.exit('magicBlockMarkerEnd');
119112
- effects.enter('magicBlockData');
119113
- if (code === codes_codes.quotationMark)
119114
- jsonState.inString = true;
119115
- effects.consume(code);
119116
- return captureData;
119117
- }
119118
- effects.consume(code);
119119
- return expectClosingO;
119120
- }
119121
- function expectClosingO(code) {
119122
- if (code === null) {
119123
- effects.exit('magicBlockMarkerEnd');
119124
- effects.exit('magicBlock');
119125
- return nok(code);
119126
- }
119127
- if (code !== codes_codes.lowercaseO) {
119128
- effects.exit('magicBlockMarkerEnd');
119129
- effects.enter('magicBlockData');
119130
- if (code === codes_codes.quotationMark)
119131
- jsonState.inString = true;
119132
- effects.consume(code);
119133
- return captureData;
119134
- }
119135
- effects.consume(code);
119136
- return expectClosingC;
119137
- }
119138
- function expectClosingC(code) {
119139
- if (code === null) {
119140
- effects.exit('magicBlockMarkerEnd');
119141
- effects.exit('magicBlock');
119142
- return nok(code);
119143
- }
119144
- if (code !== codes_codes.lowercaseC) {
119145
- effects.exit('magicBlockMarkerEnd');
119146
- effects.enter('magicBlockData');
119147
- if (code === codes_codes.quotationMark)
119148
- jsonState.inString = true;
119149
- effects.consume(code);
119150
- return captureData;
119151
- }
119152
- effects.consume(code);
119153
- return expectClosingK;
119154
- }
119155
- function expectClosingK(code) {
119156
- if (code === null) {
119157
- effects.exit('magicBlockMarkerEnd');
119158
- effects.exit('magicBlock');
119159
- return nok(code);
119160
- }
119161
- if (code !== codes_codes.lowercaseK) {
119162
- effects.exit('magicBlockMarkerEnd');
119163
- effects.enter('magicBlockData');
119164
- if (code === codes_codes.quotationMark)
119165
- jsonState.inString = true;
119166
- effects.consume(code);
119167
- return captureData;
119168
- }
119169
- effects.consume(code);
119170
- return expectClosingBracket;
119171
- }
119172
- function expectClosingBracket(code) {
119173
- if (code === null) {
119174
- effects.exit('magicBlockMarkerEnd');
119175
- effects.exit('magicBlock');
119176
- return nok(code);
119177
- }
119178
- if (code !== codes_codes.rightSquareBracket) {
119179
- effects.exit('magicBlockMarkerEnd');
119180
- effects.enter('magicBlockData');
119181
- if (code === codes_codes.quotationMark)
119182
- jsonState.inString = true;
119183
- effects.consume(code);
119184
- return captureData;
119185
- }
119186
- effects.consume(code);
119187
- effects.exit('magicBlockMarkerEnd');
119188
- // Check for trailing whitespace on the same line
119189
- return consumeTrailing;
119190
- }
119191
- /**
119192
- * Consume trailing whitespace (spaces/tabs) on the same line after [/block].
119193
- * For concrete flow constructs, we must end at eol/eof or fail.
119194
- * Trailing whitespace is consumed; other content causes nok (text tokenizer handles it).
119195
- */
119196
- function consumeTrailing(code) {
119197
- // End of file - done
119198
- if (code === null) {
119199
- effects.exit('magicBlock');
119200
- return ok(code);
119201
- }
119202
- // Line ending - done
119203
- if (markdownLineEnding(code)) {
119204
- effects.exit('magicBlock');
119205
- return ok(code);
119206
- }
119207
- // Space or tab - consume as trailing whitespace
119208
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
119209
- effects.enter('magicBlockTrailing');
119210
- effects.consume(code);
119211
- return consumeTrailingContinue;
119212
- }
119213
- // Any other character - fail flow tokenizer, let text tokenizer handle it
119214
- effects.exit('magicBlock');
119215
- return nok(code);
119216
- }
119217
- /**
119218
- * Continue consuming trailing whitespace.
119219
- */
119220
- function consumeTrailingContinue(code) {
119221
- // End of file - done
119222
- if (code === null) {
119223
- effects.exit('magicBlockTrailing');
119224
- effects.exit('magicBlock');
119225
- return ok(code);
119226
- }
119227
- // Line ending - done
119228
- if (markdownLineEnding(code)) {
119229
- effects.exit('magicBlockTrailing');
119230
- effects.exit('magicBlock');
119231
- return ok(code);
119232
- }
119233
- // More space or tab - keep consuming
119234
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
119235
- effects.consume(code);
119236
- return consumeTrailingContinue;
119237
- }
119238
- // Non-whitespace after whitespace - fail flow tokenizer
119239
- effects.exit('magicBlockTrailing');
119240
- effects.exit('magicBlock');
119241
- return nok(code);
119242
- }
119243
- /**
119244
- * Called when we can't continue (lazy line or EOF) - exit the construct.
119245
- */
119246
- function after(code) {
119247
- effects.exit('magicBlock');
119248
- return nok(code);
119249
- }
119250
- }
119251
- /**
119252
- * Text tokenizer for single-line magic blocks only.
119253
- * Used in inline contexts like list items and paragraphs.
119254
- * Multiline blocks are handled by the flow tokenizer.
119255
- */
119256
- function tokenizeMagicBlockText(effects, ok, nok) {
119257
- // State for tracking JSON content
119258
- const jsonState = { escapeNext: false, inString: false };
119259
- const blockTypeRef = { value: '' };
119260
- let seenOpenBrace = false;
119261
- // Create shared parsers for opening marker and type capture
119262
- const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
119263
- const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
119264
- // Success handler for closing marker - exits tokens and returns ok
119265
- const closingSuccess = (code) => {
119266
- effects.exit('magicBlockMarkerEnd');
119267
- effects.exit('magicBlock');
119268
- return ok(code);
119269
- };
119270
- // Mismatch handler - falls back to data capture
119271
- const closingMismatch = (code) => {
119272
- effects.exit('magicBlockMarkerEnd');
119273
- effects.enter('magicBlockData');
119274
- if (code === codes_codes.quotationMark)
119275
- jsonState.inString = true;
119276
- effects.consume(code);
119277
- return captureData;
119278
- };
119279
- // EOF handler
119280
- const closingEof = (_code) => nok(_code);
119281
- // Create closing marker parsers
119282
- const closingFromBeforeData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
119283
- const closingFromData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
119284
- return start;
119285
- function start(code) {
119286
- if (code !== codes_codes.leftSquareBracket)
119287
- return nok(code);
119288
- effects.enter('magicBlock');
119289
- effects.enter('magicBlockMarkerStart');
119290
- effects.consume(code);
119291
- return openingMarkerParser;
119292
- }
119293
- /**
119294
- * State before data content - handles line endings before entering data token.
119295
- * Whitespace before '{' is allowed.
119296
- */
119297
- function beforeData(code) {
119298
- // Fail on EOF - magic block must be closed
119299
- if (code === null) {
119300
- return nok(code);
119301
- }
119302
- // Handle line endings before any data - consume them without entering data token
119303
- if (markdownLineEnding(code)) {
119304
- effects.enter('magicBlockLineEnding');
119305
- effects.consume(code);
119306
- effects.exit('magicBlockLineEnding');
119307
- return beforeData;
119308
- }
119309
- // Check for closing marker directly (without entering data)
119310
- if (code === codes_codes.leftSquareBracket) {
119311
- effects.enter('magicBlockMarkerEnd');
119312
- effects.consume(code);
119313
- return closingFromBeforeData.expectSlash;
119314
- }
119315
- // If we've already seen the opening brace, just continue capturing data
119316
- if (seenOpenBrace) {
119317
- effects.enter('magicBlockData');
119318
- return captureData(code);
119319
- }
119320
- // Skip whitespace (spaces/tabs) before the data
119321
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
119322
- return beforeDataWhitespace(code);
119323
- }
119324
- // Data must start with '{' for valid JSON
119325
- if (code !== codes_codes.leftCurlyBrace) {
119326
- return nok(code);
119327
- }
119328
- // We have '{' - enter data token and start capturing
119329
- seenOpenBrace = true;
119330
- effects.enter('magicBlockData');
119331
- return captureData(code);
119332
- }
119333
- /**
119334
- * Consume whitespace before the data.
119335
- */
119336
- function beforeDataWhitespace(code) {
119337
- if (code === null) {
119338
- return nok(code);
119339
- }
119340
- if (markdownLineEnding(code)) {
119341
- effects.enter('magicBlockLineEnding');
119342
- effects.consume(code);
119343
- effects.exit('magicBlockLineEnding');
119344
- return beforeData;
119345
- }
119346
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
119347
- effects.enter('magicBlockData');
119348
- effects.consume(code);
119349
- return beforeDataWhitespaceContinue;
119350
- }
119351
- if (code === codes_codes.leftCurlyBrace) {
119352
- seenOpenBrace = true;
119353
- effects.enter('magicBlockData');
119354
- return captureData(code);
119355
- }
119356
- return nok(code);
119357
- }
119358
- /**
119359
- * Continue consuming whitespace or validate the opening brace.
119360
- */
119361
- function beforeDataWhitespaceContinue(code) {
119362
- if (code === null) {
119363
- effects.exit('magicBlockData');
119364
- return nok(code);
119365
- }
119366
- if (markdownLineEnding(code)) {
119367
- effects.exit('magicBlockData');
119368
- effects.enter('magicBlockLineEnding');
119369
- effects.consume(code);
119370
- effects.exit('magicBlockLineEnding');
119371
- return beforeData;
119372
- }
119373
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
119374
- effects.consume(code);
119375
- return beforeDataWhitespaceContinue;
119376
- }
119377
- if (code === codes_codes.leftCurlyBrace) {
119378
- seenOpenBrace = true;
119379
- return captureData(code);
119380
- }
119381
- effects.exit('magicBlockData');
119382
- return nok(code);
119383
- }
119384
- function captureData(code) {
119385
- // Fail on EOF - magic block must be closed
119386
- if (code === null) {
119387
- effects.exit('magicBlockData');
119388
- return nok(code);
119389
- }
119390
- // Handle multiline magic blocks within text/paragraphs
119391
- // Exit data, consume line ending with proper token, then re-enter data
119392
- if (markdownLineEnding(code)) {
119393
- effects.exit('magicBlockData');
119394
- effects.enter('magicBlockLineEnding');
119395
- effects.consume(code);
119396
- effects.exit('magicBlockLineEnding');
119397
- return beforeData; // Go back to beforeData to handle potential empty lines
119398
- }
119399
- if (jsonState.escapeNext) {
119400
- jsonState.escapeNext = false;
119401
- effects.consume(code);
119402
- return captureData;
119403
- }
119404
- if (jsonState.inString) {
119405
- if (code === codes_codes.backslash) {
119406
- jsonState.escapeNext = true;
119407
- effects.consume(code);
119408
- return captureData;
119409
- }
119410
- if (code === codes_codes.quotationMark) {
119411
- jsonState.inString = false;
119412
- }
119413
- effects.consume(code);
119414
- return captureData;
119415
- }
119416
- if (code === codes_codes.quotationMark) {
119417
- jsonState.inString = true;
119418
- effects.consume(code);
119419
- return captureData;
119420
- }
119421
- if (code === codes_codes.leftSquareBracket) {
119422
- effects.exit('magicBlockData');
119423
- effects.enter('magicBlockMarkerEnd');
119424
- effects.consume(code);
119425
- return closingFromData.expectSlash;
119426
- }
119427
- effects.consume(code);
119428
- return captureData;
119429
- }
119430
- }
119431
- /* harmony default export */ const syntax = ((/* unused pure expression or super */ null && (syntax_magicBlock)));
119432
-
119433
- ;// ./lib/micromark/magic-block/index.ts
119434
- /**
119435
- * Micromark extension for magic block syntax.
119436
- *
119437
- * Usage:
119438
- * ```ts
119439
- * import { magicBlock } from './lib/micromark/magic-block';
119440
- *
119441
- * const processor = unified()
119442
- * .data('micromarkExtensions', [magicBlock()])
119443
- * ```
119444
- */
119445
-
119446
-
119447
- ;// ./node_modules/micromark-util-symbol/lib/types.js
119448
- /**
119449
- * This module is compiled away!
119450
- *
119451
- * Here is the list of all types of tokens exposed by micromark, with a short
119452
- * explanation of what they include and where they are found.
119453
- * In picking names, generally, the rule is to be as explicit as possible
119454
- * instead of reusing names.
119455
- * For example, there is a `definitionDestination` and a `resourceDestination`,
119456
- * instead of one shared name.
118627
+ * Here is the list of all types of tokens exposed by micromark, with a short
118628
+ * explanation of what they include and where they are found.
118629
+ * In picking names, generally, the rule is to be as explicit as possible
118630
+ * instead of reusing names.
118631
+ * For example, there is a `definitionDestination` and a `resourceDestination`,
118632
+ * instead of one shared name.
119457
118633
  */
119458
118634
 
119459
118635
  // Note: when changing the next record, you must also change `TokenTypeMap`
@@ -119888,16 +119064,1104 @@ const types_types = /** @type {const} */ ({
119888
119064
  // The whitespace after a marker.
119889
119065
  listItemPrefixWhitespace: 'listItemPrefixWhitespace',
119890
119066
 
119891
- // The numerical value of an ordered item.
119892
- listItemValue: 'listItemValue',
119067
+ // The numerical value of an ordered item.
119068
+ listItemValue: 'listItemValue',
119069
+
119070
+ // Internal types used for subtokenizers, compiled away
119071
+ chunkDocument: 'chunkDocument',
119072
+ chunkContent: 'chunkContent',
119073
+ chunkFlow: 'chunkFlow',
119074
+ chunkText: 'chunkText',
119075
+ chunkString: 'chunkString'
119076
+ })
119077
+
119078
+ ;// ./lib/micromark/jsx-table/syntax.ts
119079
+
119080
+
119081
+ const syntax_nonLazyContinuationStart = {
119082
+ tokenize: syntax_tokenizeNonLazyContinuationStart,
119083
+ partial: true,
119084
+ };
119085
+ function resolveToJsxTable(events) {
119086
+ let index = events.length;
119087
+ while (index > 0) {
119088
+ index -= 1;
119089
+ if (events[index][0] === 'enter' && events[index][1].type === 'jsxTable') {
119090
+ break;
119091
+ }
119092
+ }
119093
+ if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
119094
+ events[index][1].start = events[index - 2][1].start;
119095
+ events[index + 1][1].start = events[index - 2][1].start;
119096
+ events.splice(index - 2, 2);
119097
+ }
119098
+ return events;
119099
+ }
119100
+ const jsxTableConstruct = {
119101
+ name: 'jsxTable',
119102
+ tokenize: tokenizeJsxTable,
119103
+ resolveTo: resolveToJsxTable,
119104
+ concrete: true,
119105
+ };
119106
+ function tokenizeJsxTable(effects, ok, nok) {
119107
+ let codeSpanOpenSize = 0;
119108
+ let codeSpanCloseSize = 0;
119109
+ let depth = 1;
119110
+ const ABLE_SUFFIX = [codes.lowercaseA, codes.lowercaseB, codes.lowercaseL, codes.lowercaseE];
119111
+ /** Build a state chain that matches a sequence of character codes. */
119112
+ function matchChars(chars, onMatch, onFail) {
119113
+ if (chars.length === 0)
119114
+ return onMatch;
119115
+ return ((code) => {
119116
+ if (code === chars[0]) {
119117
+ effects.consume(code);
119118
+ return matchChars(chars.slice(1), onMatch, onFail);
119119
+ }
119120
+ return onFail(code);
119121
+ });
119122
+ }
119123
+ return start;
119124
+ function start(code) {
119125
+ if (code !== codes.lessThan)
119126
+ return nok(code);
119127
+ effects.enter('jsxTable');
119128
+ effects.enter('jsxTableData');
119129
+ effects.consume(code);
119130
+ return afterLessThan;
119131
+ }
119132
+ function afterLessThan(code) {
119133
+ if (code === codes.uppercaseT || code === codes.lowercaseT) {
119134
+ effects.consume(code);
119135
+ return matchChars(ABLE_SUFFIX, afterTagName, nok);
119136
+ }
119137
+ return nok(code);
119138
+ }
119139
+ function afterTagName(code) {
119140
+ if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
119141
+ effects.consume(code);
119142
+ return body;
119143
+ }
119144
+ return nok(code);
119145
+ }
119146
+ function body(code) {
119147
+ // Reject unclosed <Table> so it falls back to normal HTML block parsing
119148
+ // instead of swallowing all subsequent content to EOF
119149
+ if (code === null) {
119150
+ return nok(code);
119151
+ }
119152
+ if (markdownLineEnding(code)) {
119153
+ effects.exit('jsxTableData');
119154
+ return continuationStart(code);
119155
+ }
119156
+ if (code === codes.backslash) {
119157
+ effects.consume(code);
119158
+ return escapedChar;
119159
+ }
119160
+ if (code === codes.lessThan) {
119161
+ effects.consume(code);
119162
+ return closeSlash;
119163
+ }
119164
+ // Skip over backtick code spans so `</Table>` in inline code isn't
119165
+ // treated as the closing tag
119166
+ if (code === codes.graveAccent) {
119167
+ codeSpanOpenSize = 0;
119168
+ return countOpenTicks(code);
119169
+ }
119170
+ effects.consume(code);
119171
+ return body;
119172
+ }
119173
+ function countOpenTicks(code) {
119174
+ if (code === codes.graveAccent) {
119175
+ codeSpanOpenSize += 1;
119176
+ effects.consume(code);
119177
+ return countOpenTicks;
119178
+ }
119179
+ return inCodeSpan(code);
119180
+ }
119181
+ function inCodeSpan(code) {
119182
+ if (code === null || markdownLineEnding(code))
119183
+ return body(code);
119184
+ if (code === codes.graveAccent) {
119185
+ codeSpanCloseSize = 0;
119186
+ return countCloseTicks(code);
119187
+ }
119188
+ effects.consume(code);
119189
+ return inCodeSpan;
119190
+ }
119191
+ function countCloseTicks(code) {
119192
+ if (code === codes.graveAccent) {
119193
+ codeSpanCloseSize += 1;
119194
+ effects.consume(code);
119195
+ return countCloseTicks;
119196
+ }
119197
+ return codeSpanCloseSize === codeSpanOpenSize ? body(code) : inCodeSpan(code);
119198
+ }
119199
+ function escapedChar(code) {
119200
+ if (code === null || markdownLineEnding(code)) {
119201
+ return body(code);
119202
+ }
119203
+ effects.consume(code);
119204
+ return body;
119205
+ }
119206
+ function closeSlash(code) {
119207
+ if (code === codes.slash) {
119208
+ effects.consume(code);
119209
+ return closeTagFirstChar;
119210
+ }
119211
+ if (code === codes.uppercaseT || code === codes.lowercaseT) {
119212
+ effects.consume(code);
119213
+ return matchChars(ABLE_SUFFIX, openAfterTagName, body);
119214
+ }
119215
+ return body(code);
119216
+ }
119217
+ function closeTagFirstChar(code) {
119218
+ if (code === codes.uppercaseT || code === codes.lowercaseT) {
119219
+ effects.consume(code);
119220
+ return matchChars(ABLE_SUFFIX, closeGt, body);
119221
+ }
119222
+ return body(code);
119223
+ }
119224
+ function openAfterTagName(code) {
119225
+ if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
119226
+ depth += 1;
119227
+ effects.consume(code);
119228
+ return body;
119229
+ }
119230
+ return body(code);
119231
+ }
119232
+ function closeGt(code) {
119233
+ if (code === codes.greaterThan) {
119234
+ depth -= 1;
119235
+ effects.consume(code);
119236
+ if (depth === 0) {
119237
+ return afterClose;
119238
+ }
119239
+ return body;
119240
+ }
119241
+ return body(code);
119242
+ }
119243
+ function afterClose(code) {
119244
+ if (code === null || markdownLineEnding(code)) {
119245
+ effects.exit('jsxTableData');
119246
+ effects.exit('jsxTable');
119247
+ return ok(code);
119248
+ }
119249
+ effects.consume(code);
119250
+ return afterClose;
119251
+ }
119252
+ // Line ending handling — follows the htmlFlow pattern
119253
+ function continuationStart(code) {
119254
+ return effects.check(syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
119255
+ }
119256
+ function continuationStartNonLazy(code) {
119257
+ effects.enter(types_types.lineEnding);
119258
+ effects.consume(code);
119259
+ effects.exit(types_types.lineEnding);
119260
+ return continuationBefore;
119261
+ }
119262
+ function continuationBefore(code) {
119263
+ if (code === null || markdownLineEnding(code)) {
119264
+ return continuationStart(code);
119265
+ }
119266
+ effects.enter('jsxTableData');
119267
+ return body(code);
119268
+ }
119269
+ function continuationAfter(code) {
119270
+ // At EOF without </Table>, reject so content isn't swallowed
119271
+ if (code === null) {
119272
+ return nok(code);
119273
+ }
119274
+ effects.exit('jsxTable');
119275
+ return ok(code);
119276
+ }
119277
+ }
119278
+ function syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
119279
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
119280
+ const self = this;
119281
+ return start;
119282
+ function start(code) {
119283
+ if (markdownLineEnding(code)) {
119284
+ effects.enter(types_types.lineEnding);
119285
+ effects.consume(code);
119286
+ effects.exit(types_types.lineEnding);
119287
+ return after;
119288
+ }
119289
+ return nok(code);
119290
+ }
119291
+ function after(code) {
119292
+ if (self.parser.lazy[self.now().line]) {
119293
+ return nok(code);
119294
+ }
119295
+ return ok(code);
119296
+ }
119297
+ }
119298
+ /**
119299
+ * Micromark extension that tokenizes `<Table>...</Table>` and `<table>...</table>`
119300
+ * as a single flow block.
119301
+ *
119302
+ * Prevents CommonMark HTML block type 6 from fragmenting table blocks at blank lines.
119303
+ */
119304
+ function syntax_jsxTable() {
119305
+ return {
119306
+ flow: {
119307
+ [codes.lessThan]: [jsxTableConstruct],
119308
+ },
119309
+ };
119310
+ }
119311
+
119312
+ ;// ./lib/micromark/jsx-table/index.ts
119313
+
119314
+
119315
+ ;// ./lib/micromark/magic-block/syntax.ts
119316
+
119317
+
119318
+ /**
119319
+ * Known magic block types that the tokenizer will recognize.
119320
+ * Unknown types will not be tokenized as magic blocks.
119321
+ */
119322
+ const KNOWN_BLOCK_TYPES = new Set([
119323
+ 'code',
119324
+ 'api-header',
119325
+ 'image',
119326
+ 'callout',
119327
+ 'parameters',
119328
+ 'table',
119329
+ 'embed',
119330
+ 'html',
119331
+ 'recipe',
119332
+ 'tutorial-tile',
119333
+ ]);
119334
+ /**
119335
+ * Check if a character is valid for a magic block type identifier.
119336
+ * Types can contain alphanumeric characters and hyphens (e.g., "api-header", "tutorial-tile")
119337
+ */
119338
+ function isTypeChar(code) {
119339
+ return asciiAlphanumeric(code) || code === codes.dash;
119340
+ }
119341
+ /**
119342
+ * Creates the opening marker state machine: [block:
119343
+ * Returns the first state function to start parsing.
119344
+ */
119345
+ function createOpeningMarkerParser(effects, nok, onComplete) {
119346
+ const expectB = (code) => {
119347
+ if (code !== codes.lowercaseB)
119348
+ return nok(code);
119349
+ effects.consume(code);
119350
+ return expectL;
119351
+ };
119352
+ const expectL = (code) => {
119353
+ if (code !== codes.lowercaseL)
119354
+ return nok(code);
119355
+ effects.consume(code);
119356
+ return expectO;
119357
+ };
119358
+ const expectO = (code) => {
119359
+ if (code !== codes.lowercaseO)
119360
+ return nok(code);
119361
+ effects.consume(code);
119362
+ return expectC;
119363
+ };
119364
+ const expectC = (code) => {
119365
+ if (code !== codes.lowercaseC)
119366
+ return nok(code);
119367
+ effects.consume(code);
119368
+ return expectK;
119369
+ };
119370
+ const expectK = (code) => {
119371
+ if (code !== codes.lowercaseK)
119372
+ return nok(code);
119373
+ effects.consume(code);
119374
+ return expectColon;
119375
+ };
119376
+ const expectColon = (code) => {
119377
+ if (code !== codes.colon)
119378
+ return nok(code);
119379
+ effects.consume(code);
119380
+ effects.exit('magicBlockMarkerStart');
119381
+ effects.enter('magicBlockType');
119382
+ return onComplete;
119383
+ };
119384
+ return expectB;
119385
+ }
119386
+ /**
119387
+ * Creates the type capture state machine.
119388
+ * Captures type characters until ] and validates against known types.
119389
+ */
119390
+ function createTypeCaptureParser(effects, nok, onComplete, blockTypeRef) {
119391
+ const captureTypeFirst = (code) => {
119392
+ // Reject empty type name [block:]
119393
+ if (code === codes.rightSquareBracket) {
119394
+ return nok(code);
119395
+ }
119396
+ if (isTypeChar(code)) {
119397
+ blockTypeRef.value += String.fromCharCode(code);
119398
+ effects.consume(code);
119399
+ return captureType;
119400
+ }
119401
+ return nok(code);
119402
+ };
119403
+ const captureType = (code) => {
119404
+ if (code === codes.rightSquareBracket) {
119405
+ if (!KNOWN_BLOCK_TYPES.has(blockTypeRef.value)) {
119406
+ return nok(code);
119407
+ }
119408
+ effects.exit('magicBlockType');
119409
+ effects.enter('magicBlockMarkerTypeEnd');
119410
+ effects.consume(code);
119411
+ effects.exit('magicBlockMarkerTypeEnd');
119412
+ return onComplete;
119413
+ }
119414
+ if (isTypeChar(code)) {
119415
+ blockTypeRef.value += String.fromCharCode(code);
119416
+ effects.consume(code);
119417
+ return captureType;
119418
+ }
119419
+ return nok(code);
119420
+ };
119421
+ return { first: captureTypeFirst, remaining: captureType };
119422
+ }
119423
+ /**
119424
+ * Creates the closing marker state machine: /block]
119425
+ * Handles partial matches by calling onMismatch to fall back to data capture.
119426
+ */
119427
+ function createClosingMarkerParser(effects, onSuccess, onMismatch, onEof, jsonState) {
119428
+ const handleMismatch = (code) => {
119429
+ if (jsonState && code === codes.quotationMark) {
119430
+ jsonState.inString = true;
119431
+ }
119432
+ return onMismatch(code);
119433
+ };
119434
+ const expectSlash = (code) => {
119435
+ if (code === null)
119436
+ return onEof(code);
119437
+ if (code !== codes.slash)
119438
+ return handleMismatch(code);
119439
+ effects.consume(code);
119440
+ return expectB;
119441
+ };
119442
+ const expectB = (code) => {
119443
+ if (code === null)
119444
+ return onEof(code);
119445
+ if (code !== codes.lowercaseB)
119446
+ return handleMismatch(code);
119447
+ effects.consume(code);
119448
+ return expectL;
119449
+ };
119450
+ const expectL = (code) => {
119451
+ if (code === null)
119452
+ return onEof(code);
119453
+ if (code !== codes.lowercaseL)
119454
+ return handleMismatch(code);
119455
+ effects.consume(code);
119456
+ return expectO;
119457
+ };
119458
+ const expectO = (code) => {
119459
+ if (code === null)
119460
+ return onEof(code);
119461
+ if (code !== codes.lowercaseO)
119462
+ return handleMismatch(code);
119463
+ effects.consume(code);
119464
+ return expectC;
119465
+ };
119466
+ const expectC = (code) => {
119467
+ if (code === null)
119468
+ return onEof(code);
119469
+ if (code !== codes.lowercaseC)
119470
+ return handleMismatch(code);
119471
+ effects.consume(code);
119472
+ return expectK;
119473
+ };
119474
+ const expectK = (code) => {
119475
+ if (code === null)
119476
+ return onEof(code);
119477
+ if (code !== codes.lowercaseK)
119478
+ return handleMismatch(code);
119479
+ effects.consume(code);
119480
+ return expectBracket;
119481
+ };
119482
+ const expectBracket = (code) => {
119483
+ if (code === null)
119484
+ return onEof(code);
119485
+ if (code !== codes.rightSquareBracket)
119486
+ return handleMismatch(code);
119487
+ effects.consume(code);
119488
+ return onSuccess;
119489
+ };
119490
+ return { expectSlash };
119491
+ }
119492
+ /**
119493
+ * Partial construct for checking non-lazy continuation.
119494
+ * This is used by the flow tokenizer to check if we can continue
119495
+ * parsing on the next line.
119496
+ */
119497
+ const syntax_nonLazyContinuation = {
119498
+ partial: true,
119499
+ tokenize: syntax_tokenizeNonLazyContinuation,
119500
+ };
119501
+ /**
119502
+ * Tokenizer for non-lazy continuation checking.
119503
+ * Returns ok if the next line is non-lazy (can continue), nok if lazy.
119504
+ */
119505
+ function syntax_tokenizeNonLazyContinuation(effects, ok, nok) {
119506
+ const lineStart = (code) => {
119507
+ // `this` here refers to the micromark parser
119508
+ // since we are just passing functions as references and not actually calling them
119509
+ // micromarks's internal parser will call this automatically with appropriate arguments
119510
+ return this.parser.lazy[this.now().line] ? nok(code) : ok(code);
119511
+ };
119512
+ const start = (code) => {
119513
+ if (code === null) {
119514
+ return nok(code);
119515
+ }
119516
+ if (!markdownLineEnding(code)) {
119517
+ return nok(code);
119518
+ }
119519
+ effects.enter('magicBlockLineEnding');
119520
+ effects.consume(code);
119521
+ effects.exit('magicBlockLineEnding');
119522
+ return lineStart;
119523
+ };
119524
+ return start;
119525
+ }
119526
+ /**
119527
+ * Create a micromark extension for magic block syntax.
119528
+ *
119529
+ * This extension handles both single-line and multiline magic blocks:
119530
+ * - Flow construct (concrete): Handles block-level multiline magic blocks at document level
119531
+ * - Text construct: Handles inline magic blocks in lists, paragraphs, etc.
119532
+ *
119533
+ * The flow construct is marked as "concrete" which prevents it from being
119534
+ * interrupted by container markers (like `>` for blockquotes or `-` for lists).
119535
+ */
119536
+ function syntax_magicBlock() {
119537
+ return {
119538
+ // Flow construct - handles block-level magic blocks at document root
119539
+ // Marked as concrete to prevent interruption by containers
119540
+ flow: {
119541
+ [codes.leftSquareBracket]: {
119542
+ name: 'magicBlock',
119543
+ concrete: true,
119544
+ tokenize: tokenizeMagicBlockFlow,
119545
+ },
119546
+ },
119547
+ // Text construct - handles magic blocks in inline contexts (lists, paragraphs)
119548
+ text: {
119549
+ [codes.leftSquareBracket]: {
119550
+ name: 'magicBlock',
119551
+ tokenize: tokenizeMagicBlockText,
119552
+ },
119553
+ },
119554
+ };
119555
+ }
119556
+ /**
119557
+ * Flow tokenizer for block-level magic blocks (multiline).
119558
+ * Uses the continuation checking pattern from code fences.
119559
+ */
119560
+ function tokenizeMagicBlockFlow(effects, ok, nok) {
119561
+ // State for tracking JSON content
119562
+ const jsonState = { escapeNext: false, inString: false };
119563
+ const blockTypeRef = { value: '' };
119564
+ let seenOpenBrace = false;
119565
+ // Create shared parsers for opening marker and type capture
119566
+ const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
119567
+ const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
119568
+ return start;
119569
+ function start(code) {
119570
+ if (code !== codes.leftSquareBracket)
119571
+ return nok(code);
119572
+ effects.enter('magicBlock');
119573
+ effects.enter('magicBlockMarkerStart');
119574
+ effects.consume(code);
119575
+ return openingMarkerParser;
119576
+ }
119577
+ /**
119578
+ * State before data content - handles line endings or starts data capture.
119579
+ */
119580
+ function beforeData(code) {
119581
+ // EOF - magic block must be closed
119582
+ if (code === null) {
119583
+ effects.exit('magicBlock');
119584
+ return nok(code);
119585
+ }
119586
+ // Line ending before any data - check continuation
119587
+ if (markdownLineEnding(code)) {
119588
+ return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
119589
+ }
119590
+ // Check for closing marker directly (without entering data)
119591
+ // This handles cases like [block:type]\n{}\n\n[/block] where there are
119592
+ // newlines after the data object
119593
+ if (code === codes.leftSquareBracket) {
119594
+ effects.enter('magicBlockMarkerEnd');
119595
+ effects.consume(code);
119596
+ return expectSlashFromContinuation;
119597
+ }
119598
+ // If we've already seen the opening brace, just continue capturing data
119599
+ if (seenOpenBrace) {
119600
+ effects.enter('magicBlockData');
119601
+ return captureData(code);
119602
+ }
119603
+ // Skip whitespace (spaces/tabs) before the data - stay in beforeData
119604
+ // Don't enter magicBlockData token yet until we confirm there's a '{'
119605
+ if (code === codes.space || code === codes.horizontalTab) {
119606
+ return beforeDataWhitespace(code);
119607
+ }
119608
+ // Data must start with '{' for valid JSON
119609
+ if (code !== codes.leftCurlyBrace) {
119610
+ effects.exit('magicBlock');
119611
+ return nok(code);
119612
+ }
119613
+ // We have '{' - enter data token and start capturing
119614
+ seenOpenBrace = true;
119615
+ effects.enter('magicBlockData');
119616
+ return captureData(code);
119617
+ }
119618
+ /**
119619
+ * Consume whitespace before the data without creating a token.
119620
+ * Uses a temporary token to satisfy micromark's requirement.
119621
+ */
119622
+ function beforeDataWhitespace(code) {
119623
+ if (code === null) {
119624
+ effects.exit('magicBlock');
119625
+ return nok(code);
119626
+ }
119627
+ if (markdownLineEnding(code)) {
119628
+ return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
119629
+ }
119630
+ if (code === codes.space || code === codes.horizontalTab) {
119631
+ // We need to consume this but can't without a token - use magicBlockData
119632
+ // and track that we haven't seen '{' yet
119633
+ effects.enter('magicBlockData');
119634
+ effects.consume(code);
119635
+ return beforeDataWhitespaceContinue;
119636
+ }
119637
+ if (code === codes.leftCurlyBrace) {
119638
+ seenOpenBrace = true;
119639
+ effects.enter('magicBlockData');
119640
+ return captureData(code);
119641
+ }
119642
+ effects.exit('magicBlock');
119643
+ return nok(code);
119644
+ }
119645
+ /**
119646
+ * Continue consuming whitespace or validate the opening brace.
119647
+ */
119648
+ function beforeDataWhitespaceContinue(code) {
119649
+ if (code === null) {
119650
+ effects.exit('magicBlockData');
119651
+ effects.exit('magicBlock');
119652
+ return nok(code);
119653
+ }
119654
+ if (markdownLineEnding(code)) {
119655
+ effects.exit('magicBlockData');
119656
+ return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
119657
+ }
119658
+ if (code === codes.space || code === codes.horizontalTab) {
119659
+ effects.consume(code);
119660
+ return beforeDataWhitespaceContinue;
119661
+ }
119662
+ if (code === codes.leftCurlyBrace) {
119663
+ seenOpenBrace = true;
119664
+ return captureData(code);
119665
+ }
119666
+ effects.exit('magicBlockData');
119667
+ effects.exit('magicBlock');
119668
+ return nok(code);
119669
+ }
119670
+ /**
119671
+ * Continuation OK before we've entered data token.
119672
+ */
119673
+ function continuationOkBeforeData(code) {
119674
+ effects.enter('magicBlockLineEnding');
119675
+ effects.consume(code);
119676
+ effects.exit('magicBlockLineEnding');
119677
+ return beforeData; // Stay in beforeData state - don't enter magicBlockData yet
119678
+ }
119679
+ function captureData(code) {
119680
+ // EOF - magic block must be closed
119681
+ if (code === null) {
119682
+ effects.exit('magicBlockData');
119683
+ effects.exit('magicBlock');
119684
+ return nok(code);
119685
+ }
119686
+ // At line ending, check if we can continue on the next line
119687
+ if (markdownLineEnding(code)) {
119688
+ effects.exit('magicBlockData');
119689
+ return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
119690
+ }
119691
+ if (jsonState.escapeNext) {
119692
+ jsonState.escapeNext = false;
119693
+ effects.consume(code);
119694
+ return captureData;
119695
+ }
119696
+ if (jsonState.inString) {
119697
+ if (code === codes.backslash) {
119698
+ jsonState.escapeNext = true;
119699
+ effects.consume(code);
119700
+ return captureData;
119701
+ }
119702
+ if (code === codes.quotationMark) {
119703
+ jsonState.inString = false;
119704
+ }
119705
+ effects.consume(code);
119706
+ return captureData;
119707
+ }
119708
+ if (code === codes.quotationMark) {
119709
+ jsonState.inString = true;
119710
+ effects.consume(code);
119711
+ return captureData;
119712
+ }
119713
+ if (code === codes.leftSquareBracket) {
119714
+ effects.exit('magicBlockData');
119715
+ effects.enter('magicBlockMarkerEnd');
119716
+ effects.consume(code);
119717
+ return expectSlash;
119718
+ }
119719
+ effects.consume(code);
119720
+ return captureData;
119721
+ }
119722
+ /**
119723
+ * Called when non-lazy continuation check passes - we can continue parsing.
119724
+ */
119725
+ function continuationOk(code) {
119726
+ // Consume the line ending
119727
+ effects.enter('magicBlockLineEnding');
119728
+ effects.consume(code);
119729
+ effects.exit('magicBlockLineEnding');
119730
+ return continuationStart;
119731
+ }
119732
+ /**
119733
+ * Start of continuation line - check for more line endings, closing marker, or start capturing data.
119734
+ */
119735
+ function continuationStart(code) {
119736
+ // Handle consecutive line endings
119737
+ if (code === null) {
119738
+ effects.exit('magicBlock');
119739
+ return nok(code);
119740
+ }
119741
+ if (markdownLineEnding(code)) {
119742
+ return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
119743
+ }
119744
+ // Check if this is the start of the closing marker [/block]
119745
+ // If so, handle it directly without entering magicBlockData
119746
+ if (code === codes.leftSquareBracket) {
119747
+ effects.enter('magicBlockMarkerEnd');
119748
+ effects.consume(code);
119749
+ return expectSlashFromContinuation;
119750
+ }
119751
+ effects.enter('magicBlockData');
119752
+ return captureData(code);
119753
+ }
119754
+ /**
119755
+ * Check for closing marker slash when coming from continuation.
119756
+ * If not a closing marker, create an empty data token and continue.
119757
+ */
119758
+ function expectSlashFromContinuation(code) {
119759
+ if (code === null) {
119760
+ effects.exit('magicBlockMarkerEnd');
119761
+ effects.exit('magicBlock');
119762
+ return nok(code);
119763
+ }
119764
+ if (markdownLineEnding(code)) {
119765
+ effects.exit('magicBlockMarkerEnd');
119766
+ return effects.check(syntax_nonLazyContinuation, continuationOkBeforeData, after)(code);
119767
+ }
119768
+ if (code === codes.slash) {
119769
+ effects.consume(code);
119770
+ return expectClosingB;
119771
+ }
119772
+ // Not a closing marker - this is data content
119773
+ // Exit marker and enter data
119774
+ effects.exit('magicBlockMarkerEnd');
119775
+ effects.enter('magicBlockData');
119776
+ // The [ was consumed by the marker, so we need to conceptually "have it" in our data
119777
+ // But since we already consumed it into the marker, we need a different approach
119778
+ // Re-classify: consume this character as data and continue
119779
+ if (code === codes.quotationMark)
119780
+ jsonState.inString = true;
119781
+ effects.consume(code);
119782
+ return captureData;
119783
+ }
119784
+ function expectSlash(code) {
119785
+ if (code === null) {
119786
+ effects.exit('magicBlockMarkerEnd');
119787
+ effects.exit('magicBlock');
119788
+ return nok(code);
119789
+ }
119790
+ // At line ending during marker parsing
119791
+ if (markdownLineEnding(code)) {
119792
+ effects.exit('magicBlockMarkerEnd');
119793
+ return effects.check(syntax_nonLazyContinuation, continuationOk, after)(code);
119794
+ }
119795
+ if (code !== codes.slash) {
119796
+ effects.exit('magicBlockMarkerEnd');
119797
+ effects.enter('magicBlockData');
119798
+ if (code === codes.quotationMark)
119799
+ jsonState.inString = true;
119800
+ effects.consume(code);
119801
+ return captureData;
119802
+ }
119803
+ effects.consume(code);
119804
+ return expectClosingB;
119805
+ }
119806
+ function expectClosingB(code) {
119807
+ if (code === null) {
119808
+ effects.exit('magicBlockMarkerEnd');
119809
+ effects.exit('magicBlock');
119810
+ return nok(code);
119811
+ }
119812
+ if (code !== codes.lowercaseB) {
119813
+ effects.exit('magicBlockMarkerEnd');
119814
+ effects.enter('magicBlockData');
119815
+ if (code === codes.quotationMark)
119816
+ jsonState.inString = true;
119817
+ effects.consume(code);
119818
+ return captureData;
119819
+ }
119820
+ effects.consume(code);
119821
+ return expectClosingL;
119822
+ }
119823
+ function expectClosingL(code) {
119824
+ if (code === null) {
119825
+ effects.exit('magicBlockMarkerEnd');
119826
+ effects.exit('magicBlock');
119827
+ return nok(code);
119828
+ }
119829
+ if (code !== codes.lowercaseL) {
119830
+ effects.exit('magicBlockMarkerEnd');
119831
+ effects.enter('magicBlockData');
119832
+ if (code === codes.quotationMark)
119833
+ jsonState.inString = true;
119834
+ effects.consume(code);
119835
+ return captureData;
119836
+ }
119837
+ effects.consume(code);
119838
+ return expectClosingO;
119839
+ }
119840
+ function expectClosingO(code) {
119841
+ if (code === null) {
119842
+ effects.exit('magicBlockMarkerEnd');
119843
+ effects.exit('magicBlock');
119844
+ return nok(code);
119845
+ }
119846
+ if (code !== codes.lowercaseO) {
119847
+ effects.exit('magicBlockMarkerEnd');
119848
+ effects.enter('magicBlockData');
119849
+ if (code === codes.quotationMark)
119850
+ jsonState.inString = true;
119851
+ effects.consume(code);
119852
+ return captureData;
119853
+ }
119854
+ effects.consume(code);
119855
+ return expectClosingC;
119856
+ }
119857
+ function expectClosingC(code) {
119858
+ if (code === null) {
119859
+ effects.exit('magicBlockMarkerEnd');
119860
+ effects.exit('magicBlock');
119861
+ return nok(code);
119862
+ }
119863
+ if (code !== codes.lowercaseC) {
119864
+ effects.exit('magicBlockMarkerEnd');
119865
+ effects.enter('magicBlockData');
119866
+ if (code === codes.quotationMark)
119867
+ jsonState.inString = true;
119868
+ effects.consume(code);
119869
+ return captureData;
119870
+ }
119871
+ effects.consume(code);
119872
+ return expectClosingK;
119873
+ }
119874
+ function expectClosingK(code) {
119875
+ if (code === null) {
119876
+ effects.exit('magicBlockMarkerEnd');
119877
+ effects.exit('magicBlock');
119878
+ return nok(code);
119879
+ }
119880
+ if (code !== codes.lowercaseK) {
119881
+ effects.exit('magicBlockMarkerEnd');
119882
+ effects.enter('magicBlockData');
119883
+ if (code === codes.quotationMark)
119884
+ jsonState.inString = true;
119885
+ effects.consume(code);
119886
+ return captureData;
119887
+ }
119888
+ effects.consume(code);
119889
+ return expectClosingBracket;
119890
+ }
119891
+ function expectClosingBracket(code) {
119892
+ if (code === null) {
119893
+ effects.exit('magicBlockMarkerEnd');
119894
+ effects.exit('magicBlock');
119895
+ return nok(code);
119896
+ }
119897
+ if (code !== codes.rightSquareBracket) {
119898
+ effects.exit('magicBlockMarkerEnd');
119899
+ effects.enter('magicBlockData');
119900
+ if (code === codes.quotationMark)
119901
+ jsonState.inString = true;
119902
+ effects.consume(code);
119903
+ return captureData;
119904
+ }
119905
+ effects.consume(code);
119906
+ effects.exit('magicBlockMarkerEnd');
119907
+ // Check for trailing whitespace on the same line
119908
+ return consumeTrailing;
119909
+ }
119910
+ /**
119911
+ * Consume trailing whitespace (spaces/tabs) on the same line after [/block].
119912
+ * For concrete flow constructs, we must end at eol/eof or fail.
119913
+ * Trailing whitespace is consumed; other content causes nok (text tokenizer handles it).
119914
+ */
119915
+ function consumeTrailing(code) {
119916
+ // End of file - done
119917
+ if (code === null) {
119918
+ effects.exit('magicBlock');
119919
+ return ok(code);
119920
+ }
119921
+ // Line ending - done
119922
+ if (markdownLineEnding(code)) {
119923
+ effects.exit('magicBlock');
119924
+ return ok(code);
119925
+ }
119926
+ // Space or tab - consume as trailing whitespace
119927
+ if (code === codes.space || code === codes.horizontalTab) {
119928
+ effects.enter('magicBlockTrailing');
119929
+ effects.consume(code);
119930
+ return consumeTrailingContinue;
119931
+ }
119932
+ // Any other character - fail flow tokenizer, let text tokenizer handle it
119933
+ effects.exit('magicBlock');
119934
+ return nok(code);
119935
+ }
119936
+ /**
119937
+ * Continue consuming trailing whitespace.
119938
+ */
119939
+ function consumeTrailingContinue(code) {
119940
+ // End of file - done
119941
+ if (code === null) {
119942
+ effects.exit('magicBlockTrailing');
119943
+ effects.exit('magicBlock');
119944
+ return ok(code);
119945
+ }
119946
+ // Line ending - done
119947
+ if (markdownLineEnding(code)) {
119948
+ effects.exit('magicBlockTrailing');
119949
+ effects.exit('magicBlock');
119950
+ return ok(code);
119951
+ }
119952
+ // More space or tab - keep consuming
119953
+ if (code === codes.space || code === codes.horizontalTab) {
119954
+ effects.consume(code);
119955
+ return consumeTrailingContinue;
119956
+ }
119957
+ // Non-whitespace after whitespace - fail flow tokenizer
119958
+ effects.exit('magicBlockTrailing');
119959
+ effects.exit('magicBlock');
119960
+ return nok(code);
119961
+ }
119962
+ /**
119963
+ * Called when we can't continue (lazy line or EOF) - exit the construct.
119964
+ */
119965
+ function after(code) {
119966
+ effects.exit('magicBlock');
119967
+ return nok(code);
119968
+ }
119969
+ }
119970
+ /**
119971
+ * Text tokenizer for single-line magic blocks only.
119972
+ * Used in inline contexts like list items and paragraphs.
119973
+ * Multiline blocks are handled by the flow tokenizer.
119974
+ */
119975
+ function tokenizeMagicBlockText(effects, ok, nok) {
119976
+ // State for tracking JSON content
119977
+ const jsonState = { escapeNext: false, inString: false };
119978
+ const blockTypeRef = { value: '' };
119979
+ let seenOpenBrace = false;
119980
+ // Create shared parsers for opening marker and type capture
119981
+ const typeParser = createTypeCaptureParser(effects, nok, beforeData, blockTypeRef);
119982
+ const openingMarkerParser = createOpeningMarkerParser(effects, nok, typeParser.first);
119983
+ // Success handler for closing marker - exits tokens and returns ok
119984
+ const closingSuccess = (code) => {
119985
+ effects.exit('magicBlockMarkerEnd');
119986
+ effects.exit('magicBlock');
119987
+ return ok(code);
119988
+ };
119989
+ // Mismatch handler - falls back to data capture
119990
+ const closingMismatch = (code) => {
119991
+ effects.exit('magicBlockMarkerEnd');
119992
+ effects.enter('magicBlockData');
119993
+ if (code === codes.quotationMark)
119994
+ jsonState.inString = true;
119995
+ effects.consume(code);
119996
+ return captureData;
119997
+ };
119998
+ // EOF handler
119999
+ const closingEof = (_code) => nok(_code);
120000
+ // Create closing marker parsers
120001
+ const closingFromBeforeData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
120002
+ const closingFromData = createClosingMarkerParser(effects, closingSuccess, closingMismatch, closingEof, jsonState);
120003
+ return start;
120004
+ function start(code) {
120005
+ if (code !== codes.leftSquareBracket)
120006
+ return nok(code);
120007
+ effects.enter('magicBlock');
120008
+ effects.enter('magicBlockMarkerStart');
120009
+ effects.consume(code);
120010
+ return openingMarkerParser;
120011
+ }
120012
+ /**
120013
+ * State before data content - handles line endings before entering data token.
120014
+ * Whitespace before '{' is allowed.
120015
+ */
120016
+ function beforeData(code) {
120017
+ // Fail on EOF - magic block must be closed
120018
+ if (code === null) {
120019
+ return nok(code);
120020
+ }
120021
+ // Handle line endings before any data - consume them without entering data token
120022
+ if (markdownLineEnding(code)) {
120023
+ effects.enter('magicBlockLineEnding');
120024
+ effects.consume(code);
120025
+ effects.exit('magicBlockLineEnding');
120026
+ return beforeData;
120027
+ }
120028
+ // Check for closing marker directly (without entering data)
120029
+ if (code === codes.leftSquareBracket) {
120030
+ effects.enter('magicBlockMarkerEnd');
120031
+ effects.consume(code);
120032
+ return closingFromBeforeData.expectSlash;
120033
+ }
120034
+ // If we've already seen the opening brace, just continue capturing data
120035
+ if (seenOpenBrace) {
120036
+ effects.enter('magicBlockData');
120037
+ return captureData(code);
120038
+ }
120039
+ // Skip whitespace (spaces/tabs) before the data
120040
+ if (code === codes.space || code === codes.horizontalTab) {
120041
+ return beforeDataWhitespace(code);
120042
+ }
120043
+ // Data must start with '{' for valid JSON
120044
+ if (code !== codes.leftCurlyBrace) {
120045
+ return nok(code);
120046
+ }
120047
+ // We have '{' - enter data token and start capturing
120048
+ seenOpenBrace = true;
120049
+ effects.enter('magicBlockData');
120050
+ return captureData(code);
120051
+ }
120052
+ /**
120053
+ * Consume whitespace before the data.
120054
+ */
120055
+ function beforeDataWhitespace(code) {
120056
+ if (code === null) {
120057
+ return nok(code);
120058
+ }
120059
+ if (markdownLineEnding(code)) {
120060
+ effects.enter('magicBlockLineEnding');
120061
+ effects.consume(code);
120062
+ effects.exit('magicBlockLineEnding');
120063
+ return beforeData;
120064
+ }
120065
+ if (code === codes.space || code === codes.horizontalTab) {
120066
+ effects.enter('magicBlockData');
120067
+ effects.consume(code);
120068
+ return beforeDataWhitespaceContinue;
120069
+ }
120070
+ if (code === codes.leftCurlyBrace) {
120071
+ seenOpenBrace = true;
120072
+ effects.enter('magicBlockData');
120073
+ return captureData(code);
120074
+ }
120075
+ return nok(code);
120076
+ }
120077
+ /**
120078
+ * Continue consuming whitespace or validate the opening brace.
120079
+ */
120080
+ function beforeDataWhitespaceContinue(code) {
120081
+ if (code === null) {
120082
+ effects.exit('magicBlockData');
120083
+ return nok(code);
120084
+ }
120085
+ if (markdownLineEnding(code)) {
120086
+ effects.exit('magicBlockData');
120087
+ effects.enter('magicBlockLineEnding');
120088
+ effects.consume(code);
120089
+ effects.exit('magicBlockLineEnding');
120090
+ return beforeData;
120091
+ }
120092
+ if (code === codes.space || code === codes.horizontalTab) {
120093
+ effects.consume(code);
120094
+ return beforeDataWhitespaceContinue;
120095
+ }
120096
+ if (code === codes.leftCurlyBrace) {
120097
+ seenOpenBrace = true;
120098
+ return captureData(code);
120099
+ }
120100
+ effects.exit('magicBlockData');
120101
+ return nok(code);
120102
+ }
120103
+ function captureData(code) {
120104
+ // Fail on EOF - magic block must be closed
120105
+ if (code === null) {
120106
+ effects.exit('magicBlockData');
120107
+ return nok(code);
120108
+ }
120109
+ // Handle multiline magic blocks within text/paragraphs
120110
+ // Exit data, consume line ending with proper token, then re-enter data
120111
+ if (markdownLineEnding(code)) {
120112
+ effects.exit('magicBlockData');
120113
+ effects.enter('magicBlockLineEnding');
120114
+ effects.consume(code);
120115
+ effects.exit('magicBlockLineEnding');
120116
+ return beforeData; // Go back to beforeData to handle potential empty lines
120117
+ }
120118
+ if (jsonState.escapeNext) {
120119
+ jsonState.escapeNext = false;
120120
+ effects.consume(code);
120121
+ return captureData;
120122
+ }
120123
+ if (jsonState.inString) {
120124
+ if (code === codes.backslash) {
120125
+ jsonState.escapeNext = true;
120126
+ effects.consume(code);
120127
+ return captureData;
120128
+ }
120129
+ if (code === codes.quotationMark) {
120130
+ jsonState.inString = false;
120131
+ }
120132
+ effects.consume(code);
120133
+ return captureData;
120134
+ }
120135
+ if (code === codes.quotationMark) {
120136
+ jsonState.inString = true;
120137
+ effects.consume(code);
120138
+ return captureData;
120139
+ }
120140
+ if (code === codes.leftSquareBracket) {
120141
+ effects.exit('magicBlockData');
120142
+ effects.enter('magicBlockMarkerEnd');
120143
+ effects.consume(code);
120144
+ return closingFromData.expectSlash;
120145
+ }
120146
+ effects.consume(code);
120147
+ return captureData;
120148
+ }
120149
+ }
120150
+ /* harmony default export */ const syntax = ((/* unused pure expression or super */ null && (syntax_magicBlock)));
120151
+
120152
+ ;// ./lib/micromark/magic-block/index.ts
120153
+ /**
120154
+ * Micromark extension for magic block syntax.
120155
+ *
120156
+ * Usage:
120157
+ * ```ts
120158
+ * import { magicBlock } from './lib/micromark/magic-block';
120159
+ *
120160
+ * const processor = unified()
120161
+ * .data('micromarkExtensions', [magicBlock()])
120162
+ * ```
120163
+ */
119893
120164
 
119894
- // Internal types used for subtokenizers, compiled away
119895
- chunkDocument: 'chunkDocument',
119896
- chunkContent: 'chunkContent',
119897
- chunkFlow: 'chunkFlow',
119898
- chunkText: 'chunkText',
119899
- chunkString: 'chunkString'
119900
- })
119901
120165
 
119902
120166
  ;// ./lib/micromark/mdx-component/syntax.ts
119903
120167
 
@@ -119914,8 +120178,8 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
119914
120178
  // blank lines between nested JSX siblings don't fragment the block. Excludes table
119915
120179
  // tags (mdxishTables owns their blank lines) and voids (never close).
119916
120180
  const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
119917
- const syntax_nonLazyContinuationStart = {
119918
- tokenize: syntax_tokenizeNonLazyContinuationStart,
120181
+ const mdx_component_syntax_nonLazyContinuationStart = {
120182
+ tokenize: mdx_component_syntax_tokenizeNonLazyContinuationStart,
119919
120183
  partial: true,
119920
120184
  };
119921
120185
  // Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
@@ -120009,11 +120273,11 @@ function createTokenize(mode) {
120009
120273
  // When a } brings braceDepth back to a saved value, we return to the
120010
120274
  // template literal instead of continuing in the brace expression.
120011
120275
  const templateStack = [];
120012
- const isAlpha = (code) => (code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) ||
120013
- (code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ);
120276
+ const isAlpha = (code) => (code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
120277
+ (code >= codes.lowercaseA && code <= codes.lowercaseZ);
120014
120278
  const isSameCaseAsTag = (code) => isLowercaseTag
120015
- ? code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ
120016
- : code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ;
120279
+ ? code >= codes.lowercaseA && code <= codes.lowercaseZ
120280
+ : code >= codes.uppercaseA && code <= codes.uppercaseZ;
120017
120281
  // Shared brace-expression state machine. The two call sites differ only in where
120018
120282
  // to continue after a line ending and where to return when braceDepth reaches zero.
120019
120283
  function createBraceExprStates(continuationStart, afterBraceClose) {
@@ -120026,22 +120290,22 @@ function createTokenize(mode) {
120026
120290
  effects.exit('mdxComponentData');
120027
120291
  return continuationStart(code);
120028
120292
  }
120029
- if (code === codes_codes.quotationMark || code === codes_codes.apostrophe) {
120293
+ if (code === codes.quotationMark || code === codes.apostrophe) {
120030
120294
  quoteChar = code;
120031
120295
  effects.consume(code);
120032
120296
  return braceString;
120033
120297
  }
120034
- if (code === codes_codes.graveAccent) {
120298
+ if (code === codes.graveAccent) {
120035
120299
  inTemplateLit = true;
120036
120300
  effects.consume(code);
120037
120301
  return braceTemplateLiteral;
120038
120302
  }
120039
- if (code === codes_codes.leftCurlyBrace) {
120303
+ if (code === codes.leftCurlyBrace) {
120040
120304
  braceDepth += 1;
120041
120305
  effects.consume(code);
120042
120306
  return braceExpr;
120043
120307
  }
120044
- if (code === codes_codes.rightCurlyBrace) {
120308
+ if (code === codes.rightCurlyBrace) {
120045
120309
  braceDepth -= 1;
120046
120310
  effects.consume(code);
120047
120311
  if (templateStack.length > 0 && braceDepth === templateStack[templateStack.length - 1]) {
@@ -120066,7 +120330,7 @@ function createTokenize(mode) {
120066
120330
  effects.exit('mdxComponentData');
120067
120331
  return continuationStart(code);
120068
120332
  }
120069
- if (code === codes_codes.backslash) {
120333
+ if (code === codes.backslash) {
120070
120334
  effects.consume(code);
120071
120335
  return braceStringEscape;
120072
120336
  }
@@ -120094,16 +120358,16 @@ function createTokenize(mode) {
120094
120358
  effects.exit('mdxComponentData');
120095
120359
  return continuationStart(code);
120096
120360
  }
120097
- if (code === codes_codes.graveAccent) {
120361
+ if (code === codes.graveAccent) {
120098
120362
  inTemplateLit = false;
120099
120363
  effects.consume(code);
120100
120364
  return braceExpr;
120101
120365
  }
120102
- if (code === codes_codes.backslash) {
120366
+ if (code === codes.backslash) {
120103
120367
  effects.consume(code);
120104
120368
  return braceTemplateLiteralEscape;
120105
120369
  }
120106
- if (code === codes_codes.dollarSign) {
120370
+ if (code === codes.dollarSign) {
120107
120371
  effects.consume(code);
120108
120372
  return braceTemplateLiteralDollar;
120109
120373
  }
@@ -120118,7 +120382,7 @@ function createTokenize(mode) {
120118
120382
  return braceTemplateLiteral;
120119
120383
  }
120120
120384
  function braceTemplateLiteralDollar(code) {
120121
- if (code === codes_codes.leftCurlyBrace) {
120385
+ if (code === codes.leftCurlyBrace) {
120122
120386
  templateStack.push(braceDepth);
120123
120387
  braceDepth += 1;
120124
120388
  inTemplateLit = false;
@@ -120134,7 +120398,7 @@ function createTokenize(mode) {
120134
120398
  return start;
120135
120399
  // ── Start ──────────────────────────────────────────────────────────────
120136
120400
  function start(code) {
120137
- if (code !== codes_codes.lessThan)
120401
+ if (code !== codes.lessThan)
120138
120402
  return nok(code);
120139
120403
  effects.enter('mdxComponent');
120140
120404
  effects.enter('mdxComponentData');
@@ -120146,7 +120410,7 @@ function createTokenize(mode) {
120146
120410
  // Uppercase A-Z → PascalCase MDX component. Flow mode claims block
120147
120411
  // components; text mode only claims inline components (Anchor, Glossary),
120148
120412
  // which is enforced once the full name is known in `tagNameRest`.
120149
- if (code !== null && code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) {
120413
+ if (code !== null && code >= codes.uppercaseA && code <= codes.uppercaseZ) {
120150
120414
  tagName = String.fromCharCode(code);
120151
120415
  isLowercaseTag = false;
120152
120416
  sawBraceAttr = false;
@@ -120156,7 +120420,7 @@ function createTokenize(mode) {
120156
120420
  // Lowercase a-z → HTML tag (claim only if `{...}` attr appears). In
120157
120421
  // flow mode, refuse to interrupt a paragraph — same rule as html-flow
120158
120422
  // type-7. The text variant picks these up during inline parsing.
120159
- if (code !== null && code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ) {
120423
+ if (code !== null && code >= codes.lowercaseA && code <= codes.lowercaseZ) {
120160
120424
  if (isFlow && self.interrupt)
120161
120425
  return nok(code);
120162
120426
  tagName = String.fromCharCode(code);
@@ -120169,10 +120433,10 @@ function createTokenize(mode) {
120169
120433
  }
120170
120434
  function tagNameRest(code) {
120171
120435
  if (code !== null &&
120172
- ((code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) ||
120173
- (code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ) ||
120174
- (code >= codes_codes.digit0 && code <= codes_codes.digit9) ||
120175
- code === codes_codes.underscore)) {
120436
+ ((code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
120437
+ (code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
120438
+ (code >= codes.digit0 && code <= codes.digit9) ||
120439
+ code === codes.underscore)) {
120176
120440
  tagName += String.fromCharCode(code);
120177
120441
  effects.consume(code);
120178
120442
  return tagNameRest;
@@ -120207,14 +120471,14 @@ function createTokenize(mode) {
120207
120471
  return openTagContinuationStart(code);
120208
120472
  }
120209
120473
  // Self-closing />
120210
- if (code === codes_codes.slash) {
120474
+ if (code === codes.slash) {
120211
120475
  if (requiresBraceAttr && !sawBraceAttr)
120212
120476
  return nok(code);
120213
120477
  effects.consume(code);
120214
120478
  return selfCloseGt;
120215
120479
  }
120216
120480
  // End of opening tag
120217
- if (code === codes_codes.greaterThan) {
120481
+ if (code === codes.greaterThan) {
120218
120482
  if (requiresBraceAttr && !sawBraceAttr) {
120219
120483
  // Plain lowercase block tags stay claimable in flow, gated per line by
120220
120484
  // `plainClaimLineStart`; everything else falls through to CommonMark.
@@ -120227,13 +120491,13 @@ function createTokenize(mode) {
120227
120491
  return body;
120228
120492
  }
120229
120493
  // Quoted attribute value
120230
- if (code === codes_codes.quotationMark || code === codes_codes.apostrophe) {
120494
+ if (code === codes.quotationMark || code === codes.apostrophe) {
120231
120495
  quoteChar = code;
120232
120496
  effects.consume(code);
120233
120497
  return inQuotedAttr;
120234
120498
  }
120235
120499
  // JSX expression attribute
120236
- if (code === codes_codes.leftCurlyBrace) {
120500
+ if (code === codes.leftCurlyBrace) {
120237
120501
  braceDepth = 1;
120238
120502
  sawBraceAttr = true;
120239
120503
  effects.consume(code);
@@ -120251,7 +120515,7 @@ function createTokenize(mode) {
120251
120515
  effects.exit('mdxComponentData');
120252
120516
  return openTagContinuationStart(code);
120253
120517
  }
120254
- if (code === codes_codes.backslash) {
120518
+ if (code === codes.backslash) {
120255
120519
  effects.consume(code);
120256
120520
  return inQuotedAttrEscape;
120257
120521
  }
@@ -120271,7 +120535,7 @@ function createTokenize(mode) {
120271
120535
  return inQuotedAttr;
120272
120536
  }
120273
120537
  function selfCloseGt(code) {
120274
- if (code === codes_codes.greaterThan) {
120538
+ if (code === codes.greaterThan) {
120275
120539
  effects.consume(code);
120276
120540
  // Self-closing tag completes the token
120277
120541
  return afterClose;
@@ -120281,7 +120545,7 @@ function createTokenize(mode) {
120281
120545
  }
120282
120546
  // Continuation for multi-line opening tags
120283
120547
  function openTagContinuationStart(code) {
120284
- return effects.check(syntax_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
120548
+ return effects.check(mdx_component_syntax_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
120285
120549
  }
120286
120550
  function openTagContinuationNonLazy(code) {
120287
120551
  sawLineEnding = true;
@@ -120324,25 +120588,25 @@ function createTokenize(mode) {
120324
120588
  atLineStart = true;
120325
120589
  return bodyContinuationStart(code);
120326
120590
  }
120327
- if (code !== codes_codes.space && code !== codes_codes.horizontalTab) {
120591
+ if (code !== codes.space && code !== codes.horizontalTab) {
120328
120592
  openerLineHasContent = true;
120329
120593
  }
120330
- if (code === codes_codes.backslash) {
120594
+ if (code === codes.backslash) {
120331
120595
  effects.consume(code);
120332
120596
  return bodyEscapedChar;
120333
120597
  }
120334
- if (code === codes_codes.lessThan) {
120598
+ if (code === codes.lessThan) {
120335
120599
  effects.consume(code);
120336
120600
  return bodyLessThan;
120337
120601
  }
120338
120602
  // Code span tracking
120339
- if (code === codes_codes.graveAccent) {
120603
+ if (code === codes.graveAccent) {
120340
120604
  codeSpanOpenSize = 0;
120341
120605
  return countOpenTicks(code);
120342
120606
  }
120343
120607
  // JSX expression child — track braces/template literals so the closing
120344
120608
  // backtick of `{`...`}` is not misread as a code span opener
120345
- if (code === codes_codes.leftCurlyBrace) {
120609
+ if (code === codes.leftCurlyBrace) {
120346
120610
  braceDepth = 1;
120347
120611
  inTemplateLit = false;
120348
120612
  effects.consume(code);
@@ -120362,14 +120626,14 @@ function createTokenize(mode) {
120362
120626
  }
120363
120627
  // ── Code span handling ─────────────────────────────────────────────────
120364
120628
  function countOpenTicks(code) {
120365
- if (code === codes_codes.graveAccent) {
120629
+ if (code === codes.graveAccent) {
120366
120630
  codeSpanOpenSize += 1;
120367
120631
  effects.consume(code);
120368
120632
  return countOpenTicks;
120369
120633
  }
120370
120634
  // 3+ backticks at line start = fenced code block
120371
120635
  if (atLineStart && codeSpanOpenSize >= 3) {
120372
- fenceChar = codes_codes.graveAccent;
120636
+ fenceChar = codes.graveAccent;
120373
120637
  fenceLength = codeSpanOpenSize;
120374
120638
  atLineStart = false;
120375
120639
  return inFencedCode(code);
@@ -120379,7 +120643,7 @@ function createTokenize(mode) {
120379
120643
  function inCodeSpan(code) {
120380
120644
  if (code === null || markdownLineEnding(code))
120381
120645
  return body(code);
120382
- if (code === codes_codes.graveAccent) {
120646
+ if (code === codes.graveAccent) {
120383
120647
  codeSpanCloseSize = 0;
120384
120648
  return countCloseTicks(code);
120385
120649
  }
@@ -120387,7 +120651,7 @@ function createTokenize(mode) {
120387
120651
  return inCodeSpan;
120388
120652
  }
120389
120653
  function countCloseTicks(code) {
120390
- if (code === codes_codes.graveAccent) {
120654
+ if (code === codes.graveAccent) {
120391
120655
  codeSpanCloseSize += 1;
120392
120656
  effects.consume(code);
120393
120657
  return countCloseTicks;
@@ -120406,7 +120670,7 @@ function createTokenize(mode) {
120406
120670
  return inFencedCode;
120407
120671
  }
120408
120672
  function fencedCodeContinuationStart(code) {
120409
- return effects.check(syntax_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
120673
+ return effects.check(mdx_component_syntax_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
120410
120674
  }
120411
120675
  function fencedCodeContinuationNonLazy(code) {
120412
120676
  sawLineEnding = true;
@@ -120421,6 +120685,16 @@ function createTokenize(mode) {
120421
120685
  }
120422
120686
  effects.enter('mdxComponentData');
120423
120687
  fenceCloseLength = 0;
120688
+ return fencedCodeMaybeClose(code);
120689
+ }
120690
+ // Skip leading indentation before the closing-fence check: an indented fence
120691
+ // (the norm in a component body) closes on an equally-indented line, else the
120692
+ // closer is never matched and scanning runs to EOF (CX-3704).
120693
+ function fencedCodeMaybeClose(code) {
120694
+ if (markdownSpace(code)) {
120695
+ effects.consume(code);
120696
+ return fencedCodeMaybeClose;
120697
+ }
120424
120698
  // Check for closing fence
120425
120699
  if (code === fenceChar) {
120426
120700
  fenceCloseLength = 1;
@@ -120450,7 +120724,7 @@ function createTokenize(mode) {
120450
120724
  return body(code);
120451
120725
  }
120452
120726
  // Only spaces/tabs allowed after closing fence
120453
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
120727
+ if (code === codes.space || code === codes.horizontalTab) {
120454
120728
  effects.consume(code);
120455
120729
  return fenceCloseTrailing;
120456
120730
  }
@@ -120459,7 +120733,7 @@ function createTokenize(mode) {
120459
120733
  }
120460
120734
  // ── Tilde fenced code detection ────────────────────────────────────────
120461
120735
  function bodyAfterLineStart(code) {
120462
- if (code === codes_codes.tilde) {
120736
+ if (code === codes.tilde) {
120463
120737
  fenceCloseLength = 1;
120464
120738
  effects.consume(code);
120465
120739
  return countTildes;
@@ -120468,13 +120742,13 @@ function createTokenize(mode) {
120468
120742
  return body(code);
120469
120743
  }
120470
120744
  function countTildes(code) {
120471
- if (code === codes_codes.tilde) {
120745
+ if (code === codes.tilde) {
120472
120746
  fenceCloseLength += 1;
120473
120747
  effects.consume(code);
120474
120748
  return countTildes;
120475
120749
  }
120476
120750
  if (fenceCloseLength >= 3) {
120477
- fenceChar = codes_codes.tilde;
120751
+ fenceChar = codes.tilde;
120478
120752
  fenceLength = fenceCloseLength;
120479
120753
  return inFencedCode(code);
120480
120754
  }
@@ -120484,7 +120758,7 @@ function createTokenize(mode) {
120484
120758
  }
120485
120759
  // ── Tag detection inside body ──────────────────────────────────────────
120486
120760
  function bodyLessThan(code) {
120487
- if (code === codes_codes.slash) {
120761
+ if (code === codes.slash) {
120488
120762
  if (onOpenerLine)
120489
120763
  openerLineCloses += 1;
120490
120764
  effects.consume(code);
@@ -120511,10 +120785,10 @@ function createTokenize(mode) {
120511
120785
  // ── Nested opening tag ─────────────────────────────────────────────────
120512
120786
  function nestedOpenTagName(code) {
120513
120787
  if (code !== null &&
120514
- ((code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) ||
120515
- (code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ) ||
120516
- (code >= codes_codes.digit0 && code <= codes_codes.digit9) ||
120517
- code === codes_codes.underscore)) {
120788
+ ((code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
120789
+ (code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
120790
+ (code >= codes.digit0 && code <= codes.digit9) ||
120791
+ code === codes.underscore)) {
120518
120792
  closingTagName += String.fromCharCode(code);
120519
120793
  effects.consume(code);
120520
120794
  return nestedOpenTagName;
@@ -120522,10 +120796,10 @@ function createTokenize(mode) {
120522
120796
  // Same-name opener followed by a tag-end char bumps depth. A line ending
120523
120797
  // counts too: Prettier puts a newline right after the name (`<div\n …\n>`).
120524
120798
  if (closingTagName === tagName &&
120525
- (code === codes_codes.greaterThan ||
120526
- code === codes_codes.slash ||
120527
- code === codes_codes.space ||
120528
- code === codes_codes.horizontalTab ||
120799
+ (code === codes.greaterThan ||
120800
+ code === codes.slash ||
120801
+ code === codes.space ||
120802
+ code === codes.horizontalTab ||
120529
120803
  markdownLineEnding(code))) {
120530
120804
  depth += 1;
120531
120805
  }
@@ -120544,15 +120818,15 @@ function createTokenize(mode) {
120544
120818
  }
120545
120819
  function closingTagNameRest(code) {
120546
120820
  if (code !== null &&
120547
- ((code >= codes_codes.uppercaseA && code <= codes_codes.uppercaseZ) ||
120548
- (code >= codes_codes.lowercaseA && code <= codes_codes.lowercaseZ) ||
120549
- (code >= codes_codes.digit0 && code <= codes_codes.digit9) ||
120550
- code === codes_codes.underscore)) {
120821
+ ((code >= codes.uppercaseA && code <= codes.uppercaseZ) ||
120822
+ (code >= codes.lowercaseA && code <= codes.lowercaseZ) ||
120823
+ (code >= codes.digit0 && code <= codes.digit9) ||
120824
+ code === codes.underscore)) {
120551
120825
  closingTagName += String.fromCharCode(code);
120552
120826
  effects.consume(code);
120553
120827
  return closingTagNameRest;
120554
120828
  }
120555
- if (closingTagName === tagName && code === codes_codes.greaterThan) {
120829
+ if (closingTagName === tagName && code === codes.greaterThan) {
120556
120830
  depth -= 1;
120557
120831
  effects.consume(code);
120558
120832
  if (depth === 0) {
@@ -120604,7 +120878,7 @@ function createTokenize(mode) {
120604
120878
  }
120605
120879
  // ── Body continuation (line endings) ───────────────────────────────────
120606
120880
  function bodyContinuationStart(code) {
120607
- return effects.check(syntax_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
120881
+ return effects.check(mdx_component_syntax_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
120608
120882
  }
120609
120883
  function bodyContinuationNonLazy(code) {
120610
120884
  sawLineEnding = true;
@@ -120636,9 +120910,16 @@ function createTokenize(mode) {
120636
120910
  }
120637
120911
  // Dispatch a non-blank continuation line: fenced code at line start, else body.
120638
120912
  function bodyLineStart(code) {
120639
- if (atLineStart && code === codes_codes.tilde)
120913
+ // Skip leading indentation while staying "at line start" so an indented
120914
+ // fence is still recognized. Otherwise the first space clears `atLineStart`
120915
+ // and its content — including any unbalanced `{` — stays live text (CX-3704).
120916
+ if (atLineStart && markdownSpace(code)) {
120917
+ effects.consume(code);
120918
+ return bodyLineStart;
120919
+ }
120920
+ if (atLineStart && code === codes.tilde)
120640
120921
  return bodyAfterLineStart(code);
120641
- if (atLineStart && code === codes_codes.graveAccent) {
120922
+ if (atLineStart && code === codes.graveAccent) {
120642
120923
  codeSpanOpenSize = 0;
120643
120924
  // Leave `atLineStart` set — `countOpenTicks` needs it to tell a fence from an
120644
120925
  // inline code span once the run of backticks is fully counted; it's cleared once
@@ -120653,7 +120934,7 @@ function createTokenize(mode) {
120653
120934
  // fence) refuses so CommonMark html-flow reparses it exactly as it does today.
120654
120935
  function plainClaimLineStart(code) {
120655
120936
  // Leading whitespace only → treat as a blank line, matching CommonMark.
120656
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
120937
+ if (code === codes.space || code === codes.horizontalTab) {
120657
120938
  effects.consume(code);
120658
120939
  return plainClaimLineStart;
120659
120940
  }
@@ -120666,7 +120947,7 @@ function createTokenize(mode) {
120666
120947
  // paragraph that merely starts with a tag must fall back so its markdown
120667
120948
  // parses and rehype-raw re-nests it into the wrapper.
120668
120949
  if (pendingBlankLine) {
120669
- if (code !== codes_codes.lessThan)
120950
+ if (code !== codes.lessThan)
120670
120951
  return nok(code);
120671
120952
  return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
120672
120953
  }
@@ -120686,7 +120967,7 @@ function createTokenize(mode) {
120686
120967
  }
120687
120968
  };
120688
120969
  }
120689
- function syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
120970
+ function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
120690
120971
  // eslint-disable-next-line @typescript-eslint/no-this-alias
120691
120972
  const self = this;
120692
120973
  return start;
@@ -120719,7 +121000,7 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
120719
121000
  return afterLessThan;
120720
121001
  }
120721
121002
  function afterLessThan(code) {
120722
- if (code === codes_codes.slash) {
121003
+ if (code === codes.slash) {
120723
121004
  effects.consume(code);
120724
121005
  return afterSlash;
120725
121006
  }
@@ -120738,7 +121019,7 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
120738
121019
  function scanToLineEnd(code) {
120739
121020
  if (code === null || markdownLineEnding(code)) {
120740
121021
  effects.exit(types_types.data);
120741
- return lastNonSpace === codes_codes.greaterThan ? ok(code) : nok(code);
121022
+ return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
120742
121023
  }
120743
121024
  if (!markdownSpace(code))
120744
121025
  lastNonSpace = code;
@@ -120771,8 +121052,8 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
120771
121052
  */
120772
121053
  function syntax_mdxComponent() {
120773
121054
  return {
120774
- flow: { [codes_codes.lessThan]: [mdxComponentFlowConstruct] },
120775
- text: { [codes_codes.lessThan]: [mdxComponentTextConstruct] },
121055
+ flow: { [codes.lessThan]: [mdxComponentFlowConstruct] },
121056
+ text: { [codes.lessThan]: [mdxComponentTextConstruct] },
120776
121057
  };
120777
121058
  }
120778
121059
 
@@ -120794,9 +121075,20 @@ function syntax_mdxComponent() {
120794
121075
 
120795
121076
 
120796
121077
 
121078
+
121079
+
121080
+
121081
+
121082
+
121083
+
120797
121084
  const buildInlineMdProcessor = (safeMode) => {
120798
- const micromarkExts = [syntax_mdxComponent(), syntax_gemoji(), legacyVariable(), syntax_magicBlock()];
121085
+ // `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
121086
+ // body (e.g. a `<Callout>`) is captured as one html node. Without it, blank
121087
+ // lines between rows let CommonMark HTML block type 6 fragment the table and
121088
+ // its rows spill out as text / indented code blocks (CX-3705).
121089
+ const micromarkExts = [syntax_jsxTable(), syntax_mdxComponent(), syntax_gemoji(), legacyVariable(), syntax_magicBlock()];
120799
121090
  const fromMarkdownExts = [
121091
+ jsx_table_jsxTableFromMarkdown(),
120800
121092
  mdx_component_mdxComponentFromMarkdown(),
120801
121093
  gemojiFromMarkdown(),
120802
121094
  legacyVariableFromMarkdown(),
@@ -120856,6 +121148,65 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
120856
121148
  children,
120857
121149
  ...(position ? { position } : {}),
120858
121150
  });
121151
+ // Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
121152
+ // structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
121153
+ // `mdxishJsxToMdast`, both of which run later on raw html nodes.
121154
+ const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table', 'figure', 'figcaption']);
121155
+ const NESTED_TABLE_RE = /<table[\s>]/i;
121156
+ const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
121157
+ // Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
121158
+ // literal-brace behavior; variables/glossary already resolve inside raw html.
121159
+ const PLAIN_CONTENT_TYPES = new Set([
121160
+ 'paragraph',
121161
+ 'text',
121162
+ 'html',
121163
+ 'mdxTextExpression',
121164
+ 'mdxFlowExpression',
121165
+ enums_NodeTypes.variable,
121166
+ enums_NodeTypes.glossary,
121167
+ ]);
121168
+ // Promoting plain HTML is only worth bypassing rehype-raw's parse5 pass when
121169
+ // the body parses into an actual markdown construct.
121170
+ const containsMarkdownConstruct = (nodes) => nodes.some(node => !PLAIN_CONTENT_TYPES.has(node.type) ||
121171
+ ('children' in node && Array.isArray(node.children) && containsMarkdownConstruct(node.children)));
121172
+ /**
121173
+ * Index of the `</tag>` that balances the already-consumed opening tag (the
121174
+ * caller starts us one level deep). `lastIndexOf` mis-slices sibling same-tag
121175
+ * pairs like `<div>**a**</div><div>**b**</div>`, so we depth-match instead —
121176
+ * delegating to `walkTags` (htmlparser2) so quoted attributes (`title="</div>"`),
121177
+ * code spans, and legacy `<<VARIABLE>>` are handled for free. Returns -1 when
121178
+ * the wrapper is left open.
121179
+ */
121180
+ function findBalancedClosingTagIndex(content, tag) {
121181
+ const target = tag.toLowerCase();
121182
+ const canonicalCloserLength = tag.length + 3; // `</tag>`
121183
+ // The caller already stripped the opening tag, so re-attach one: htmlparser2
121184
+ // drops an unmatched closer, and we want it balanced. Offsets shift by the
121185
+ // prefix length.
121186
+ const prefix = `<${tag}>`;
121187
+ let depth = 0;
121188
+ let closeIndex = -1;
121189
+ walkTags(prefix + content, {
121190
+ onOpen: ({ name, isSelfClosing, isStrayCloser }) => {
121191
+ if (closeIndex >= 0 || isSelfClosing || isStrayCloser)
121192
+ return;
121193
+ if (name.toLowerCase() === target)
121194
+ depth += 1;
121195
+ },
121196
+ onClose: ({ name, start, end, implicit }) => {
121197
+ if (closeIndex >= 0 || implicit || name.toLowerCase() !== target)
121198
+ return;
121199
+ // Only canonical `</tag>` closers — the caller slices by that length, so a
121200
+ // whitespaced `</tag >` would misalign; leaving it unmatched keeps it raw.
121201
+ if (end - start !== canonicalCloserLength)
121202
+ return;
121203
+ depth -= 1;
121204
+ if (depth === 0)
121205
+ closeIndex = start - prefix.length;
121206
+ },
121207
+ });
121208
+ return closeIndex;
121209
+ }
120859
121210
 
120860
121211
  ;// ./processor/transform/mdxish/components/inline-html.ts
120861
121212
 
@@ -120987,10 +121338,36 @@ const mdxishInlineMdxComponents = () => tree => {
120987
121338
  };
120988
121339
  /* harmony default export */ const inline_mdx_blocks = (mdxishInlineMdxComponents);
120989
121340
 
121341
+ ;// ./processor/transform/mdxish/indentation.ts
121342
+ /**
121343
+ * CommonMark indentation helpers, shared by the mdxish preprocessors so tab- and
121344
+ * space-indented content is measured (and sliced) on one scale.
121345
+ *
121346
+ * CommonMark's indented-code threshold is 4 *columns*, and a tab is a 4-column tab
121347
+ * stop — not a fixed 4 characters. Counting characters (tab = 1) under-measures
121348
+ * tab-indented lines, letting them slip past the 4-column gate so their content
121349
+ * fragments into code blocks. Keeping one implementation here stops the two callers
121350
+ * from drifting on what "4 columns" means.
121351
+ */
121352
+ /** The run of leading spaces/tabs on a line. */
121353
+ const leadingIndent = (line) => line.match(/^[ \t]*/)?.[0] ?? '';
121354
+ /**
121355
+ * Expand a leading-whitespace run to spaces using CommonMark's 4-column tab stops,
121356
+ * so a run of mixed tabs/spaces can be measured by length and sliced by column.
121357
+ */
121358
+ function expandIndentToColumns(indent) {
121359
+ return indent
121360
+ .split('')
121361
+ .reduce((columns, char) => columns + (char === '\t' ? ' '.repeat(4 - (columns.length % 4)) : ' '), '');
121362
+ }
121363
+ /** Indentation width of a line in CommonMark columns (a tab advances to the next 4-column stop). */
121364
+ const indentWidth = (line) => expandIndentToColumns(leadingIndent(line)).length;
121365
+
120990
121366
  ;// ./processor/transform/mdxish/terminate-html-flow-blocks.ts
120991
121367
 
120992
121368
 
120993
121369
 
121370
+
120994
121371
  const STANDALONE_HTML_LINE_REGEX = /^(<[a-z][^<>]*>|<\/[a-z][^<>]*>)+\s*$/;
120995
121372
  const HTML_LINE_WITH_CONTENT_REGEX = /^<[a-z][^<>]*>.*<\/[a-z][^<>]*>(?:[^<]*)$/;
120996
121373
  // A line that is exactly one lowercase opening (or self-closing) tag — the shape
@@ -121016,11 +121393,6 @@ function countRawContentTags(line) {
121016
121393
  closes: (line.match(close) ?? []).length,
121017
121394
  }));
121018
121395
  }
121019
- // Indentation width in columns, counting a tab as 4 per CommonMark.
121020
- function indentWidth(line) {
121021
- const leading = line.match(/^[ \t]*/)?.[0] ?? '';
121022
- return leading.replace(/\t/g, ' ').length;
121023
- }
121024
121396
  /**
121025
121397
  * Decides whether a blank line belongs between `line` and `next` so the HTML
121026
121398
  * flow block opened on `line` terminates and `next` parses as markdown.
@@ -121092,6 +121464,7 @@ function terminateHtmlFlowBlocks(content) {
121092
121464
 
121093
121465
 
121094
121466
 
121467
+
121095
121468
  // Matches a JSX attribute expression (e.g. `key={i}`) anywhere in a string. */
121096
121469
  const NESTED_ATTR_EXPRESSION_RE = /[\w-]+\s*=\s*\{/;
121097
121470
  // Name shape mirrors `componentTagPattern`; the lookbehind skips the inner tag
@@ -121102,25 +121475,33 @@ const NESTED_COMPONENT_TAG_RE = /(?<!<)<([A-Z][A-Za-z0-9_]*)[\s/>]/g;
121102
121475
  const hasNestedGenericComponentTag = (content) => [...content.matchAll(NESTED_COMPONENT_TAG_RE)].some(match => !GENERIC_MDX_COMPONENT_EXCLUDED_TAGS.has(match[1]));
121103
121476
  /**
121104
121477
  * Strip the shared leading indentation from a component body so readability indentation
121105
- * isn't parsed as indented code (4+ spaces), e.g. ` <p>` / ` text` -> `<p>` / ` text`.
121478
+ * isn't parsed as indented code (4+ columns), e.g. ` <p>` / ` text` -> `<p>` / ` text`.
121106
121479
  * Relative indentation is kept, so content genuinely 4+ columns deeper stays code. We
121107
121480
  * only strip when a line actually reaches 4 columns; otherwise the body is left as-is so
121108
121481
  * its leading whitespace survives as text nodes (mixed component + HTML content needs it).
121482
+ *
121483
+ * Indentation is measured in CommonMark columns (tab = up to 4), matching how the parser
121484
+ * decides indented code. A char count (tab = 1) under-measures tab-indented bodies, so
121485
+ * they slip past the 4-column gate and their nested content fragments into code blocks.
121109
121486
  */
121110
121487
  function safeDeindent(text) {
121111
121488
  const lines = text.split('\n');
121112
121489
  const nonEmptyLines = lines.filter(line => line.trim().length > 0);
121113
121490
  if (nonEmptyLines.length === 0)
121114
121491
  return text;
121115
- // Indent counts characters (tab = 1), unlike indentWidth's CommonMark columns
121116
- // (tab = 4) in terminate-html-flow-blocks.
121117
- const indents = nonEmptyLines.map(line => line.match(/^(\s*)/)?.[1].length ?? 0);
121492
+ const indents = nonEmptyLines.map(line => expandIndentToColumns(leadingIndent(line)).length);
121118
121493
  const minIndent = Math.min(...indents);
121119
121494
  const maxIndent = Math.max(...indents);
121120
- const stripAmount = maxIndent > 3 ? minIndent : 0;
121121
- if (stripAmount === 0)
121495
+ if (maxIndent < 4 || minIndent === 0)
121122
121496
  return text;
121123
- return lines.map(line => line.slice(stripAmount)).join('\n');
121497
+ // Expand each line's leading run to spaces before slicing so a shared indent of mixed
121498
+ // tabs/spaces (and partial-tab remainders) strips cleanly while relative depth survives.
121499
+ return lines
121500
+ .map(line => {
121501
+ const indent = leadingIndent(line);
121502
+ return expandIndentToColumns(indent).slice(minIndent) + line.slice(indent.length);
121503
+ })
121504
+ .join('\n');
121124
121505
  }
121125
121506
  /**
121126
121507
  * Parse component-body markdown into mdast children. Dedenting shifts columns and
@@ -121180,6 +121561,10 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
121180
121561
  * This transformer identifies these patterns and converts them to proper MDX JSX elements so they
121181
121562
  * can be accurately recognized and rendered later with their component definition code.
121182
121563
  *
121564
+ * Note: The main goal is to promote PascalCase tags to MDX elements, but we want to promote
121565
+ * normal HTML to MDX elements in some cases so they get the full custom parsing behavior.
121566
+ * E.g. tags with JSX expressions, nested components, etc.
121567
+ *
121183
121568
  * The mdx-component micromark tokenizer ensures that multi-line components are captured
121184
121569
  * as single HTML nodes, so this transformer only needs to handle two cases:
121185
121570
  *
@@ -121226,6 +121611,7 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
121226
121611
  if (GENERIC_MDX_COMPONENT_EXCLUDED_TAGS.has(tag))
121227
121612
  return; // owned by dedicated transformers
121228
121613
  const isPascal = isPascalCase(tag);
121614
+ // ==== SPECIAL CASES TO PROMOTE NORMAL HTML TO MDX ELEMENTS ====
121229
121615
  // Lowercase inline tags with `{…}` attributes belong to
121230
121616
  // mdxishInlineComponentBlocks; leave them as html for that pass. PascalCase
121231
121617
  // components stay flow-level even when inline (ReadMe's component model).
@@ -121234,11 +121620,19 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
121234
121620
  // A lowercase wrapper is only promoted when it (or a descendant) carries a
121235
121621
  // JSX expression or nests a component; otherwise it would swallow that inner
121236
121622
  // JSX/component as literal text that rehype-raw's parse5 pass can't handle.
121237
- // Table-structural wrappers are excluded — `mdxishTables` re-parses those.
121238
- const hasNestedExpressionAttr = !selfClosing && NESTED_ATTR_EXPRESSION_RE.test(contentAfterTag);
121623
+ // Table-structural wrappers are excluded from both — `mdxishTables` re-parses
121624
+ // those, so a `{…}` in a cell (e.g. `<code>--depth={n}</code>`) must not
121625
+ // accidentally promote the table to an MDX element prematurely.
121239
121626
  const isTableStructuralTag = tag === 'table' || tableTags.has(tag);
121627
+ const hasNestedExpressionAttr = !selfClosing && !isTableStructuralTag && NESTED_ATTR_EXPRESSION_RE.test(contentAfterTag);
121240
121628
  const hasNestedComponentTag = !selfClosing && !isTableStructuralTag && hasNestedGenericComponentTag(contentAfterTag);
121241
- if (!isPascal && !hasExpressionAttr(attributes) && !hasNestedExpressionAttr && !hasNestedComponentTag)
121629
+ // Promotion: By default commonmark doesn't parse markdown in single line HTML tags (e.g. <div>**bold**</div>)
121630
+ // To support that, we try to promote them to MDX elements so the markdown gets parsed
121631
+ const isPlainLowercaseHtml = !isPascal && !hasExpressionAttr(attributes) && !hasNestedExpressionAttr && !hasNestedComponentTag;
121632
+ const plainClosingTagIndex = isPlainLowercaseHtml && !selfClosing && isMarkdownPromotableHtmlTag(tag) && !NESTED_TABLE_RE.test(contentAfterTag)
121633
+ ? findBalancedClosingTagIndex(contentAfterTag, tag)
121634
+ : -1;
121635
+ if (isPlainLowercaseHtml && plainClosingTagIndex < 0)
121242
121636
  return;
121243
121637
  const closingTagStr = `</${tag}>`;
121244
121638
  // Case 1: Self-closing tag
@@ -121259,14 +121653,26 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
121259
121653
  return;
121260
121654
  }
121261
121655
  // Case 2: Self-contained block (closing tag in content)
121262
- if (contentAfterTag.includes(closingTagStr)) {
121263
- const closingTagIndex = contentAfterTag.lastIndexOf(closingTagStr);
121656
+ const closingTagIndex = isPlainLowercaseHtml ? plainClosingTagIndex : contentAfterTag.lastIndexOf(closingTagStr);
121657
+ if (closingTagIndex >= 0) {
121264
121658
  // Untrimmed so parseMdChildren can dedent before trimming.
121265
121659
  const componentInnerContent = contentAfterTag.substring(0, closingTagIndex);
121266
121660
  const contentAfterClose = contentAfterTag.substring(closingTagIndex + closingTagStr.length).trim();
121267
- let parsedChildren = componentInnerContent.trim()
121268
- ? parseMdChildren(componentInnerContent, safeMode)
121269
- : [];
121661
+ let parsedChildren = [];
121662
+ if (componentInnerContent.trim()) {
121663
+ try {
121664
+ parsedChildren = parseMdChildren(componentInnerContent, safeMode);
121665
+ }
121666
+ catch (error) {
121667
+ // Plain HTML bodies can hold anything (e.g. stray braces the strict
121668
+ // expression parser rejects) — keep the node raw instead of throwing.
121669
+ if (isPlainLowercaseHtml)
121670
+ return;
121671
+ throw error;
121672
+ }
121673
+ }
121674
+ if (isPlainLowercaseHtml && !containsMarkdownConstruct(parsedChildren))
121675
+ return;
121270
121676
  // Lowercase tags are usually inline; unwrap a sole paragraph so their
121271
121677
  // phrasing content isn't spuriously block-wrapped.
121272
121678
  if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
@@ -123467,21 +123873,21 @@ function resolveEntity(name) {
123467
123873
  function tokenizeLooseHtmlEntity(effects, ok, nok) {
123468
123874
  let length = 0;
123469
123875
  const start = (code) => {
123470
- if (code !== codes_codes.ampersand)
123876
+ if (code !== codes.ampersand)
123471
123877
  return nok(code);
123472
123878
  effects.enter('looseHtmlEntity');
123473
123879
  effects.consume(code);
123474
123880
  return afterAmpersand;
123475
123881
  };
123476
123882
  const afterAmpersand = (code) => {
123477
- if (code === codes_codes.numberSign) {
123883
+ if (code === codes.numberSign) {
123478
123884
  effects.consume(code);
123479
123885
  return afterHash;
123480
123886
  }
123481
123887
  return accumulateNamed(code);
123482
123888
  };
123483
123889
  const afterHash = (code) => {
123484
- if (code === codes_codes.lowercaseX || code === codes_codes.uppercaseX) {
123890
+ if (code === codes.lowercaseX || code === codes.uppercaseX) {
123485
123891
  effects.consume(code);
123486
123892
  return accumulateHex;
123487
123893
  }
@@ -123495,7 +123901,7 @@ function tokenizeLooseHtmlEntity(effects, ok, nok) {
123495
123901
  }
123496
123902
  if (length === 0)
123497
123903
  return nok(code);
123498
- if (code === codes_codes.semicolon)
123904
+ if (code === codes.semicolon)
123499
123905
  return nok(code);
123500
123906
  effects.exit('looseHtmlEntity');
123501
123907
  return ok(code);
@@ -123508,7 +123914,7 @@ function tokenizeLooseHtmlEntity(effects, ok, nok) {
123508
123914
  }
123509
123915
  if (length === 0)
123510
123916
  return nok(code);
123511
- if (code === codes_codes.semicolon)
123917
+ if (code === codes.semicolon)
123512
123918
  return nok(code);
123513
123919
  effects.exit('looseHtmlEntity');
123514
123920
  return ok(code);
@@ -123521,7 +123927,7 @@ function tokenizeLooseHtmlEntity(effects, ok, nok) {
123521
123927
  }
123522
123928
  if (length === 0)
123523
123929
  return nok(code);
123524
- if (code === codes_codes.semicolon)
123930
+ if (code === codes.semicolon)
123525
123931
  return nok(code);
123526
123932
  effects.exit('looseHtmlEntity');
123527
123933
  return ok(code);
@@ -123556,7 +123962,7 @@ function exitLooseHtmlEntity(token) {
123556
123962
  }
123557
123963
  function looseHtmlEntity() {
123558
123964
  return {
123559
- text: { [codes_codes.ampersand]: looseHtmlEntityConstruct },
123965
+ text: { [codes.ampersand]: looseHtmlEntityConstruct },
123560
123966
  };
123561
123967
  }
123562
123968
  function looseHtmlEntityFromMarkdown() {
@@ -123690,7 +124096,7 @@ const textToBlock = (text) => [{ children: textToInline(text), type: 'paragraph'
123690
124096
  /**
123691
124097
  * Converts leading newlines in magic block content to `<br>` tags.
123692
124098
  * Leading newlines are stripped by remark-parse before they become soft break nodes,
123693
- * so remark-breaks cannot handle them. We convert them to HTML `<br>` tags instead.
124099
+ * so the hard-breaks plugin cannot handle them. We convert them to HTML `<br>` tags instead.
123694
124100
  */
123695
124101
  const ensureLeadingBreaks = (text) => text.replace(/^\n+/, match => '<br>'.repeat(match.length));
123696
124102
  /** Preprocesses magic block body content before parsing. */
@@ -123702,7 +124108,7 @@ const contentParser = lib_unified()
123702
124108
  .data('micromarkExtensions', [syntax_gemoji(), legacyVariable(), looseHtmlEntity()])
123703
124109
  .data('fromMarkdownExtensions', [gemojiFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
123704
124110
  .use(lib_remarkParse)
123705
- .use(remarkBreaks)
124111
+ .use(hard_breaks)
123706
124112
  .use(lib_remarkGfm)
123707
124113
  .use(normalize_malformed_md_syntax);
123708
124114
  /**
@@ -124249,9 +124655,6 @@ const magicBlockTransformer = (options = {}) => tree => {
124249
124655
  // single-line `<div>…</div>`). CommonMark slurps the whole div as one `html`
124250
124656
  // node, so the tokenizer never sees the HTMLBlock — we recover it here.
124251
124657
  const RAW_HTML_BLOCK_RE = /<HTMLBlock\b([^>]*)>\s*\{\s*`((?:[^`\\]|\\.)*)`\s*\}\s*<\/HTMLBlock>/g;
124252
- // Opening `<HTMLBlock …>` as its own `html` node — produced inside a paragraph
124253
- // when an HTMLBlock appears inline alongside text.
124254
- const HTML_BLOCK_OPEN_RE = /^<HTMLBlock\b([^>]*)>$/;
124255
124658
  /**
124256
124659
  * Builds the canonical `html-block` MDAST node the renderer expects.
124257
124660
  */
@@ -124332,13 +124735,14 @@ const splitRawHtmlBlocks = (node) => {
124332
124735
  /**
124333
124736
  * Converts every `<HTMLBlock>` shape that survives parsing into the canonical
124334
124737
  * `html-block` MDAST node, reading the body from the tokenizer's template-literal
124335
- * expression. Three shapes occur:
124738
+ * expression. Two shapes occur:
124336
124739
  *
124337
- * 1. JSX element (`mdxJsxFlowElement`/`mdxJsxTextElement`) — multiline/block
124338
- * context and table cells (after their remarkMdx re-parse).
124339
- * 2. Raw `html` blob (`splitRawHtmlBlocks`) single-line top-level, or nested
124340
- * in raw HTML like an inline `<div>`.
124341
- * 3. Inline-in-paragraph split into `html` + expression + `html` siblings.
124740
+ * 1. JSX element (`mdxJsxFlowElement`/`mdxJsxTextElement`) — table cells, after
124741
+ * their remarkMdx re-parse (that re-parse runs without the htmlBlockComponent
124742
+ * tokenizer, so `<HTMLBlock>` arrives as JSX rather than an opaque `html` node).
124743
+ * 2. Raw `html` blob (`splitRawHtmlBlocks`) the htmlBlockComponent tokenizer's
124744
+ * opaque output (top-level and inline), or an `<HTMLBlock>` embedded in a
124745
+ * larger raw-HTML node like an inline `<div>` that the tokenizer never saw.
124342
124746
  *
124343
124747
  * Runs *after* `mdxishTables` so table cells are re-parsed first;
124344
124748
  * `mdxishTables` recognizes the still-JSX `<HTMLBlock>` element when deciding to
@@ -124363,36 +124767,6 @@ const mdxishHtmlBlocks = () => tree => {
124363
124767
  if (replacement)
124364
124768
  parent.children.splice(index, 1, ...replacement);
124365
124769
  });
124366
- // Shape 3: inline within a paragraph — `<HTMLBlock>` open/close arrive as
124367
- // separate `html` siblings with the template-literal expression between them.
124368
- lib_visit(tree, 'paragraph', (paragraph) => {
124369
- // An html-block is block content, so it isn't a valid PhrasingContent child;
124370
- // widen to RootContent (which HTMLBlock belongs to) for the in-place splice.
124371
- const children = paragraph.children;
124372
- for (let i = 0; i < children.length; i += 1) {
124373
- const open = children[i];
124374
- const openMatch = open.type === 'html' ? open.value.match(HTML_BLOCK_OPEN_RE) : null;
124375
- if (!openMatch)
124376
- continue; // eslint-disable-line no-continue
124377
- const closeIdx = children.findIndex((child, j) => j > i && child.type === 'html' && child.value === '</HTMLBlock>');
124378
- if (closeIdx === -1)
124379
- continue; // eslint-disable-line no-continue
124380
- const body = children
124381
- .slice(i + 1, closeIdx)
124382
- .map(child => {
124383
- if (child.type === 'mdxTextExpression' || child.type === 'mdxFlowExpression') {
124384
- return extractTemplateLiteral(child.value);
124385
- }
124386
- // Preserve raw text from any other phrasing sibling (e.g. stray
124387
- // whitespace or content the tokenizer didn't claim) so it isn't
124388
- // silently dropped from the html payload.
124389
- return 'value' in child && typeof child.value === 'string' ? child.value : '';
124390
- })
124391
- .join('');
124392
- const openingTagIndent = (open.position?.start.column ?? 1) - 1;
124393
- children.splice(i, closeIdx - i + 1, htmlBlockFromRaw(openMatch[1], body, open.position, openingTagIndent));
124394
- }
124395
- });
124396
124770
  };
124397
124771
  /* harmony default export */ const mdxish_html_blocks = (mdxishHtmlBlocks);
124398
124772
 
@@ -125092,6 +125466,29 @@ const mdxishMermaidTransformer = () => (tree) => {
125092
125466
  };
125093
125467
  /* harmony default export */ const mdxish_mermaid = (mdxishMermaidTransformer);
125094
125468
 
125469
+ ;// ./processor/transform/mdxish/normalize-closing-tag-whitespace.ts
125470
+
125471
+
125472
+ // Spaces/tabs only — newlines would let prose `<` / `>` across lines look like one tag.
125473
+ const SPACED_CLOSING_TAG_RE = /<\/[ \t]*([a-zA-Z][a-zA-Z0-9-]*)[ \t]*>/g;
125474
+ /**
125475
+ * Canonicalize spaced closing tags (`</ td >` → `</td>`) for known HTML names.
125476
+ *
125477
+ * In HTML, `</` + whitespace is a bogus comment, so `</ table >` never closes the
125478
+ * table (jsxTable misses it → empty table + pre; CX-3706). Only standard HTML tags;
125479
+ * custom components, prose (`a </ b`), and code blocks are left alone.
125480
+ *
125481
+ * @example
125482
+ * normalizeClosingTagWhitespace('</ td >') // '</td>'
125483
+ * normalizeClosingTagWhitespace('</table >') // '</table>'
125484
+ * normalizeClosingTagWhitespace('a </ b >') // unchanged
125485
+ */
125486
+ function normalizeClosingTagWhitespace(content) {
125487
+ const { protectedContent, protectedCode } = protectCodeBlocks(content);
125488
+ const result = protectedContent.replace(SPACED_CLOSING_TAG_RE, (match, tagName) => STANDARD_HTML_TAGS.has(tagName.toLowerCase()) ? `</${tagName}>` : match);
125489
+ return restoreCodeBlocks(result, protectedCode);
125490
+ }
125491
+
125095
125492
  ;// ./processor/transform/mdxish/normalize-compact-headings.ts
125096
125493
 
125097
125494
  /**
@@ -125703,25 +126100,25 @@ const variablesTextTransformer = () => tree => {
125703
126100
  };
125704
126101
  /* harmony default export */ const variables_text = (variablesTextTransformer);
125705
126102
 
125706
- ;// ./lib/mdast-util/jsx-table/index.ts
125707
- const jsx_table_contextMap = new WeakMap();
125708
- function findJsxTableToken() {
126103
+ ;// ./lib/mdast-util/html-block-component/index.ts
126104
+ const html_block_component_contextMap = new WeakMap();
126105
+ function findHtmlBlockComponentToken() {
125709
126106
  const events = this.tokenStack;
125710
126107
  for (let i = events.length - 1; i >= 0; i -= 1) {
125711
- if (events[i][0].type === 'jsxTable')
126108
+ if (events[i][0].type === 'htmlBlockComponent')
125712
126109
  return events[i][0];
125713
126110
  }
125714
126111
  return undefined;
125715
126112
  }
125716
- function enterJsxTable(token) {
125717
- jsx_table_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
126113
+ function enterHtmlBlockComponent(token) {
126114
+ html_block_component_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
125718
126115
  this.enter({ type: 'html', value: '' }, token);
125719
126116
  }
125720
- function exitJsxTableData(token) {
125721
- const tableToken = findJsxTableToken.call(this);
125722
- if (!tableToken)
126117
+ function exitHtmlBlockComponentData(token) {
126118
+ const componentToken = findHtmlBlockComponentToken.call(this);
126119
+ if (!componentToken)
125723
126120
  return;
125724
- const ctx = jsx_table_contextMap.get(tableToken);
126121
+ const ctx = html_block_component_contextMap.get(componentToken);
125725
126122
  if (ctx) {
125726
126123
  const gap = token.start.line - ctx.lastEndLine;
125727
126124
  if (ctx.chunks.length > 0 && gap > 0) {
@@ -125731,27 +126128,304 @@ function exitJsxTableData(token) {
125731
126128
  ctx.lastEndLine = token.end.line;
125732
126129
  }
125733
126130
  }
125734
- function exitJsxTable(token) {
125735
- const ctx = jsx_table_contextMap.get(token);
126131
+ function exitHtmlBlockComponent(token) {
126132
+ const ctx = html_block_component_contextMap.get(token);
125736
126133
  const node = this.stack[this.stack.length - 1];
125737
126134
  if (ctx) {
125738
126135
  node.value = ctx.chunks.join('');
125739
- jsx_table_contextMap.delete(token);
126136
+ html_block_component_contextMap.delete(token);
125740
126137
  }
125741
126138
  this.exit(token);
125742
126139
  }
125743
- function jsx_table_jsxTableFromMarkdown() {
126140
+ function html_block_component_htmlBlockComponentFromMarkdown() {
125744
126141
  return {
125745
126142
  enter: {
125746
- jsxTable: enterJsxTable,
126143
+ htmlBlockComponent: enterHtmlBlockComponent,
125747
126144
  },
125748
126145
  exit: {
125749
- jsxTableData: exitJsxTableData,
125750
- jsxTable: exitJsxTable,
126146
+ htmlBlockComponentData: exitHtmlBlockComponentData,
126147
+ htmlBlockComponent: exitHtmlBlockComponent,
125751
126148
  },
125752
126149
  };
125753
126150
  }
125754
126151
 
126152
+ ;// ./lib/micromark/html-block-component/syntax.ts
126153
+
126154
+
126155
+ const TAG_SUFFIX = [
126156
+ codes.uppercaseT,
126157
+ codes.uppercaseM,
126158
+ codes.uppercaseL,
126159
+ codes.uppercaseB,
126160
+ codes.lowercaseL,
126161
+ codes.lowercaseO,
126162
+ codes.lowercaseC,
126163
+ codes.lowercaseK,
126164
+ ];
126165
+ // ---------------------------------------------------------------------------
126166
+ // Shared tokenizer factory
126167
+ // ---------------------------------------------------------------------------
126168
+ /**
126169
+ * Creates a tokenize function for `<HTMLBlock>...</HTMLBlock>`.
126170
+ *
126171
+ * - **flow** (block-level): supports multiline content via line continuations,
126172
+ * consumes trailing whitespace after the closing tag.
126173
+ * - **text** (inline): single-line only, exits immediately after the closing tag.
126174
+ */
126175
+ function syntax_createTokenize(mode) {
126176
+ return function tokenize(effects, ok, nok) {
126177
+ let depth = 1;
126178
+ function matchChars(chars, onMatch, onFail) {
126179
+ if (chars.length === 0)
126180
+ return onMatch;
126181
+ const next = (code) => {
126182
+ if (code === chars[0]) {
126183
+ effects.consume(code);
126184
+ return matchChars(chars.slice(1), onMatch, onFail);
126185
+ }
126186
+ return onFail(code);
126187
+ };
126188
+ return next;
126189
+ }
126190
+ function matchTagName(onMatch, onFail) {
126191
+ const next = (code) => {
126192
+ if (code === codes.uppercaseH) {
126193
+ effects.consume(code);
126194
+ return matchChars(TAG_SUFFIX, onMatch, onFail);
126195
+ }
126196
+ return onFail(code);
126197
+ };
126198
+ return next;
126199
+ }
126200
+ return start;
126201
+ function start(code) {
126202
+ if (code !== codes.lessThan)
126203
+ return nok(code);
126204
+ effects.enter('htmlBlockComponent');
126205
+ effects.enter('htmlBlockComponentData');
126206
+ effects.consume(code);
126207
+ return matchTagName(afterTagName, nok);
126208
+ }
126209
+ function afterTagName(code) {
126210
+ if (code === codes.greaterThan) {
126211
+ effects.consume(code);
126212
+ return body;
126213
+ }
126214
+ if (code === codes.space || code === codes.horizontalTab) {
126215
+ effects.consume(code);
126216
+ return inAttributes;
126217
+ }
126218
+ if (mode === 'flow' && markdownLineEnding(code)) {
126219
+ effects.exit('htmlBlockComponentData');
126220
+ return attributeContinuationStart(code);
126221
+ }
126222
+ if (code === codes.slash) {
126223
+ effects.consume(code);
126224
+ return selfClose;
126225
+ }
126226
+ return nok(code);
126227
+ }
126228
+ function inAttributes(code) {
126229
+ if (code === codes.greaterThan) {
126230
+ effects.consume(code);
126231
+ return body;
126232
+ }
126233
+ if (code === null) {
126234
+ return nok(code);
126235
+ }
126236
+ if (markdownLineEnding(code)) {
126237
+ if (mode === 'text')
126238
+ return nok(code);
126239
+ effects.exit('htmlBlockComponentData');
126240
+ return attributeContinuationStart(code);
126241
+ }
126242
+ effects.consume(code);
126243
+ return inAttributes;
126244
+ }
126245
+ function attributeContinuationStart(code) {
126246
+ return effects.check(html_block_component_syntax_nonLazyContinuationStart, attributeContinuationNonLazy, continuationAfter)(code);
126247
+ }
126248
+ function attributeContinuationNonLazy(code) {
126249
+ effects.enter(types_types.lineEnding);
126250
+ effects.consume(code);
126251
+ effects.exit(types_types.lineEnding);
126252
+ return attributeContinuationBefore;
126253
+ }
126254
+ function attributeContinuationBefore(code) {
126255
+ if (code === null || markdownLineEnding(code)) {
126256
+ return attributeContinuationStart(code);
126257
+ }
126258
+ effects.enter('htmlBlockComponentData');
126259
+ return inAttributes(code);
126260
+ }
126261
+ function selfClose(code) {
126262
+ if (code === codes.greaterThan) {
126263
+ effects.consume(code);
126264
+ return mode === 'flow' ? afterClose : done(code);
126265
+ }
126266
+ return nok(code);
126267
+ }
126268
+ function body(code) {
126269
+ if (code === null)
126270
+ return nok(code);
126271
+ if (markdownLineEnding(code)) {
126272
+ if (mode === 'text') {
126273
+ // Text constructs operate on paragraph content which spans lines
126274
+ effects.consume(code);
126275
+ return body;
126276
+ }
126277
+ effects.exit('htmlBlockComponentData');
126278
+ return continuationStart(code);
126279
+ }
126280
+ if (code === codes.lessThan) {
126281
+ effects.consume(code);
126282
+ return closeSlash;
126283
+ }
126284
+ effects.consume(code);
126285
+ return body;
126286
+ }
126287
+ function closeSlash(code) {
126288
+ if (code === codes.slash) {
126289
+ effects.consume(code);
126290
+ return matchTagName(closeGt, body);
126291
+ }
126292
+ return matchTagName(openAfterTagName, body)(code);
126293
+ }
126294
+ function openAfterTagName(code) {
126295
+ if (code === codes.greaterThan || code === codes.space || code === codes.horizontalTab) {
126296
+ depth += 1;
126297
+ effects.consume(code);
126298
+ return body;
126299
+ }
126300
+ return body(code);
126301
+ }
126302
+ function closeGt(code) {
126303
+ if (code === codes.greaterThan) {
126304
+ depth -= 1;
126305
+ effects.consume(code);
126306
+ if (depth === 0) {
126307
+ return mode === 'flow' ? afterClose : done(code);
126308
+ }
126309
+ return body;
126310
+ }
126311
+ return body(code);
126312
+ }
126313
+ // -- flow-only states ---------------------------------------------------
126314
+ function afterClose(code) {
126315
+ if (code === null || markdownLineEnding(code)) {
126316
+ return done(code);
126317
+ }
126318
+ if (code === codes.space || code === codes.horizontalTab) {
126319
+ effects.consume(code);
126320
+ return afterClose;
126321
+ }
126322
+ // Reject so the block re-parses as a paragraph, deferring to the
126323
+ // text tokenizer which preserves trailing content in the same line.
126324
+ return nok(code);
126325
+ }
126326
+ // -- flow-only: line continuation ---------------------------------------
126327
+ function continuationStart(code) {
126328
+ return effects.check(html_block_component_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
126329
+ }
126330
+ function continuationStartNonLazy(code) {
126331
+ effects.enter(types_types.lineEnding);
126332
+ effects.consume(code);
126333
+ effects.exit(types_types.lineEnding);
126334
+ return continuationBefore;
126335
+ }
126336
+ function continuationBefore(code) {
126337
+ if (code === null || markdownLineEnding(code)) {
126338
+ return continuationStart(code);
126339
+ }
126340
+ effects.enter('htmlBlockComponentData');
126341
+ return body(code);
126342
+ }
126343
+ function continuationAfter(code) {
126344
+ if (code === null)
126345
+ return nok(code);
126346
+ effects.exit('htmlBlockComponent');
126347
+ return ok(code);
126348
+ }
126349
+ // -- shared exit --------------------------------------------------------
126350
+ function done(_code) {
126351
+ effects.exit('htmlBlockComponentData');
126352
+ effects.exit('htmlBlockComponent');
126353
+ return ok(_code);
126354
+ }
126355
+ };
126356
+ }
126357
+ // ---------------------------------------------------------------------------
126358
+ // Flow construct (block-level)
126359
+ // ---------------------------------------------------------------------------
126360
+ const html_block_component_syntax_nonLazyContinuationStart = {
126361
+ tokenize: html_block_component_syntax_tokenizeNonLazyContinuationStart,
126362
+ partial: true,
126363
+ };
126364
+ function resolveToHtmlBlockComponent(events) {
126365
+ let index = events.length;
126366
+ while (index > 0) {
126367
+ index -= 1;
126368
+ if (events[index][0] === 'enter' && events[index][1].type === 'htmlBlockComponent') {
126369
+ break;
126370
+ }
126371
+ }
126372
+ if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
126373
+ events[index][1].start = events[index - 2][1].start;
126374
+ events[index + 1][1].start = events[index - 2][1].start;
126375
+ events.splice(index - 2, 2);
126376
+ }
126377
+ return events;
126378
+ }
126379
+ const htmlBlockComponentFlowConstruct = {
126380
+ name: 'htmlBlockComponent',
126381
+ tokenize: syntax_createTokenize('flow'),
126382
+ resolveTo: resolveToHtmlBlockComponent,
126383
+ concrete: true,
126384
+ };
126385
+ function html_block_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
126386
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
126387
+ const self = this;
126388
+ return start;
126389
+ function start(code) {
126390
+ if (markdownLineEnding(code)) {
126391
+ effects.enter(types_types.lineEnding);
126392
+ effects.consume(code);
126393
+ effects.exit(types_types.lineEnding);
126394
+ return after;
126395
+ }
126396
+ return nok(code);
126397
+ }
126398
+ function after(code) {
126399
+ if (self.parser.lazy[self.now().line]) {
126400
+ return nok(code);
126401
+ }
126402
+ return ok(code);
126403
+ }
126404
+ }
126405
+ // ---------------------------------------------------------------------------
126406
+ // Text construct (inline)
126407
+ // ---------------------------------------------------------------------------
126408
+ const htmlBlockComponentTextConstruct = {
126409
+ name: 'htmlBlockComponent',
126410
+ tokenize: syntax_createTokenize('text'),
126411
+ };
126412
+ // ---------------------------------------------------------------------------
126413
+ // Extension
126414
+ // ---------------------------------------------------------------------------
126415
+ function syntax_htmlBlockComponent() {
126416
+ return {
126417
+ flow: {
126418
+ [codes.lessThan]: [htmlBlockComponentFlowConstruct],
126419
+ },
126420
+ text: {
126421
+ [codes.lessThan]: [htmlBlockComponentTextConstruct],
126422
+ },
126423
+ };
126424
+ }
126425
+
126426
+ ;// ./lib/micromark/html-block-component/index.ts
126427
+
126428
+
125755
126429
  ;// ./lib/micromark/jsx-comment/syntax.ts
125756
126430
 
125757
126431
 
@@ -125773,7 +126447,7 @@ function jsx_table_jsxTableFromMarkdown() {
125773
126447
  function tokenizeJsxComment(effects, ok, nok) {
125774
126448
  return start;
125775
126449
  function start(code) {
125776
- if (code !== codes_codes.leftCurlyBrace)
126450
+ if (code !== codes.leftCurlyBrace)
125777
126451
  return nok(code);
125778
126452
  effects.enter('mdxFlowExpression');
125779
126453
  effects.enter('mdxFlowExpressionMarker');
@@ -125782,7 +126456,7 @@ function tokenizeJsxComment(effects, ok, nok) {
125782
126456
  return expectSlash;
125783
126457
  }
125784
126458
  function expectSlash(code) {
125785
- if (code !== codes_codes.slash) {
126459
+ if (code !== codes.slash) {
125786
126460
  effects.exit('mdxFlowExpression');
125787
126461
  return nok(code);
125788
126462
  }
@@ -125791,7 +126465,7 @@ function tokenizeJsxComment(effects, ok, nok) {
125791
126465
  return expectStar;
125792
126466
  }
125793
126467
  function expectStar(code) {
125794
- if (code !== codes_codes.asterisk) {
126468
+ if (code !== codes.asterisk) {
125795
126469
  effects.exit('mdxFlowExpressionChunk');
125796
126470
  effects.exit('mdxFlowExpression');
125797
126471
  return nok(code);
@@ -125818,7 +126492,7 @@ function tokenizeJsxComment(effects, ok, nok) {
125818
126492
  effects.exit('mdxFlowExpressionChunk');
125819
126493
  return before(code);
125820
126494
  }
125821
- if (code === codes_codes.asterisk) {
126495
+ if (code === codes.asterisk) {
125822
126496
  effects.consume(code);
125823
126497
  return maybeClosed;
125824
126498
  }
@@ -125830,11 +126504,11 @@ function tokenizeJsxComment(effects, ok, nok) {
125830
126504
  effects.exit('mdxFlowExpressionChunk');
125831
126505
  return before(code);
125832
126506
  }
125833
- if (code === codes_codes.slash) {
126507
+ if (code === codes.slash) {
125834
126508
  effects.consume(code);
125835
126509
  return expectClosingBrace;
125836
126510
  }
125837
- if (code === codes_codes.asterisk) {
126511
+ if (code === codes.asterisk) {
125838
126512
  effects.consume(code);
125839
126513
  return maybeClosed;
125840
126514
  }
@@ -125846,7 +126520,7 @@ function tokenizeJsxComment(effects, ok, nok) {
125846
126520
  effects.exit('mdxFlowExpressionChunk');
125847
126521
  return before(code);
125848
126522
  }
125849
- if (code === codes_codes.rightCurlyBrace) {
126523
+ if (code === codes.rightCurlyBrace) {
125850
126524
  effects.exit('mdxFlowExpressionChunk');
125851
126525
  effects.enter('mdxFlowExpressionMarker');
125852
126526
  effects.consume(code);
@@ -125854,7 +126528,7 @@ function tokenizeJsxComment(effects, ok, nok) {
125854
126528
  effects.exit('mdxFlowExpression');
125855
126529
  return ok;
125856
126530
  }
125857
- if (code === codes_codes.asterisk) {
126531
+ if (code === codes.asterisk) {
125858
126532
  effects.consume(code);
125859
126533
  return maybeClosed;
125860
126534
  }
@@ -125865,7 +126539,7 @@ function tokenizeJsxComment(effects, ok, nok) {
125865
126539
  function jsxComment() {
125866
126540
  return {
125867
126541
  flow: {
125868
- [codes_codes.leftCurlyBrace]: {
126542
+ [codes.leftCurlyBrace]: {
125869
126543
  name: 'jsxComment',
125870
126544
  concrete: true,
125871
126545
  tokenize: tokenizeJsxComment,
@@ -125874,243 +126548,6 @@ function jsxComment() {
125874
126548
  };
125875
126549
  }
125876
126550
 
125877
- ;// ./lib/micromark/jsx-table/syntax.ts
125878
-
125879
-
125880
- const jsx_table_syntax_nonLazyContinuationStart = {
125881
- tokenize: jsx_table_syntax_tokenizeNonLazyContinuationStart,
125882
- partial: true,
125883
- };
125884
- function resolveToJsxTable(events) {
125885
- let index = events.length;
125886
- while (index > 0) {
125887
- index -= 1;
125888
- if (events[index][0] === 'enter' && events[index][1].type === 'jsxTable') {
125889
- break;
125890
- }
125891
- }
125892
- if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
125893
- events[index][1].start = events[index - 2][1].start;
125894
- events[index + 1][1].start = events[index - 2][1].start;
125895
- events.splice(index - 2, 2);
125896
- }
125897
- return events;
125898
- }
125899
- const jsxTableConstruct = {
125900
- name: 'jsxTable',
125901
- tokenize: tokenizeJsxTable,
125902
- resolveTo: resolveToJsxTable,
125903
- concrete: true,
125904
- };
125905
- function tokenizeJsxTable(effects, ok, nok) {
125906
- let codeSpanOpenSize = 0;
125907
- let codeSpanCloseSize = 0;
125908
- let depth = 1;
125909
- const ABLE_SUFFIX = [codes_codes.lowercaseA, codes_codes.lowercaseB, codes_codes.lowercaseL, codes_codes.lowercaseE];
125910
- /** Build a state chain that matches a sequence of character codes. */
125911
- function matchChars(chars, onMatch, onFail) {
125912
- if (chars.length === 0)
125913
- return onMatch;
125914
- return ((code) => {
125915
- if (code === chars[0]) {
125916
- effects.consume(code);
125917
- return matchChars(chars.slice(1), onMatch, onFail);
125918
- }
125919
- return onFail(code);
125920
- });
125921
- }
125922
- return start;
125923
- function start(code) {
125924
- if (code !== codes_codes.lessThan)
125925
- return nok(code);
125926
- effects.enter('jsxTable');
125927
- effects.enter('jsxTableData');
125928
- effects.consume(code);
125929
- return afterLessThan;
125930
- }
125931
- function afterLessThan(code) {
125932
- if (code === codes_codes.uppercaseT || code === codes_codes.lowercaseT) {
125933
- effects.consume(code);
125934
- return matchChars(ABLE_SUFFIX, afterTagName, nok);
125935
- }
125936
- return nok(code);
125937
- }
125938
- function afterTagName(code) {
125939
- if (code === codes_codes.greaterThan || code === codes_codes.slash || code === codes_codes.space || code === codes_codes.horizontalTab) {
125940
- effects.consume(code);
125941
- return body;
125942
- }
125943
- return nok(code);
125944
- }
125945
- function body(code) {
125946
- // Reject unclosed <Table> so it falls back to normal HTML block parsing
125947
- // instead of swallowing all subsequent content to EOF
125948
- if (code === null) {
125949
- return nok(code);
125950
- }
125951
- if (markdownLineEnding(code)) {
125952
- effects.exit('jsxTableData');
125953
- return continuationStart(code);
125954
- }
125955
- if (code === codes_codes.backslash) {
125956
- effects.consume(code);
125957
- return escapedChar;
125958
- }
125959
- if (code === codes_codes.lessThan) {
125960
- effects.consume(code);
125961
- return closeSlash;
125962
- }
125963
- // Skip over backtick code spans so `</Table>` in inline code isn't
125964
- // treated as the closing tag
125965
- if (code === codes_codes.graveAccent) {
125966
- codeSpanOpenSize = 0;
125967
- return countOpenTicks(code);
125968
- }
125969
- effects.consume(code);
125970
- return body;
125971
- }
125972
- function countOpenTicks(code) {
125973
- if (code === codes_codes.graveAccent) {
125974
- codeSpanOpenSize += 1;
125975
- effects.consume(code);
125976
- return countOpenTicks;
125977
- }
125978
- return inCodeSpan(code);
125979
- }
125980
- function inCodeSpan(code) {
125981
- if (code === null || markdownLineEnding(code))
125982
- return body(code);
125983
- if (code === codes_codes.graveAccent) {
125984
- codeSpanCloseSize = 0;
125985
- return countCloseTicks(code);
125986
- }
125987
- effects.consume(code);
125988
- return inCodeSpan;
125989
- }
125990
- function countCloseTicks(code) {
125991
- if (code === codes_codes.graveAccent) {
125992
- codeSpanCloseSize += 1;
125993
- effects.consume(code);
125994
- return countCloseTicks;
125995
- }
125996
- return codeSpanCloseSize === codeSpanOpenSize ? body(code) : inCodeSpan(code);
125997
- }
125998
- function escapedChar(code) {
125999
- if (code === null || markdownLineEnding(code)) {
126000
- return body(code);
126001
- }
126002
- effects.consume(code);
126003
- return body;
126004
- }
126005
- function closeSlash(code) {
126006
- if (code === codes_codes.slash) {
126007
- effects.consume(code);
126008
- return closeTagFirstChar;
126009
- }
126010
- if (code === codes_codes.uppercaseT || code === codes_codes.lowercaseT) {
126011
- effects.consume(code);
126012
- return matchChars(ABLE_SUFFIX, openAfterTagName, body);
126013
- }
126014
- return body(code);
126015
- }
126016
- function closeTagFirstChar(code) {
126017
- if (code === codes_codes.uppercaseT || code === codes_codes.lowercaseT) {
126018
- effects.consume(code);
126019
- return matchChars(ABLE_SUFFIX, closeGt, body);
126020
- }
126021
- return body(code);
126022
- }
126023
- function openAfterTagName(code) {
126024
- if (code === codes_codes.greaterThan || code === codes_codes.slash || code === codes_codes.space || code === codes_codes.horizontalTab) {
126025
- depth += 1;
126026
- effects.consume(code);
126027
- return body;
126028
- }
126029
- return body(code);
126030
- }
126031
- function closeGt(code) {
126032
- if (code === codes_codes.greaterThan) {
126033
- depth -= 1;
126034
- effects.consume(code);
126035
- if (depth === 0) {
126036
- return afterClose;
126037
- }
126038
- return body;
126039
- }
126040
- return body(code);
126041
- }
126042
- function afterClose(code) {
126043
- if (code === null || markdownLineEnding(code)) {
126044
- effects.exit('jsxTableData');
126045
- effects.exit('jsxTable');
126046
- return ok(code);
126047
- }
126048
- effects.consume(code);
126049
- return afterClose;
126050
- }
126051
- // Line ending handling — follows the htmlFlow pattern
126052
- function continuationStart(code) {
126053
- return effects.check(jsx_table_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
126054
- }
126055
- function continuationStartNonLazy(code) {
126056
- effects.enter(types_types.lineEnding);
126057
- effects.consume(code);
126058
- effects.exit(types_types.lineEnding);
126059
- return continuationBefore;
126060
- }
126061
- function continuationBefore(code) {
126062
- if (code === null || markdownLineEnding(code)) {
126063
- return continuationStart(code);
126064
- }
126065
- effects.enter('jsxTableData');
126066
- return body(code);
126067
- }
126068
- function continuationAfter(code) {
126069
- // At EOF without </Table>, reject so content isn't swallowed
126070
- if (code === null) {
126071
- return nok(code);
126072
- }
126073
- effects.exit('jsxTable');
126074
- return ok(code);
126075
- }
126076
- }
126077
- function jsx_table_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
126078
- // eslint-disable-next-line @typescript-eslint/no-this-alias
126079
- const self = this;
126080
- return start;
126081
- function start(code) {
126082
- if (markdownLineEnding(code)) {
126083
- effects.enter(types_types.lineEnding);
126084
- effects.consume(code);
126085
- effects.exit(types_types.lineEnding);
126086
- return after;
126087
- }
126088
- return nok(code);
126089
- }
126090
- function after(code) {
126091
- if (self.parser.lazy[self.now().line]) {
126092
- return nok(code);
126093
- }
126094
- return ok(code);
126095
- }
126096
- }
126097
- /**
126098
- * Micromark extension that tokenizes `<Table>...</Table>` and `<table>...</table>`
126099
- * as a single flow block.
126100
- *
126101
- * Prevents CommonMark HTML block type 6 from fragmenting table blocks at blank lines.
126102
- */
126103
- function syntax_jsxTable() {
126104
- return {
126105
- flow: {
126106
- [codes_codes.lessThan]: [jsxTableConstruct],
126107
- },
126108
- };
126109
- }
126110
-
126111
- ;// ./lib/micromark/jsx-table/index.ts
126112
-
126113
-
126114
126551
  ;// ./lib/micromark/mdx-expression-lenient/syntax.ts
126115
126552
 
126116
126553
 
@@ -126130,7 +126567,7 @@ function tokenizeTextExpression(effects, ok, nok) {
126130
126567
  let depth = 0;
126131
126568
  return start;
126132
126569
  function start(code) {
126133
- if (code !== codes_codes.leftCurlyBrace)
126570
+ if (code !== codes.leftCurlyBrace)
126134
126571
  return nok(code);
126135
126572
  effects.enter('mdxTextExpression');
126136
126573
  effects.enter('mdxTextExpressionMarker');
@@ -126139,7 +126576,7 @@ function tokenizeTextExpression(effects, ok, nok) {
126139
126576
  return before;
126140
126577
  }
126141
126578
  function before(code) {
126142
- if (code === codes_codes.eof) {
126579
+ if (code === codes.eof) {
126143
126580
  effects.exit('mdxTextExpression');
126144
126581
  return nok(code);
126145
126582
  }
@@ -126149,24 +126586,24 @@ function tokenizeTextExpression(effects, ok, nok) {
126149
126586
  effects.exit('lineEnding');
126150
126587
  return before;
126151
126588
  }
126152
- if (code === codes_codes.rightCurlyBrace && depth === 0) {
126589
+ if (code === codes.rightCurlyBrace && depth === 0) {
126153
126590
  return close(code);
126154
126591
  }
126155
126592
  effects.enter('mdxTextExpressionChunk');
126156
126593
  return inside(code);
126157
126594
  }
126158
126595
  function inside(code) {
126159
- if (code === codes_codes.eof || markdownLineEnding(code)) {
126596
+ if (code === codes.eof || markdownLineEnding(code)) {
126160
126597
  effects.exit('mdxTextExpressionChunk');
126161
126598
  return before(code);
126162
126599
  }
126163
- if (code === codes_codes.rightCurlyBrace && depth === 0) {
126600
+ if (code === codes.rightCurlyBrace && depth === 0) {
126164
126601
  effects.exit('mdxTextExpressionChunk');
126165
126602
  return close(code);
126166
126603
  }
126167
- if (code === codes_codes.leftCurlyBrace)
126604
+ if (code === codes.leftCurlyBrace)
126168
126605
  depth += 1;
126169
- else if (code === codes_codes.rightCurlyBrace)
126606
+ else if (code === codes.rightCurlyBrace)
126170
126607
  depth -= 1;
126171
126608
  effects.consume(code);
126172
126609
  return inside;
@@ -126182,7 +126619,7 @@ function tokenizeTextExpression(effects, ok, nok) {
126182
126619
  function mdxExpressionLenient() {
126183
126620
  return {
126184
126621
  text: {
126185
- [codes_codes.leftCurlyBrace]: {
126622
+ [codes.leftCurlyBrace]: {
126186
126623
  name: 'mdxTextExpression',
126187
126624
  tokenize: tokenizeTextExpression,
126188
126625
  },
@@ -126286,6 +126723,9 @@ function loadComponents() {
126286
126723
 
126287
126724
 
126288
126725
 
126726
+
126727
+
126728
+
126289
126729
 
126290
126730
 
126291
126731
 
@@ -126300,15 +126740,19 @@ const defaultTransformers = [
126300
126740
  * CommonMark/remark limitations and reach parity with legacy (rdmd) rendering.
126301
126741
  *
126302
126742
  * Runs a series of string-level transformations before micromark/remark parsing:
126303
- * 1. Normalize malformed table separator syntax (e.g., `|: ---``| :---`)
126304
- * 2. Terminate HTML flow blocks so subsequent content isn't swallowed
126305
- * 3. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
126306
- * 4. Normalize compact ATX headings (e.g., `#Heading``# Heading`)
126307
- * 5. Replace snake_case component names with parser-safe placeholders
126743
+ * 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` `</td>`)
126744
+ * 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
126745
+ * 3. Terminate HTML flow blocks so subsequent content isn't swallowed
126746
+ * 4. Close invalid "self-closing" HTML tags (e.g., `<i />` `<i></i>`)
126747
+ * 5. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
126748
+ * 6. Replace snake_case component names with parser-safe placeholders
126308
126749
  */
126309
126750
  function preprocessContent(content, opts) {
126310
126751
  const { knownComponents } = opts;
126311
- let result = normalizeTableSeparator(content);
126752
+ // Runs first so `jsxTable` sees a literal `</table>` (and the HTML-line
126753
+ // classification in `terminateHtmlFlowBlocks` is accurate)
126754
+ let result = normalizeClosingTagWhitespace(content);
126755
+ result = normalizeTableSeparator(result);
126312
126756
  result = terminateHtmlFlowBlocks(result);
126313
126757
  result = closeSelfClosingHtmlTags(result);
126314
126758
  result = normalizeCompactHeadings(result);
@@ -126337,6 +126781,7 @@ function mdxishAstProcessor(mdContent, opts = {}) {
126337
126781
  syntax_gemoji(),
126338
126782
  legacyVariable(),
126339
126783
  looseHtmlEntity(),
126784
+ syntax_htmlBlockComponent(),
126340
126785
  ];
126341
126786
  const fromMarkdownExts = [
126342
126787
  jsx_table_jsxTableFromMarkdown(),
@@ -126346,6 +126791,7 @@ function mdxishAstProcessor(mdContent, opts = {}) {
126346
126791
  legacyVariableFromMarkdown(),
126347
126792
  emptyTaskListItemFromMarkdown(),
126348
126793
  looseHtmlEntityFromMarkdown(),
126794
+ html_block_component_htmlBlockComponentFromMarkdown(),
126349
126795
  ];
126350
126796
  if (!safeMode) {
126351
126797
  // Insert mdx expression (text-only, no flow) after gemoji at index 3
@@ -126359,6 +126805,10 @@ function mdxishAstProcessor(mdContent, opts = {}) {
126359
126805
  // JSX comment tokenizer must come before magicBlock so it claims `{/* ... */}` first
126360
126806
  micromarkExts.unshift(jsxComment());
126361
126807
  }
126808
+ // Claim `<HTMLBlock>` as one opaque token so broad tokenizers can't fragment its body
126809
+ // We put this last as micromark tries the last-registered extension first, so push (not unshift) to win the `<` race.
126810
+ // micromarkExts.push(htmlBlockComponent());
126811
+ // fromMarkdownExts.push(htmlBlockComponentFromMarkdown());
126362
126812
  const processor = lib_unified()
126363
126813
  .data('micromarkExtensions', micromarkExts)
126364
126814
  .data('fromMarkdownExtensions', fromMarkdownExts)
@@ -126442,7 +126892,7 @@ function mdxish_mdxish(mdContent, opts = {}) {
126442
126892
  const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
126443
126893
  processor
126444
126894
  .use(safeMode ? undefined : evaluate_exports) // Evaluate `export const/function` and stash scope on file.data.mdxishScope
126445
- .use(remarkBreaks) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
126895
+ .use(hard_breaks) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
126446
126896
  .use(safeMode ? undefined : evaluate_expressions) // Evaluate self-contained MDX expressions (e.g. `{1+1}`)
126447
126897
  .use(safeMode ? undefined : evaluate_style_block_expressions) // Evaluate `<style>{`...`}</style>` template literals into plain CSS
126448
126898
  .use(variables_code, { variables }) // Resolve <<...>> and {user.*} inside code and inline code nodes
@@ -126902,332 +127352,6 @@ const mdxishTags_tags = (doc) => {
126902
127352
  };
126903
127353
  /* harmony default export */ const mdxishTags = ((/* unused pure expression or super */ null && (mdxishTags_tags)));
126904
127354
 
126905
- ;// ./lib/mdast-util/html-block-component/index.ts
126906
- const html_block_component_contextMap = new WeakMap();
126907
- function findHtmlBlockComponentToken() {
126908
- const events = this.tokenStack;
126909
- for (let i = events.length - 1; i >= 0; i -= 1) {
126910
- if (events[i][0].type === 'htmlBlockComponent')
126911
- return events[i][0];
126912
- }
126913
- return undefined;
126914
- }
126915
- function enterHtmlBlockComponent(token) {
126916
- html_block_component_contextMap.set(token, { chunks: [], lastEndLine: token.start.line });
126917
- this.enter({ type: 'html', value: '' }, token);
126918
- }
126919
- function exitHtmlBlockComponentData(token) {
126920
- const componentToken = findHtmlBlockComponentToken.call(this);
126921
- if (!componentToken)
126922
- return;
126923
- const ctx = html_block_component_contextMap.get(componentToken);
126924
- if (ctx) {
126925
- const gap = token.start.line - ctx.lastEndLine;
126926
- if (ctx.chunks.length > 0 && gap > 0) {
126927
- ctx.chunks.push('\n'.repeat(gap));
126928
- }
126929
- ctx.chunks.push(this.sliceSerialize(token));
126930
- ctx.lastEndLine = token.end.line;
126931
- }
126932
- }
126933
- function exitHtmlBlockComponent(token) {
126934
- const ctx = html_block_component_contextMap.get(token);
126935
- const node = this.stack[this.stack.length - 1];
126936
- if (ctx) {
126937
- node.value = ctx.chunks.join('');
126938
- html_block_component_contextMap.delete(token);
126939
- }
126940
- this.exit(token);
126941
- }
126942
- function html_block_component_htmlBlockComponentFromMarkdown() {
126943
- return {
126944
- enter: {
126945
- htmlBlockComponent: enterHtmlBlockComponent,
126946
- },
126947
- exit: {
126948
- htmlBlockComponentData: exitHtmlBlockComponentData,
126949
- htmlBlockComponent: exitHtmlBlockComponent,
126950
- },
126951
- };
126952
- }
126953
-
126954
- ;// ./lib/micromark/html-block-component/syntax.ts
126955
-
126956
-
126957
- const TAG_SUFFIX = [
126958
- codes_codes.uppercaseT,
126959
- codes_codes.uppercaseM,
126960
- codes_codes.uppercaseL,
126961
- codes_codes.uppercaseB,
126962
- codes_codes.lowercaseL,
126963
- codes_codes.lowercaseO,
126964
- codes_codes.lowercaseC,
126965
- codes_codes.lowercaseK,
126966
- ];
126967
- // ---------------------------------------------------------------------------
126968
- // Shared tokenizer factory
126969
- // ---------------------------------------------------------------------------
126970
- /**
126971
- * Creates a tokenize function for `<HTMLBlock>...</HTMLBlock>`.
126972
- *
126973
- * - **flow** (block-level): supports multiline content via line continuations,
126974
- * consumes trailing whitespace after the closing tag.
126975
- * - **text** (inline): single-line only, exits immediately after the closing tag.
126976
- */
126977
- function syntax_createTokenize(mode) {
126978
- return function tokenize(effects, ok, nok) {
126979
- let depth = 1;
126980
- function matchChars(chars, onMatch, onFail) {
126981
- if (chars.length === 0)
126982
- return onMatch;
126983
- const next = (code) => {
126984
- if (code === chars[0]) {
126985
- effects.consume(code);
126986
- return matchChars(chars.slice(1), onMatch, onFail);
126987
- }
126988
- return onFail(code);
126989
- };
126990
- return next;
126991
- }
126992
- function matchTagName(onMatch, onFail) {
126993
- const next = (code) => {
126994
- if (code === codes_codes.uppercaseH) {
126995
- effects.consume(code);
126996
- return matchChars(TAG_SUFFIX, onMatch, onFail);
126997
- }
126998
- return onFail(code);
126999
- };
127000
- return next;
127001
- }
127002
- return start;
127003
- function start(code) {
127004
- if (code !== codes_codes.lessThan)
127005
- return nok(code);
127006
- effects.enter('htmlBlockComponent');
127007
- effects.enter('htmlBlockComponentData');
127008
- effects.consume(code);
127009
- return matchTagName(afterTagName, nok);
127010
- }
127011
- function afterTagName(code) {
127012
- if (code === codes_codes.greaterThan) {
127013
- effects.consume(code);
127014
- return body;
127015
- }
127016
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
127017
- effects.consume(code);
127018
- return inAttributes;
127019
- }
127020
- if (mode === 'flow' && markdownLineEnding(code)) {
127021
- effects.exit('htmlBlockComponentData');
127022
- return attributeContinuationStart(code);
127023
- }
127024
- if (code === codes_codes.slash) {
127025
- effects.consume(code);
127026
- return selfClose;
127027
- }
127028
- return nok(code);
127029
- }
127030
- function inAttributes(code) {
127031
- if (code === codes_codes.greaterThan) {
127032
- effects.consume(code);
127033
- return body;
127034
- }
127035
- if (code === null) {
127036
- return nok(code);
127037
- }
127038
- if (markdownLineEnding(code)) {
127039
- if (mode === 'text')
127040
- return nok(code);
127041
- effects.exit('htmlBlockComponentData');
127042
- return attributeContinuationStart(code);
127043
- }
127044
- effects.consume(code);
127045
- return inAttributes;
127046
- }
127047
- function attributeContinuationStart(code) {
127048
- return effects.check(html_block_component_syntax_nonLazyContinuationStart, attributeContinuationNonLazy, continuationAfter)(code);
127049
- }
127050
- function attributeContinuationNonLazy(code) {
127051
- effects.enter(types_types.lineEnding);
127052
- effects.consume(code);
127053
- effects.exit(types_types.lineEnding);
127054
- return attributeContinuationBefore;
127055
- }
127056
- function attributeContinuationBefore(code) {
127057
- if (code === null || markdownLineEnding(code)) {
127058
- return attributeContinuationStart(code);
127059
- }
127060
- effects.enter('htmlBlockComponentData');
127061
- return inAttributes(code);
127062
- }
127063
- function selfClose(code) {
127064
- if (code === codes_codes.greaterThan) {
127065
- effects.consume(code);
127066
- return mode === 'flow' ? afterClose : done(code);
127067
- }
127068
- return nok(code);
127069
- }
127070
- function body(code) {
127071
- if (code === null)
127072
- return nok(code);
127073
- if (markdownLineEnding(code)) {
127074
- if (mode === 'text') {
127075
- // Text constructs operate on paragraph content which spans lines
127076
- effects.consume(code);
127077
- return body;
127078
- }
127079
- effects.exit('htmlBlockComponentData');
127080
- return continuationStart(code);
127081
- }
127082
- if (code === codes_codes.lessThan) {
127083
- effects.consume(code);
127084
- return closeSlash;
127085
- }
127086
- effects.consume(code);
127087
- return body;
127088
- }
127089
- function closeSlash(code) {
127090
- if (code === codes_codes.slash) {
127091
- effects.consume(code);
127092
- return matchTagName(closeGt, body);
127093
- }
127094
- return matchTagName(openAfterTagName, body)(code);
127095
- }
127096
- function openAfterTagName(code) {
127097
- if (code === codes_codes.greaterThan || code === codes_codes.space || code === codes_codes.horizontalTab) {
127098
- depth += 1;
127099
- effects.consume(code);
127100
- return body;
127101
- }
127102
- return body(code);
127103
- }
127104
- function closeGt(code) {
127105
- if (code === codes_codes.greaterThan) {
127106
- depth -= 1;
127107
- effects.consume(code);
127108
- if (depth === 0) {
127109
- return mode === 'flow' ? afterClose : done(code);
127110
- }
127111
- return body;
127112
- }
127113
- return body(code);
127114
- }
127115
- // -- flow-only states ---------------------------------------------------
127116
- function afterClose(code) {
127117
- if (code === null || markdownLineEnding(code)) {
127118
- return done(code);
127119
- }
127120
- if (code === codes_codes.space || code === codes_codes.horizontalTab) {
127121
- effects.consume(code);
127122
- return afterClose;
127123
- }
127124
- // Reject so the block re-parses as a paragraph, deferring to the
127125
- // text tokenizer which preserves trailing content in the same line.
127126
- return nok(code);
127127
- }
127128
- // -- flow-only: line continuation ---------------------------------------
127129
- function continuationStart(code) {
127130
- return effects.check(html_block_component_syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
127131
- }
127132
- function continuationStartNonLazy(code) {
127133
- effects.enter(types_types.lineEnding);
127134
- effects.consume(code);
127135
- effects.exit(types_types.lineEnding);
127136
- return continuationBefore;
127137
- }
127138
- function continuationBefore(code) {
127139
- if (code === null || markdownLineEnding(code)) {
127140
- return continuationStart(code);
127141
- }
127142
- effects.enter('htmlBlockComponentData');
127143
- return body(code);
127144
- }
127145
- function continuationAfter(code) {
127146
- if (code === null)
127147
- return nok(code);
127148
- effects.exit('htmlBlockComponent');
127149
- return ok(code);
127150
- }
127151
- // -- shared exit --------------------------------------------------------
127152
- function done(_code) {
127153
- effects.exit('htmlBlockComponentData');
127154
- effects.exit('htmlBlockComponent');
127155
- return ok(_code);
127156
- }
127157
- };
127158
- }
127159
- // ---------------------------------------------------------------------------
127160
- // Flow construct (block-level)
127161
- // ---------------------------------------------------------------------------
127162
- const html_block_component_syntax_nonLazyContinuationStart = {
127163
- tokenize: html_block_component_syntax_tokenizeNonLazyContinuationStart,
127164
- partial: true,
127165
- };
127166
- function resolveToHtmlBlockComponent(events) {
127167
- let index = events.length;
127168
- while (index > 0) {
127169
- index -= 1;
127170
- if (events[index][0] === 'enter' && events[index][1].type === 'htmlBlockComponent') {
127171
- break;
127172
- }
127173
- }
127174
- if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
127175
- events[index][1].start = events[index - 2][1].start;
127176
- events[index + 1][1].start = events[index - 2][1].start;
127177
- events.splice(index - 2, 2);
127178
- }
127179
- return events;
127180
- }
127181
- const htmlBlockComponentFlowConstruct = {
127182
- name: 'htmlBlockComponent',
127183
- tokenize: syntax_createTokenize('flow'),
127184
- resolveTo: resolveToHtmlBlockComponent,
127185
- concrete: true,
127186
- };
127187
- function html_block_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
127188
- // eslint-disable-next-line @typescript-eslint/no-this-alias
127189
- const self = this;
127190
- return start;
127191
- function start(code) {
127192
- if (markdownLineEnding(code)) {
127193
- effects.enter(types_types.lineEnding);
127194
- effects.consume(code);
127195
- effects.exit(types_types.lineEnding);
127196
- return after;
127197
- }
127198
- return nok(code);
127199
- }
127200
- function after(code) {
127201
- if (self.parser.lazy[self.now().line]) {
127202
- return nok(code);
127203
- }
127204
- return ok(code);
127205
- }
127206
- }
127207
- // ---------------------------------------------------------------------------
127208
- // Text construct (inline)
127209
- // ---------------------------------------------------------------------------
127210
- const htmlBlockComponentTextConstruct = {
127211
- name: 'htmlBlockComponent',
127212
- tokenize: syntax_createTokenize('text'),
127213
- };
127214
- // ---------------------------------------------------------------------------
127215
- // Extension
127216
- // ---------------------------------------------------------------------------
127217
- function syntax_htmlBlockComponent() {
127218
- return {
127219
- flow: {
127220
- [codes.lessThan]: [htmlBlockComponentFlowConstruct],
127221
- },
127222
- text: {
127223
- [codes.lessThan]: [htmlBlockComponentTextConstruct],
127224
- },
127225
- };
127226
- }
127227
-
127228
- ;// ./lib/micromark/html-block-component/index.ts
127229
-
127230
-
127231
127355
  ;// ./lib/stripComments.ts
127232
127356
 
127233
127357