@readme/markdown 13.6.0 → 13.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -11357,6 +11357,7 @@ __webpack_require__.r(__webpack_exports__);
11357
11357
  // EXPORTS
11358
11358
  __webpack_require__.d(__webpack_exports__, {
11359
11359
  Components: () => (/* reexport */ components_namespaceObject),
11360
+ FLOW_TYPES: () => (/* reexport */ FLOW_TYPES),
11360
11361
  Owlmoji: () => (/* reexport */ Owlmoji),
11361
11362
  compile: () => (/* reexport */ lib_compile),
11362
11363
  exports: () => (/* reexport */ lib_exports),
@@ -12538,6 +12539,28 @@ var parseOptions = function parseOptions() {
12538
12539
  return opts;
12539
12540
  };
12540
12541
 
12542
+ ;// ./lib/constants.ts
12543
+ /**
12544
+ * Pattern to match component tags (PascalCase or snake_case)
12545
+ */
12546
+ const componentTagPattern = /<(\/?[A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>/g;
12547
+ /**
12548
+ * MDAST flow (block-level) content types that cannot be represented
12549
+ * inside GFM table cells. Used to decide whether a table should be
12550
+ * serialized as GFM or as JSX `<Table>` syntax.
12551
+ *
12552
+ * @see https://github.com/syntax-tree/mdast#flowcontent
12553
+ */
12554
+ const FLOW_TYPES = new Set([
12555
+ 'blockquote',
12556
+ 'code',
12557
+ 'heading',
12558
+ 'html',
12559
+ 'list',
12560
+ 'table',
12561
+ 'thematicBreak',
12562
+ ]);
12563
+
12541
12564
  ;// ./node_modules/github-slugger/regex.js
12542
12565
  // This module is generated by `script/`.
12543
12566
  /* eslint-disable no-control-regex, no-misleading-character-class, no-useless-escape */
@@ -52992,17 +53015,22 @@ function plain_one(node, opts) {
52992
53015
  function plain_all(node, opts) {
52993
53016
  let index = -1;
52994
53017
  const result = [];
53018
+ const separator = opts.separator ?? ' ';
52995
53019
  // eslint-disable-next-line no-plusplus
52996
53020
  while (++index < node?.children.length) {
52997
53021
  result[index] = plain_one(node.children[index], opts);
52998
53022
  }
52999
- return result.join(' ').replaceAll(/\s+/g, ' ').trim();
53023
+ return result.join(separator).replaceAll(/\s+/g, ' ').trim();
53000
53024
  }
53001
53025
  const plain = (node, opts = {}) => {
53002
53026
  return 'children' in node ? plain_all(node, opts) || plain_one(node, opts) : plain_one(node, opts);
53003
53027
  };
53004
53028
  /* harmony default export */ const lib_plain = (plain);
53005
53029
 
53030
+ ;// ./processor/compile/variable.ts
53031
+ const variable = (node) => `{user.${node.data?.hProperties?.name || ''}}`;
53032
+ /* harmony default export */ const compile_variable = (variable);
53033
+
53006
53034
  ;// ./processor/transform/extract-text.ts
53007
53035
  /**
53008
53036
  * Extracts text content from a single AST node recursively.
@@ -53014,7 +53042,7 @@ const plain = (node, opts = {}) => {
53014
53042
  * @returns The concatenated text content
53015
53043
  */
53016
53044
  const extractText = (node) => {
53017
- if (node.type === 'text' && typeof node.value === 'string') {
53045
+ if ((node.type === 'text' || node.type === 'html') && typeof node.value === 'string') {
53018
53046
  return node.value;
53019
53047
  }
53020
53048
  // When a blockquote contains only an image (no text), treat it as having content
@@ -53047,8 +53075,18 @@ const extractText = (node) => {
53047
53075
 
53048
53076
 
53049
53077
 
53078
+
53079
+
53050
53080
  const titleParser = unified().use(remarkParse).use(remarkGfm);
53051
- const toMarkdownExtensions = [gfmStrikethroughToMarkdown()];
53081
+ // The title paragraph may contain custom AST nodes that `toMarkdown` doesn't
53082
+ // natively understand
53083
+ const toMarkdownExtensions = [
53084
+ gfmStrikethroughToMarkdown(),
53085
+ // For mdx variable syntaxes (e.g., {user.name})
53086
+ mdxExpressionToMarkdown(),
53087
+ // Important: This is required and would crash the parser if there's no variable node handler
53088
+ { handlers: { [NodeTypes.variable]: compile_variable } },
53089
+ ];
53052
53090
  const callouts_regex = `^(${emoji_regex().source}|⚠)(\\s+|$)`;
53053
53091
  const findFirst = (node) => {
53054
53092
  if ('children' in node)
@@ -70869,693 +70907,348 @@ const mdxToHast = () => tree => {
70869
70907
  };
70870
70908
  /* harmony default export */ const mdx_to_hast = (mdxToHast);
70871
70909
 
70872
- ;// ./lib/mdast-util/empty-task-list-item/index.ts
70910
+ ;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
70911
+
70912
+ // Marker patterns for multi-node emphasis detection
70913
+ const MARKER_PATTERNS = [
70914
+ { isBold: true, marker: '**' },
70915
+ { isBold: true, marker: '__' },
70916
+ { isBold: false, marker: '*' },
70917
+ { isBold: false, marker: '_' },
70918
+ ];
70919
+ // Patterns to detect for bold (** and __) and italic (* and _) syntax:
70920
+ // Bold: ** text**, **text **, word** text**, ** text **
70921
+ // Italic: * text*, *text *, word* text*, * text *
70922
+ // Same patterns for underscore variants
70923
+ // We use separate patterns for each marker type to allow this flexibility.
70924
+ // Pattern for ** bold **
70925
+ // Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
70926
+ // trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
70927
+ const asteriskBoldRegex = /([^*\s]+)?\s*(\*\*)(?:\s+((?:[^*\n]|\*(?!\*))+?)(\s*)\2|((?:[^*\n]|\*(?!\*))+?)(\s+)\2)(\S|$)?/g;
70928
+ // Pattern for __ bold __
70929
+ const underscoreBoldRegex = /([^_\s]+)?\s*(__)(?:\s+((?:__(?! )|_(?!_)|[^_\n])+?)(\s*)\2|((?:__(?! )|_(?!_)|[^_\n])+?)(\s+)\2)(\S|$)?/g;
70930
+ // Pattern for * italic *
70931
+ const asteriskItalicRegex = /([^*\s]+)?\s*(\*)(?!\*)(?:\s+([^*\n]+?)(\s*)\2|([^*\n]+?)(\s+)\2)(\S|$)?/g;
70932
+ // Pattern for _ italic _
70933
+ const underscoreItalicRegex = /([^_\s]+)?\s*(_)(?!_)(?:\s+((?:[^_\n]|_(?! ))+?)(\s*)\2|((?:[^_\n]|_(?! ))+?)(\s+)\2)(\S|$)?/g;
70934
+ // CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
70935
+ // Pattern for intraword _word_ in words like hello_world_
70936
+ const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
70937
+ // Pattern for intraword __word__ in words like hello__world__
70938
+ const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
70939
+ // Pattern for intraword *word* in words like hello*world*
70940
+ const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
70941
+ // Pattern for intraword **word** in words like hello**world**
70942
+ const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
70873
70943
  /**
70874
- * Normalizes list items that are written as only `[ ]` or `[x]` into GFM task
70875
- * list items during parse, but only when at least one whitespace character
70876
- * follows the closing bracket (`]`). This matches legacy behaviour for checkboxes
70877
- *
70878
- * The issue is `remark-gfm` does not actually classify these as task items when they have no content
70879
- * after the checkbox, which leaves them as plain text (`"[ ]"`). So a custom extension is needed to
70880
- * treat these as task items
70944
+ * Finds opening emphasis marker in a text value.
70945
+ * Returns marker info if found, null otherwise.
70881
70946
  */
70882
- function exitListItemWithEmptyTaskListItem(token) {
70883
- const node = this.stack[this.stack.length - 1];
70884
- if (node &&
70885
- node.type === 'listItem' &&
70886
- typeof node.checked !== 'boolean') {
70887
- const listItem = node;
70888
- const head = listItem.children[0];
70889
- if (head && head.type === 'paragraph' && head.children.length === 1) {
70890
- const text = head.children[0];
70891
- if (text.type === 'text') {
70892
- const hasTrailingWhitespace = typeof head.position?.end.offset === 'number' &&
70893
- typeof text.position?.end.offset === 'number' &&
70894
- head.position.end.offset > text.position.end.offset;
70895
- if (!hasTrailingWhitespace) {
70896
- this.exit(token);
70897
- return;
70898
- }
70899
- const value = text.value;
70900
- if (value === '[ ]') {
70901
- listItem.checked = false;
70902
- head.children = [];
70903
- }
70904
- else if (value === '[x]' || value === '[X]') {
70905
- listItem.checked = true;
70906
- head.children = [];
70907
- }
70947
+ function findOpeningMarker(text) {
70948
+ const results = MARKER_PATTERNS.map(({ isBold, marker }) => {
70949
+ if (marker === '*' && text.startsWith('**'))
70950
+ return null;
70951
+ if (marker === '_' && text.startsWith('__'))
70952
+ return null;
70953
+ if (text.startsWith(marker) && text.length > marker.length) {
70954
+ return { isBold, marker, textAfter: text.slice(marker.length), textBefore: '' };
70955
+ }
70956
+ const idx = text.indexOf(marker);
70957
+ if (idx > 0 && !/\s/.test(text[idx - 1])) {
70958
+ if (marker === '*' && text.slice(idx).startsWith('**'))
70959
+ return null;
70960
+ if (marker === '_' && text.slice(idx).startsWith('__'))
70961
+ return null;
70962
+ const after = text.slice(idx + marker.length);
70963
+ if (after.length > 0) {
70964
+ return { isBold, marker, textAfter: after, textBefore: text.slice(0, idx) };
70908
70965
  }
70909
70966
  }
70910
- }
70911
- this.exit(token);
70912
- }
70913
- function emptyTaskListItemFromMarkdown() {
70914
- return {
70915
- exit: {
70916
- listItem: exitListItemWithEmptyTaskListItem,
70917
- },
70918
- };
70967
+ return null;
70968
+ });
70969
+ return results.find(r => r !== null) ?? null;
70919
70970
  }
70920
-
70921
- ;// ./lib/mdast-util/legacy-variable/index.ts
70922
-
70923
- const contextMap = new WeakMap();
70924
- function findlegacyVariableToken() {
70925
- // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
70926
- const events = this.tokenStack;
70927
- for (let i = events.length - 1; i >= 0; i -= 1) {
70928
- const token = events[i][0];
70929
- if (token.type === 'legacyVariable')
70930
- return token;
70971
+ /**
70972
+ * Finds the end/closing marker in a text node for multi-node emphasis.
70973
+ */
70974
+ function findEndMarker(text, marker) {
70975
+ const spacePattern = ` ${marker}`;
70976
+ const spaceIdx = text.indexOf(spacePattern);
70977
+ if (spaceIdx >= 0) {
70978
+ if (marker === '*' && text.slice(spaceIdx + 1).startsWith('**'))
70979
+ return null;
70980
+ if (marker === '_' && text.slice(spaceIdx + 1).startsWith('__'))
70981
+ return null;
70982
+ return {
70983
+ textAfter: text.slice(spaceIdx + spacePattern.length),
70984
+ textBefore: text.slice(0, spaceIdx),
70985
+ };
70931
70986
  }
70932
- return undefined;
70933
- }
70934
- function enterlegacyVariable(token) {
70935
- contextMap.set(token, { value: '' });
70936
- }
70937
- function exitlegacyVariableValue(token) {
70938
- const variableToken = findlegacyVariableToken.call(this);
70939
- if (!variableToken)
70940
- return;
70941
- const ctx = contextMap.get(variableToken);
70942
- // Build up the variable characters
70943
- if (ctx)
70944
- ctx.value += this.sliceSerialize(token);
70945
- }
70946
- function exitlegacyVariable(token) {
70947
- const ctx = contextMap.get(token);
70948
- const serialized = this.sliceSerialize(token);
70949
- const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
70950
- ? serialized.slice(2, -2)
70951
- : ctx?.value ?? '';
70952
- const nodePosition = {
70953
- start: {
70954
- offset: token.start.offset,
70955
- line: token.start.line,
70956
- column: token.start.column,
70957
- },
70958
- end: {
70959
- offset: token.end.offset,
70960
- line: token.end.line,
70961
- column: token.end.column,
70962
- },
70963
- };
70964
- if (variableName.startsWith('glossary:')) {
70965
- const term = variableName.slice('glossary:'.length).trim();
70966
- this.enter({
70967
- type: NodeTypes.glossary,
70968
- data: {
70969
- hName: 'Glossary',
70970
- hProperties: { term },
70971
- },
70972
- children: [{ type: 'text', value: term }],
70973
- position: nodePosition,
70974
- }, token);
70975
- this.exit(token);
70976
- contextMap.delete(token);
70977
- return;
70987
+ if (text.startsWith(marker)) {
70988
+ if (marker === '*' && text.startsWith('**'))
70989
+ return null;
70990
+ if (marker === '_' && text.startsWith('__'))
70991
+ return null;
70992
+ return {
70993
+ textAfter: text.slice(marker.length),
70994
+ textBefore: '',
70995
+ };
70978
70996
  }
70979
- this.enter({
70980
- type: NodeTypes.variable,
70981
- data: {
70982
- hName: 'Variable',
70983
- hProperties: { name: variableName.trim(), isLegacy: true },
70984
- },
70985
- value: `<<${variableName}>>`,
70986
- }, token);
70987
- this.exit(token);
70988
- contextMap.delete(token);
70989
- }
70990
- function legacyVariableFromMarkdown() {
70991
- return {
70992
- enter: {
70993
- legacyVariable: enterlegacyVariable,
70994
- },
70995
- exit: {
70996
- legacyVariableValue: exitlegacyVariableValue,
70997
- legacyVariable: exitlegacyVariable,
70998
- },
70999
- };
70997
+ return null;
71000
70998
  }
71001
-
71002
- ;// ./node_modules/micromark-util-symbol/lib/codes.js
71003
70999
  /**
71004
- * Character codes.
71005
- *
71006
- * This module is compiled away!
71007
- *
71008
- * micromark works based on character codes.
71009
- * This module contains constants for the ASCII block and the replacement
71010
- * character.
71011
- * A couple of them are handled in a special way, such as the line endings
71012
- * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
71013
- * tab) and its expansion based on what column it’s at (virtual space),
71014
- * and the end-of-file (eof) character.
71015
- * As values are preprocessed before handling them, the actual characters LF,
71016
- * CR, HT, and NUL (which is present as the replacement character), are
71017
- * guaranteed to not exist.
71018
- *
71019
- * Unicode basic latin block.
71000
+ * Scan children for an opening emphasis marker in a text node.
71020
71001
  */
71021
- const codes = /** @type {const} */ ({
71022
- carriageReturn: -5,
71023
- lineFeed: -4,
71024
- carriageReturnLineFeed: -3,
71025
- horizontalTab: -2,
71026
- virtualSpace: -1,
71027
- eof: null,
71028
- nul: 0,
71029
- soh: 1,
71030
- stx: 2,
71031
- etx: 3,
71032
- eot: 4,
71033
- enq: 5,
71034
- ack: 6,
71035
- bel: 7,
71036
- bs: 8,
71037
- ht: 9, // `\t`
71038
- lf: 10, // `\n`
71039
- vt: 11, // `\v`
71040
- ff: 12, // `\f`
71041
- cr: 13, // `\r`
71042
- so: 14,
71043
- si: 15,
71044
- dle: 16,
71045
- dc1: 17,
71046
- dc2: 18,
71047
- dc3: 19,
71048
- dc4: 20,
71049
- nak: 21,
71050
- syn: 22,
71051
- etb: 23,
71052
- can: 24,
71053
- em: 25,
71054
- sub: 26,
71055
- esc: 27,
71056
- fs: 28,
71057
- gs: 29,
71058
- rs: 30,
71059
- us: 31,
71060
- space: 32,
71061
- exclamationMark: 33, // `!`
71062
- quotationMark: 34, // `"`
71063
- numberSign: 35, // `#`
71064
- dollarSign: 36, // `$`
71065
- percentSign: 37, // `%`
71066
- ampersand: 38, // `&`
71067
- apostrophe: 39, // `'`
71068
- leftParenthesis: 40, // `(`
71069
- rightParenthesis: 41, // `)`
71070
- asterisk: 42, // `*`
71071
- plusSign: 43, // `+`
71072
- comma: 44, // `,`
71073
- dash: 45, // `-`
71074
- dot: 46, // `.`
71075
- slash: 47, // `/`
71076
- digit0: 48, // `0`
71077
- digit1: 49, // `1`
71078
- digit2: 50, // `2`
71079
- digit3: 51, // `3`
71080
- digit4: 52, // `4`
71081
- digit5: 53, // `5`
71082
- digit6: 54, // `6`
71083
- digit7: 55, // `7`
71084
- digit8: 56, // `8`
71085
- digit9: 57, // `9`
71086
- colon: 58, // `:`
71087
- semicolon: 59, // `;`
71088
- lessThan: 60, // `<`
71089
- equalsTo: 61, // `=`
71090
- greaterThan: 62, // `>`
71091
- questionMark: 63, // `?`
71092
- atSign: 64, // `@`
71093
- uppercaseA: 65, // `A`
71094
- uppercaseB: 66, // `B`
71095
- uppercaseC: 67, // `C`
71096
- uppercaseD: 68, // `D`
71097
- uppercaseE: 69, // `E`
71098
- uppercaseF: 70, // `F`
71099
- uppercaseG: 71, // `G`
71100
- uppercaseH: 72, // `H`
71101
- uppercaseI: 73, // `I`
71102
- uppercaseJ: 74, // `J`
71103
- uppercaseK: 75, // `K`
71104
- uppercaseL: 76, // `L`
71105
- uppercaseM: 77, // `M`
71106
- uppercaseN: 78, // `N`
71107
- uppercaseO: 79, // `O`
71108
- uppercaseP: 80, // `P`
71109
- uppercaseQ: 81, // `Q`
71110
- uppercaseR: 82, // `R`
71111
- uppercaseS: 83, // `S`
71112
- uppercaseT: 84, // `T`
71113
- uppercaseU: 85, // `U`
71114
- uppercaseV: 86, // `V`
71115
- uppercaseW: 87, // `W`
71116
- uppercaseX: 88, // `X`
71117
- uppercaseY: 89, // `Y`
71118
- uppercaseZ: 90, // `Z`
71119
- leftSquareBracket: 91, // `[`
71120
- backslash: 92, // `\`
71121
- rightSquareBracket: 93, // `]`
71122
- caret: 94, // `^`
71123
- underscore: 95, // `_`
71124
- graveAccent: 96, // `` ` ``
71125
- lowercaseA: 97, // `a`
71126
- lowercaseB: 98, // `b`
71127
- lowercaseC: 99, // `c`
71128
- lowercaseD: 100, // `d`
71129
- lowercaseE: 101, // `e`
71130
- lowercaseF: 102, // `f`
71131
- lowercaseG: 103, // `g`
71132
- lowercaseH: 104, // `h`
71133
- lowercaseI: 105, // `i`
71134
- lowercaseJ: 106, // `j`
71135
- lowercaseK: 107, // `k`
71136
- lowercaseL: 108, // `l`
71137
- lowercaseM: 109, // `m`
71138
- lowercaseN: 110, // `n`
71139
- lowercaseO: 111, // `o`
71140
- lowercaseP: 112, // `p`
71141
- lowercaseQ: 113, // `q`
71142
- lowercaseR: 114, // `r`
71143
- lowercaseS: 115, // `s`
71144
- lowercaseT: 116, // `t`
71145
- lowercaseU: 117, // `u`
71146
- lowercaseV: 118, // `v`
71147
- lowercaseW: 119, // `w`
71148
- lowercaseX: 120, // `x`
71149
- lowercaseY: 121, // `y`
71150
- lowercaseZ: 122, // `z`
71151
- leftCurlyBrace: 123, // `{`
71152
- verticalBar: 124, // `|`
71153
- rightCurlyBrace: 125, // `}`
71154
- tilde: 126, // `~`
71155
- del: 127,
71156
- // Unicode Specials block.
71157
- byteOrderMarker: 65_279,
71158
- // Unicode Specials block.
71159
- replacementCharacter: 65_533 // `�`
71160
- })
71161
-
71162
- ;// ./lib/micromark/legacy-variable/syntax.ts
71163
-
71164
-
71165
- function isAllowedValueChar(code) {
71166
- return (code !== null &&
71167
- code !== codes.lessThan &&
71168
- code !== codes.greaterThan &&
71169
- !markdownLineEnding(code));
71170
- }
71171
- const legacyVariableConstruct = {
71172
- name: 'legacyVariable',
71173
- tokenize,
71174
- };
71175
- function tokenize(effects, ok, nok) {
71176
- let hasValue = false;
71177
- const start = (code) => {
71178
- if (code !== codes.lessThan)
71179
- return nok(code);
71180
- effects.enter('legacyVariable');
71181
- effects.enter('legacyVariableMarkerStart');
71182
- effects.consume(code); // <
71183
- return open2;
71184
- };
71185
- const open2 = (code) => {
71186
- if (code !== codes.lessThan)
71187
- return nok(code);
71188
- effects.consume(code); // <<
71189
- effects.exit('legacyVariableMarkerStart');
71190
- effects.enter('legacyVariableValue');
71191
- return value;
71192
- };
71193
- const value = (code) => {
71194
- if (code === codes.greaterThan) {
71195
- if (!hasValue)
71196
- return nok(code);
71197
- effects.exit('legacyVariableValue');
71198
- effects.enter('legacyVariableMarkerEnd');
71199
- effects.consume(code); // >
71200
- return close2;
71002
+ function findOpeningInChildren(children) {
71003
+ let result = null;
71004
+ children.some((child, idx) => {
71005
+ if (child.type !== 'text')
71006
+ return false;
71007
+ const found = findOpeningMarker(child.value);
71008
+ if (found) {
71009
+ result = { idx, opening: found };
71010
+ return true;
71201
71011
  }
71202
- if (!isAllowedValueChar(code))
71203
- return nok(code);
71204
- hasValue = true;
71205
- effects.consume(code);
71206
- return value;
71207
- };
71208
- const close2 = (code) => {
71209
- if (code !== codes.greaterThan)
71210
- return nok(code);
71211
- effects.consume(code); // >>
71212
- effects.exit('legacyVariableMarkerEnd');
71213
- effects.exit('legacyVariable');
71214
- return ok;
71215
- };
71216
- return start;
71012
+ return false;
71013
+ });
71014
+ return result;
71217
71015
  }
71218
- function legacyVariable() {
71219
- return {
71220
- text: { [codes.lessThan]: legacyVariableConstruct },
71221
- };
71016
+ /**
71017
+ * Scan children (after openingIdx) for a closing emphasis marker.
71018
+ */
71019
+ function findClosingInChildren(children, openingIdx, marker) {
71020
+ let result = null;
71021
+ children.slice(openingIdx + 1).some((child, relativeIdx) => {
71022
+ if (child.type !== 'text')
71023
+ return false;
71024
+ const found = findEndMarker(child.value, marker);
71025
+ if (found) {
71026
+ result = { closingIdx: openingIdx + 1 + relativeIdx, closing: found };
71027
+ return true;
71028
+ }
71029
+ return false;
71030
+ });
71031
+ return result;
71222
71032
  }
71223
-
71224
- ;// ./lib/micromark/legacy-variable/index.ts
71225
71033
  /**
71226
- * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
71034
+ * Build the replacement nodes for a matched emphasis pair.
71227
71035
  */
71228
-
71229
-
71230
- ;// ./processor/transform/mdxish/constants.ts
71036
+ function buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx }) {
71037
+ const newNodes = [];
71038
+ if (opening.textBefore) {
71039
+ newNodes.push({ type: 'text', value: `${opening.textBefore} ` });
71040
+ }
71041
+ const emphasisChildren = [];
71042
+ const openingText = opening.textAfter.replace(/^\s+/, '');
71043
+ if (openingText) {
71044
+ emphasisChildren.push({ type: 'text', value: openingText });
71045
+ }
71046
+ container.children.slice(openingIdx + 1, closingIdx).forEach(child => {
71047
+ emphasisChildren.push(child);
71048
+ });
71049
+ const closingText = closing.textBefore.replace(/\s+$/, '');
71050
+ if (closingText) {
71051
+ emphasisChildren.push({ type: 'text', value: closingText });
71052
+ }
71053
+ if (emphasisChildren.length > 0) {
71054
+ const emphasisNode = opening.isBold
71055
+ ? { type: 'strong', children: emphasisChildren }
71056
+ : { type: 'emphasis', children: emphasisChildren };
71057
+ newNodes.push(emphasisNode);
71058
+ }
71059
+ if (closing.textAfter) {
71060
+ newNodes.push({ type: 'text', value: closing.textAfter });
71061
+ }
71062
+ return newNodes;
71063
+ }
71231
71064
  /**
71232
- * Inline component tags handled by mdxish-inline-components.ts.
71233
- * Also excluded from block-level handling in mdxish-component-blocks.ts.
71065
+ * Find and transform one multi-node emphasis pair in the container.
71066
+ * Returns true if a pair was found and transformed, false otherwise.
71234
71067
  */
71235
- const INLINE_COMPONENT_TAGS = new Set(['Anchor']);
71236
-
71237
- ;// ./processor/transform/mdxish/mdxish-component-blocks.ts
71238
-
71239
-
71240
-
71241
-
71242
-
71243
-
71244
-
71245
- const pascalCaseTagPattern = /^<([A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>([\s\S]*)?$/;
71246
- const tagAttributePattern = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
71247
- /**
71248
- * Maximum number of siblings to scan forward when looking for a closing tag
71249
- * to avoid scanning too far and degrading performance
71250
- */
71251
- const MAX_LOOKAHEAD = 30;
71252
- /**
71253
- * Tags that have dedicated transformers and should NOT be handled by this plugin.
71254
- * These components either have special parsing requirements that the generic component
71255
- * block transformer cannot handle correctly, or are inline components that we don't
71256
- * want to convert to mdxJsxFlowElement which is a block level element.
71257
- */
71258
- const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table', 'Glossary', ...INLINE_COMPONENT_TAGS]);
71259
- const inlineMdProcessor = unified()
71260
- .data('micromarkExtensions', [legacyVariable()])
71261
- .data('fromMarkdownExtensions', [legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown()])
71262
- .use(remarkParse)
71263
- .use(remarkGfm);
71264
- const isClosingTag = (value, tag) => value.trim() === `</${tag}>`;
71265
- /**
71266
- * Parse markdown content into mdast children nodes.
71267
- */
71268
- const parseMdChildren = (value) => {
71269
- const parsed = inlineMdProcessor.parse(value);
71270
- return parsed.children || [];
71271
- };
71272
- /**
71273
- * Convert raw attribute string into mdxJsxAttribute entries.
71274
- * Handles both key-value attributes (theme="info") and boolean attributes (empty).
71275
- */
71276
- const parseAttributes = (raw) => {
71277
- const attributes = [];
71278
- const attrString = raw.trim();
71279
- if (!attrString)
71280
- return attributes;
71281
- tagAttributePattern.lastIndex = 0;
71282
- let match = tagAttributePattern.exec(attrString);
71283
- while (match !== null) {
71284
- const [, attrName, attrValue] = match;
71285
- const value = attrValue ? attrValue.replace(/^['"]|['"]$/g, '') : null;
71286
- attributes.push({ type: 'mdxJsxAttribute', name: attrName, value });
71287
- match = tagAttributePattern.exec(attrString);
71288
- }
71289
- return attributes;
71290
- };
71291
- /**
71292
- * Parse an HTML tag string into structured data.
71293
- */
71294
- const parseTag = (value) => {
71295
- const match = value.match(pascalCaseTagPattern);
71296
- if (!match)
71297
- return null;
71298
- const [, tag, attrString = '', selfClosing = '', contentAfterTag = ''] = match;
71299
- return {
71300
- tag,
71301
- attributes: parseAttributes(attrString),
71302
- selfClosing: !!selfClosing,
71303
- contentAfterTag,
71304
- };
71305
- };
71306
- /**
71307
- * Parse substring content of a node and update the parent's children to include the new nodes.
71308
- */
71309
- const parseSibling = (stack, parent, index, sibling) => {
71310
- const siblingNodes = parseMdChildren(sibling);
71311
- // The new sibling nodes might contain new components to be processed
71312
- if (siblingNodes.length > 0) {
71313
- parent.children.splice(index + 1, 0, ...siblingNodes);
71314
- stack.push(parent);
71315
- }
71316
- };
71317
- /**
71318
- * Create an MdxJsxFlowElement node from component data.
71319
- */
71320
- const createComponentNode = ({ tag, attributes, children, startPosition, endPosition }) => ({
71321
- type: 'mdxJsxFlowElement',
71322
- name: tag,
71323
- attributes,
71324
- children,
71325
- position: {
71326
- start: startPosition?.start,
71327
- end: endPosition?.end ?? startPosition?.end,
71328
- },
71329
- });
71330
- /**
71331
- * Remove a closing tag from a paragraph's children and return the updated paragraph.
71332
- */
71333
- const stripClosingTagFromParagraph = (node, tag) => {
71334
- if (!Array.isArray(node.children))
71335
- return { paragraph: node, found: false };
71336
- const children = [...node.children];
71337
- const closingIndex = children.findIndex(child => child.type === 'html' && isClosingTag(child.value || '', tag));
71338
- if (closingIndex === -1)
71339
- return { paragraph: node, found: false };
71340
- children.splice(closingIndex, 1);
71341
- return { paragraph: { ...node, children }, found: true };
71342
- };
71068
+ function processOneEmphasisPair(container) {
71069
+ const openingResult = findOpeningInChildren(container.children);
71070
+ if (!openingResult)
71071
+ return false;
71072
+ const { idx: openingIdx, opening } = openingResult;
71073
+ const closingResult = findClosingInChildren(container.children, openingIdx, opening.marker);
71074
+ if (!closingResult)
71075
+ return false;
71076
+ const { closingIdx, closing } = closingResult;
71077
+ const newNodes = buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx });
71078
+ const deleteCount = closingIdx - openingIdx + 1;
71079
+ container.children.splice(openingIdx, deleteCount, ...newNodes);
71080
+ return true;
71081
+ }
71343
71082
  /**
71344
- * Scan forward through siblings to find a closing tag.
71345
- * Handles:
71346
- * - Exact match HTML siblings (e.g., `</Tag>`)
71347
- * - HTML siblings with embedded closing tag (e.g., `...\n</Tag>`)
71348
- * - Paragraph siblings containing the closing tag as a child
71349
- *
71350
- * Returns null if not found within MAX_LOOKAHEAD siblings
71083
+ * Handle malformed emphasis that spans multiple AST nodes.
71084
+ * E.g., "**bold [link](url)**" where markers are in different text nodes.
71351
71085
  */
71352
- const scanForClosingTag = (parent, startIndex, tag) => {
71353
- const closingTagStr = `</${tag}>`;
71354
- const maxIndex = Math.min(startIndex + MAX_LOOKAHEAD, parent.children.length);
71355
- let i = startIndex + 1;
71356
- for (; i < maxIndex; i += 1) {
71357
- const sibling = parent.children[i];
71358
- // Check HTML siblings
71359
- if (sibling.type === 'html') {
71360
- const siblingValue = sibling.value || '';
71361
- // Exact match (standalone closing tag)
71362
- if (isClosingTag(siblingValue, tag)) {
71363
- return { closingIndex: i, extraClosingChildren: [] };
71364
- }
71365
- // Embedded closing tag (closing tag within HTML block content)
71366
- if (siblingValue.includes(closingTagStr)) {
71367
- const closeTagPos = siblingValue.indexOf(closingTagStr);
71368
- const contentBeforeClose = siblingValue.substring(0, closeTagPos).trim();
71369
- const contentAfterClose = siblingValue.substring(closeTagPos + closingTagStr.length).trim();
71370
- const extraChildren = contentBeforeClose
71371
- ? parseMdChildren(contentBeforeClose)
71372
- : [];
71373
- return { closingIndex: i, extraClosingChildren: extraChildren, contentAfterClose: contentAfterClose || undefined };
71374
- }
71375
- }
71376
- // Check paragraph siblings
71377
- if (sibling.type === 'paragraph') {
71378
- const { paragraph, found } = stripClosingTagFromParagraph(sibling, tag);
71379
- if (found) {
71380
- return { closingIndex: i, extraClosingChildren: [], strippedParagraph: paragraph };
71381
- }
71086
+ function visitMultiNodeEmphasis(tree) {
71087
+ const containerTypes = ['paragraph', 'heading', 'tableCell', 'listItem', 'blockquote'];
71088
+ visit(tree, node => {
71089
+ if (!containerTypes.includes(node.type))
71090
+ return;
71091
+ if (!('children' in node) || !Array.isArray(node.children))
71092
+ return;
71093
+ const container = node;
71094
+ let foundPair = true;
71095
+ while (foundPair) {
71096
+ foundPair = processOneEmphasisPair(container);
71382
71097
  }
71383
- }
71384
- if (i < parent.children.length) {
71385
- // eslint-disable-next-line no-console
71386
- console.warn(`Closing tag </${tag}> not found within ${MAX_LOOKAHEAD} siblings, stopping scan`);
71387
- }
71388
- return null;
71389
- };
71390
- const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
71391
- parent.children.splice(index, 1, mdxNode);
71392
- };
71098
+ });
71099
+ }
71393
71100
  /**
71394
- * Transform PascalCase HTML nodes into mdxJsxFlowElement nodes.
71395
- *
71396
- * Remark parses unknown/custom component tags as raw HTML nodes.
71397
- * These are the custom readme MDX syntax for components.
71398
- * This transformer identifies these patterns and converts them to proper MDX JSX elements so they
71399
- * can be accurately recognized and rendered later with their component definition code.
71400
- * Though for some tags, we need to handle them specially
71401
- *
71402
- * ## Supported HTML Structures
71403
- *
71404
- * ### 1. Self-closing tags
71405
- * ```
71406
- * <Component />
71407
- * ```
71408
- * Parsed as: `html: "<Component />"`
71409
- *
71410
- * ### 2. Self-contained blocks (entire component in single HTML node)
71411
- * ```
71412
- * <Button>Click me</Button>
71413
- * ```
71414
- * ```
71415
- * <Component>
71416
- * <h2>Title</h2>
71417
- * <p>Content</p>
71418
- * </Component>
71419
- * ```
71420
- * Parsed as: `html: "<Component>\n <h2>Title</h2>\n <p>Content</p>\n</Component>"`
71421
- * The opening tag, content, and closing tag are all captured in one HTML node.
71422
- *
71423
- * ### 3. Multi-sibling components (closing tag in a following sibling)
71424
- * Handles various structures where the closing tag is in a later sibling, such as:
71425
- *
71426
- * #### 3a. Block components (closing tag in sibling paragraph)
71427
- * ```
71428
- * <Callout>
71429
- * Some **markdown** content
71430
- * </Callout>
71431
- * ```
71432
- *
71433
- * #### 3b. Multi-paragraph components (closing tag several siblings away)
71434
- * ```
71435
- * <Callout>
71436
- *
71437
- * First paragraph
71438
- *
71439
- * Second paragraph
71440
- * </Callout>
71441
- * ```
71101
+ * A remark plugin that normalizes malformed bold and italic markers in text nodes.
71102
+ * Detects patterns like `** bold**`, `Hello** Wrong Bold**`, `__ bold__`, `Hello__ Wrong Bold__`,
71103
+ * `* italic*`, `Hello* Wrong Italic*`, `_ italic_`, or `Hello_ Wrong Italic_`
71104
+ * and converts them to proper strong/emphasis nodes, matching the behavior of the legacy rdmd engine.
71442
71105
  *
71443
- * #### 3c. Nested components split by blank lines (closing tag embedded in HTML sibling)
71444
- * ```
71445
- * <Outer>
71446
- * <Inner>content</Inner>
71106
+ * Supports both asterisk (`**bold**`, `*italic*`) and underscore (`__bold__`, `_italic_`) syntax.
71107
+ * Also supports snake_case content like `** some_snake_case**`.
71447
71108
  *
71448
- * <Inner>content</Inner>
71449
- * </Outer>
71450
- * ```
71109
+ * This runs after remark-parse, which (in v11+) is strict and doesn't parse
71110
+ * malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
71451
71111
  */
71452
- const mdxishComponentBlocks = () => tree => {
71453
- const stack = [tree];
71454
- const processChildNode = (parent, index) => {
71455
- const node = parent.children[index];
71456
- if (!node)
71457
- return;
71458
- if ('children' in node && Array.isArray(node.children)) {
71459
- stack.push(node);
71112
+ const normalizeEmphasisAST = () => (tree) => {
71113
+ visit(tree, 'text', function visitor(node, index, parent) {
71114
+ if (index === undefined || !parent)
71115
+ return undefined;
71116
+ // Skip if inside code blocks or inline code
71117
+ if (parent.type === 'inlineCode' || parent.type === 'code') {
71118
+ return undefined;
71460
71119
  }
71461
- // Only visit HTML nodes with an actual html tag,
71462
- // which means a potential unparsed MDX component
71463
- const value = node.value;
71464
- if (node.type !== 'html' || typeof value !== 'string')
71465
- return;
71466
- const parsed = parseTag(value.trim());
71467
- if (!parsed)
71468
- return;
71469
- const { tag, attributes, selfClosing, contentAfterTag = '' } = parsed;
71470
- // Skip tags that have dedicated transformers
71471
- if (EXCLUDED_TAGS.has(tag))
71472
- return;
71473
- const closingTagStr = `</${tag}>`;
71474
- // Case 1: Self-closing tag
71475
- if (selfClosing) {
71476
- const componentNode = createComponentNode({
71477
- tag,
71478
- attributes,
71479
- children: [],
71480
- startPosition: node.position,
71481
- });
71482
- substituteNodeWithMdxNode(parent, index, componentNode);
71483
- // Check and parse if there's relevant content after the current closing tag
71484
- const remainingContent = contentAfterTag.trim();
71485
- if (remainingContent) {
71486
- parseSibling(stack, parent, index, remainingContent);
71120
+ const text = node.value;
71121
+ const allMatches = [];
71122
+ [...text.matchAll(asteriskBoldRegex)].forEach(match => {
71123
+ allMatches.push({ isBold: true, marker: '**', match });
71124
+ });
71125
+ [...text.matchAll(underscoreBoldRegex)].forEach(match => {
71126
+ allMatches.push({ isBold: true, marker: '__', match });
71127
+ });
71128
+ [...text.matchAll(asteriskItalicRegex)].forEach(match => {
71129
+ allMatches.push({ isBold: false, marker: '*', match });
71130
+ });
71131
+ [...text.matchAll(underscoreItalicRegex)].forEach(match => {
71132
+ allMatches.push({ isBold: false, marker: '_', match });
71133
+ });
71134
+ [...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
71135
+ allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
71136
+ });
71137
+ [...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
71138
+ allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
71139
+ });
71140
+ [...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
71141
+ allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
71142
+ });
71143
+ [...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
71144
+ allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
71145
+ });
71146
+ if (allMatches.length === 0)
71147
+ return undefined;
71148
+ allMatches.sort((a, b) => (a.match.index ?? 0) - (b.match.index ?? 0));
71149
+ const filteredMatches = [];
71150
+ let lastEnd = 0;
71151
+ allMatches.forEach(info => {
71152
+ const start = info.match.index ?? 0;
71153
+ const end = start + info.match[0].length;
71154
+ if (start >= lastEnd) {
71155
+ filteredMatches.push(info);
71156
+ lastEnd = end;
71487
71157
  }
71488
- return;
71489
- }
71490
- // Case 2: Self-contained block (closing tag in content)
71491
- if (contentAfterTag.includes(closingTagStr)) {
71492
- // Find the first closing tag
71493
- const closingTagIndex = contentAfterTag.indexOf(closingTagStr);
71494
- const componentInnerContent = contentAfterTag.substring(0, closingTagIndex).trim();
71495
- const contentAfterClose = contentAfterTag.substring(closingTagIndex + closingTagStr.length).trim();
71496
- const componentNode = createComponentNode({
71497
- tag,
71498
- attributes,
71499
- children: componentInnerContent ? parseMdChildren(componentInnerContent) : [],
71500
- startPosition: node.position,
71501
- });
71502
- substituteNodeWithMdxNode(parent, index, componentNode);
71503
- // After the closing tag, there might be more content to be processed
71504
- if (contentAfterClose) {
71505
- parseSibling(stack, parent, index, contentAfterClose);
71158
+ });
71159
+ if (filteredMatches.length === 0)
71160
+ return undefined;
71161
+ const parts = [];
71162
+ let lastIndex = 0;
71163
+ filteredMatches.forEach(({ isBold, isIntraword, marker, match }) => {
71164
+ const matchIndex = match.index ?? 0;
71165
+ const fullMatch = match[0];
71166
+ if (isIntraword) {
71167
+ // handles cases like hello_world_ where we only want to italicize 'world'
71168
+ const charBefore = match[1] || ''; // e.g., "l" in "hello_world_"
71169
+ const content = match[2]; // e.g., "world"
71170
+ const combinedBefore = text.slice(lastIndex, matchIndex) + charBefore;
71171
+ if (combinedBefore) {
71172
+ parts.push({ type: 'text', value: combinedBefore });
71173
+ }
71174
+ if (isBold) {
71175
+ parts.push({
71176
+ type: 'strong',
71177
+ children: [{ type: 'text', value: content }],
71178
+ });
71179
+ }
71180
+ else {
71181
+ parts.push({
71182
+ type: 'emphasis',
71183
+ children: [{ type: 'text', value: content }],
71184
+ });
71185
+ }
71186
+ lastIndex = matchIndex + fullMatch.length;
71187
+ return;
71506
71188
  }
71507
- else if (componentNode.children.length > 0) {
71508
- // The content inside the component block might contain new components to be processed
71509
- stack.push(componentNode);
71189
+ if (matchIndex > lastIndex) {
71190
+ const beforeText = text.slice(lastIndex, matchIndex);
71191
+ if (beforeText) {
71192
+ parts.push({ type: 'text', value: beforeText });
71193
+ }
71510
71194
  }
71511
- return;
71512
- }
71513
- // Case 3: Multi-sibling component (closing tag in a following sibling)
71514
- // Scans forward through siblings to find closing tag in HTML or paragraph nodes
71515
- const scanResult = scanForClosingTag(parent, index, tag);
71516
- if (!scanResult)
71517
- return;
71518
- const { closingIndex, extraClosingChildren, strippedParagraph, contentAfterClose: remainingAfterClose } = scanResult;
71519
- const extraChildren = contentAfterTag ? parseMdChildren(contentAfterTag.trimStart()) : [];
71520
- // Collect all intermediate siblings between opening tag and closing tag
71521
- const intermediateChildren = parent.children.slice(index + 1, closingIndex);
71522
- // For paragraph siblings, include the full paragraph (with closing tag stripped)
71523
- // For HTML siblings, include any content parsed from before the closing tag
71524
- const closingChildren = strippedParagraph
71525
- ? (strippedParagraph.children.length > 0 ? [strippedParagraph] : [])
71526
- : extraClosingChildren;
71527
- const componentNode = createComponentNode({
71528
- tag,
71529
- attributes,
71530
- children: [...extraChildren, ...intermediateChildren, ...closingChildren],
71531
- startPosition: node.position,
71532
- endPosition: parent.children[closingIndex]?.position,
71195
+ const wordBefore = match[1]; // e.g., "Hello" in "Hello** Wrong Bold**"
71196
+ const contentWithSpaceAfter = match[3]; // Content when there's a space after opening markers
71197
+ const trailingSpace1 = match[4] || ''; // Space before closing markers (for "** text **" pattern)
71198
+ const contentWithSpaceBefore = match[5]; // Content when there's only a space before closing markers
71199
+ const trailingSpace2 = match[6] || ''; // Space before closing markers (for "**text **" pattern)
71200
+ const trailingSpace = trailingSpace1 || trailingSpace2; // Combined trailing space
71201
+ const content = (contentWithSpaceAfter || contentWithSpaceBefore || '').trim();
71202
+ const afterChar = match[7]; // Character after closing markers (if any)
71203
+ const markerPos = fullMatch.indexOf(marker);
71204
+ const spacesBeforeMarkers = wordBefore
71205
+ ? fullMatch.slice(wordBefore.length, markerPos)
71206
+ : fullMatch.slice(0, markerPos);
71207
+ const shouldAddSpace = !!contentWithSpaceAfter && !!wordBefore && !spacesBeforeMarkers;
71208
+ if (wordBefore) {
71209
+ const spacing = spacesBeforeMarkers + (shouldAddSpace ? ' ' : '');
71210
+ parts.push({ type: 'text', value: wordBefore + spacing });
71211
+ }
71212
+ else if (spacesBeforeMarkers) {
71213
+ parts.push({ type: 'text', value: spacesBeforeMarkers });
71214
+ }
71215
+ if (content) {
71216
+ if (isBold) {
71217
+ parts.push({
71218
+ type: 'strong',
71219
+ children: [{ type: 'text', value: content }],
71220
+ });
71221
+ }
71222
+ else {
71223
+ parts.push({
71224
+ type: 'emphasis',
71225
+ children: [{ type: 'text', value: content }],
71226
+ });
71227
+ }
71228
+ }
71229
+ if (afterChar) {
71230
+ const prefix = trailingSpace ? ' ' : '';
71231
+ parts.push({ type: 'text', value: prefix + afterChar });
71232
+ }
71233
+ lastIndex = matchIndex + fullMatch.length;
71533
71234
  });
71534
- // Remove all nodes from opening tag to closing tag (inclusive) and replace with component node
71535
- parent.children.splice(index, closingIndex - index + 1, componentNode);
71536
- // Since we might be merging sibling nodes together and combining content,
71537
- // there might be new components to process
71538
- if (componentNode.children.length > 0) {
71539
- stack.push(componentNode);
71540
- }
71541
- // If the closing tag sibling had content after it (e.g., another component opening tag),
71542
- // re-insert it as a sibling so it can be processed in subsequent iterations
71543
- if (remainingAfterClose) {
71544
- parseSibling(stack, parent, index, remainingAfterClose);
71235
+ if (lastIndex < text.length) {
71236
+ const remainingText = text.slice(lastIndex);
71237
+ if (remainingText) {
71238
+ parts.push({ type: 'text', value: remainingText });
71239
+ }
71545
71240
  }
71546
- };
71547
- // Process the nodes with the components depth-first to maintain the correct order of the nodes
71548
- while (stack.length) {
71549
- const parent = stack.pop();
71550
- if (parent?.children) {
71551
- parent.children.forEach((_child, index) => {
71552
- processChildNode(parent, index);
71553
- });
71241
+ if (parts.length > 0) {
71242
+ parent.children.splice(index, 1, ...parts);
71243
+ return [SKIP, index + parts.length];
71554
71244
  }
71555
- }
71245
+ return undefined;
71246
+ });
71247
+ // Handle malformed emphasis spanning multiple nodes (e.g., **text [link](url) **)
71248
+ visitMultiNodeEmphasis(tree);
71556
71249
  return tree;
71557
71250
  };
71558
- /* harmony default export */ const mdxish_component_blocks = (mdxishComponentBlocks);
71251
+ /* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
71559
71252
 
71560
71253
  ;// ./processor/transform/mdxish/mdxish-tables.ts
71561
71254
 
@@ -71566,14 +71259,22 @@ const mdxishComponentBlocks = () => tree => {
71566
71259
 
71567
71260
 
71568
71261
 
71262
+
71263
+
71264
+
71265
+
71569
71266
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
71570
71267
  const tableTypes = {
71571
71268
  tr: 'tableRow',
71572
71269
  th: 'tableCell',
71573
71270
  td: 'tableCell',
71574
71271
  };
71575
- const mdCellProcessor = unified().use(remarkParse).use(remarkGfm);
71576
- const tableNodeProcessor = unified().use(remarkParse).use(remarkMdx).use(mdxish_component_blocks);
71272
+ const tableNodeProcessor = unified()
71273
+ .use(remarkParse)
71274
+ .use(remarkMdx)
71275
+ .use(normalize_malformed_md_syntax)
71276
+ .use([callouts, gemoji_, code_tabs])
71277
+ .use(remarkGfm);
71577
71278
  /**
71578
71279
  * Check if children are only text nodes that might contain markdown
71579
71280
  */
@@ -71603,14 +71304,14 @@ const extractTextFromChildren = (children) => {
71603
71304
  .join('');
71604
71305
  };
71605
71306
  /**
71606
- * Parse markdown text into MDAST nodes
71307
+ * Returns true if any node in the array is block-level (non-phrasing) content.
71607
71308
  */
71608
- const parseMarkdown = (text) => {
71609
- const tree = mdCellProcessor.runSync(mdCellProcessor.parse(text));
71610
- return (tree.children || []);
71309
+ const hasFlowContent = (nodes) => {
71310
+ return nodes.some(node => !phrasing(node) && node.type !== 'paragraph');
71611
71311
  };
71612
71312
  /**
71613
- * Process a Table node (either MDX JSX element or parsed from HTML) and convert to markdown table
71313
+ * Process a Table node: re-parse text-only cell content, then output as
71314
+ * a markdown table (phrasing-only) or keep as JSX <Table> (has flow content).
71614
71315
  */
71615
71316
  const processTableNode = (node, index, parent) => {
71616
71317
  if (node.name !== 'Table')
@@ -71618,54 +71319,88 @@ const processTableNode = (node, index, parent) => {
71618
71319
  const { position } = node;
71619
71320
  const { align: alignAttr } = getAttrs(node);
71620
71321
  const align = Array.isArray(alignAttr) ? alignAttr : null;
71621
- const children = [];
71622
- // Process rows from thead and tbody
71623
- // The structure is: Table -> thead/tbody -> tr -> td/th
71624
- const processRow = (row) => {
71625
- const rowChildren = [];
71626
- visit(row, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
71627
- let parsedChildren = cellChildren;
71628
- // If cell contains only text nodes, try to re-parse as markdown
71629
- if (isTextOnly(cellChildren)) {
71630
- const textContent = extractTextFromChildren(cellChildren);
71631
- if (textContent.trim()) {
71632
- try {
71633
- const parsed = parseMarkdown(textContent);
71634
- // If parsing produced nodes, use them; otherwise keep original
71635
- if (parsed.length > 0) {
71636
- // Flatten paragraphs if they contain only phrasing content
71637
- parsedChildren = parsed.flatMap(parsedNode => {
71638
- if (parsedNode.type === 'paragraph' && 'children' in parsedNode && parsedNode.children) {
71639
- return parsedNode.children;
71640
- }
71641
- return [parsedNode];
71642
- });
71643
- }
71644
- }
71645
- catch {
71646
- // If parsing fails, keep original children
71647
- }
71322
+ let tableHasFlowContent = false;
71323
+ // Re-parse text-only cells through markdown and detect flow content
71324
+ visit(node, isTableCell, (cell) => {
71325
+ if (!isTextOnly(cell.children))
71326
+ return;
71327
+ const textContent = extractTextFromChildren(cell.children);
71328
+ if (!textContent.trim())
71329
+ return;
71330
+ // Since now we are using remarkMdx, which can fail and error, we need to
71331
+ // gate this behind a try/catch to ensure that malformed syntaxes do not
71332
+ // crash the page
71333
+ try {
71334
+ const parsed = tableNodeProcessor.runSync(tableNodeProcessor.parse(textContent));
71335
+ if (parsed.children.length > 0) {
71336
+ cell.children = parsed.children;
71337
+ if (hasFlowContent(parsed.children)) {
71338
+ tableHasFlowContent = true;
71648
71339
  }
71649
71340
  }
71650
- rowChildren.push({
71651
- type: tableTypes[name],
71652
- children: parsedChildren,
71653
- position: cellPosition,
71654
- });
71655
- });
71656
- children.push({
71657
- type: tableTypes[row.name],
71658
- children: rowChildren,
71659
- position: row.position,
71341
+ }
71342
+ catch {
71343
+ // If parsing fails, keep original children
71344
+ }
71345
+ });
71346
+ // mdast's table node always treats the first tableRow as <thead>, so we can't
71347
+ // represent a header-less table in mdast without the first body row getting
71348
+ // promoted. Keep as JSX instead so remarkRehype renders it correctly
71349
+ let hasThead = false;
71350
+ visit(node, isMDXElement, (child) => {
71351
+ if (child.name === 'thead')
71352
+ hasThead = true;
71353
+ });
71354
+ if (tableHasFlowContent || !hasThead) {
71355
+ // remarkMdx wraps inline elements in paragraph nodes (e.g. <td> on the
71356
+ // same line as content becomes mdxJsxTextElement inside a paragraph).
71357
+ // Unwrap these so <td>/<th> sit directly under <tr>, and strip
71358
+ // whitespace-only text nodes to avoid rendering empty <p>/<br>.
71359
+ const cleanChildren = (children) => children
71360
+ .flatMap(child => {
71361
+ if (child.type === 'paragraph' && 'children' in child && Array.isArray(child.children)) {
71362
+ return child.children;
71363
+ }
71364
+ return [child];
71365
+ })
71366
+ .filter(child => !(child.type === 'text' && 'value' in child && typeof child.value === 'string' && !child.value.trim()));
71367
+ visit(node, isMDXElement, (el) => {
71368
+ if ('children' in el && Array.isArray(el.children)) {
71369
+ el.children = cleanChildren(el.children);
71370
+ }
71660
71371
  });
71661
- };
71662
- // Visit thead and tbody, then find tr elements within them
71372
+ parent.children[index] = {
71373
+ ...node,
71374
+ position,
71375
+ };
71376
+ return;
71377
+ }
71378
+ // All cells are phrasing-only — convert to markdown table
71379
+ const children = [];
71663
71380
  visit(node, isMDXElement, (child) => {
71664
71381
  if (child.name === 'thead' || child.name === 'tbody') {
71665
71382
  visit(child, isMDXElement, (row) => {
71666
- if (row.name === 'tr' && row.type === 'mdxJsxFlowElement') {
71667
- processRow(row);
71668
- }
71383
+ if (row.name !== 'tr')
71384
+ return;
71385
+ const rowChildren = [];
71386
+ visit(row, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
71387
+ const parsedChildren = cellChildren.flatMap(parsedNode => {
71388
+ if (parsedNode.type === 'paragraph' && 'children' in parsedNode && parsedNode.children) {
71389
+ return parsedNode.children;
71390
+ }
71391
+ return [parsedNode];
71392
+ });
71393
+ rowChildren.push({
71394
+ type: tableTypes[name],
71395
+ children: parsedChildren,
71396
+ position: cellPosition,
71397
+ });
71398
+ });
71399
+ children.push({
71400
+ type: 'tableRow',
71401
+ children: rowChildren,
71402
+ position: row.position,
71403
+ });
71669
71404
  });
71670
71405
  }
71671
71406
  });
@@ -71685,54 +71420,35 @@ const processTableNode = (node, index, parent) => {
71685
71420
  /**
71686
71421
  * Converts JSX Table elements to markdown table nodes and re-parses markdown in cells.
71687
71422
  *
71688
- * Since mdxish doesn't use remarkMdx, we manually parse cell contents through
71689
- * remarkParse and remarkGfm to convert markdown to MDAST nodes.
71423
+ * The jsxTable micromark tokenizer captures `<Table>...</Table>` as a single html node,
71424
+ * preventing CommonMark HTML block type 6 from fragmenting it at blank lines. This
71425
+ * transformer then re-parses the html node with remarkMdx to produce proper JSX AST nodes
71426
+ * and converts them to MDAST table/tableRow/tableCell nodes.
71427
+ *
71428
+ * When cell content contains block-level nodes (callouts, code blocks, etc.), the table
71429
+ * is kept as a JSX <Table> element so that remarkRehype can properly handle the flow content.
71690
71430
  */
71691
71431
  const mdxishTables = () => tree => {
71692
- // First, handle MDX JSX elements (already converted by mdxishComponentBlocks)
71693
- visit(tree, isMDXElement, (node, index, parent) => {
71694
- if (node.name === 'Table') {
71695
- processTableNode(node, index, parent);
71696
- return SKIP;
71697
- }
71698
- });
71699
- // Also handle HTML and raw nodes that contain Table tags (in case mdxishComponentBlocks didn't convert them)
71700
- // This happens when the entire <Table>...</Table> block is in a single HTML node, which mdxishComponentBlocks
71701
- // doesn't handle (it only handles split nodes: opening tag, content paragraph, closing tag)
71702
- const handleTableInNode = (node, index, parent) => {
71432
+ visit(tree, 'html', (_node, index, parent) => {
71433
+ const node = _node;
71703
71434
  if (typeof index !== 'number' || !parent || !('children' in parent))
71704
71435
  return;
71705
- if (typeof node.value !== 'string')
71706
- return;
71707
- if (!node.value.includes('<Table') || !node.value.includes('</Table>'))
71436
+ if (!node.value.startsWith('<Table'))
71708
71437
  return;
71709
71438
  try {
71710
- // Parse the HTML content with remarkMdx and mdxishComponentBlocks to convert it to MDX JSX elements
71711
- // This creates a proper AST that we can then process
71712
71439
  const parsed = tableNodeProcessor.runSync(tableNodeProcessor.parse(node.value));
71713
- // Find the Table element in the parsed result and process it
71714
71440
  visit(parsed, isMDXElement, (tableNode) => {
71715
71441
  if (tableNode.name === 'Table') {
71716
- // Process the table and replace the HTML node with a markdown table node
71717
71442
  processTableNode(tableNode, index, parent);
71443
+ // Stop after the outermost Table so nested Tables don't overwrite parent.children[index]
71444
+ // we let it get handled naturally
71445
+ return EXIT;
71718
71446
  }
71719
71447
  });
71720
71448
  }
71721
71449
  catch {
71722
71450
  // If parsing fails, leave the node as-is
71723
71451
  }
71724
- };
71725
- // Handle HTML nodes (created by remark-parse for HTML blocks)
71726
- visit(tree, 'html', (node, index, parent) => {
71727
- if (typeof index === 'number' && parent && 'children' in parent) {
71728
- handleTableInNode(node, index, parent);
71729
- }
71730
- });
71731
- // Handle raw nodes (created by remark-parse for certain HTML structures)
71732
- visit(tree, 'raw', (node, index, parent) => {
71733
- if (typeof index === 'number' && parent && 'children' in parent) {
71734
- handleTableInNode(node, index, parent);
71735
- }
71736
71452
  });
71737
71453
  return tree;
71738
71454
  };
@@ -87229,7 +86945,7 @@ const tocToHast = (headings = [], variables) => {
87229
86945
  stack.pop();
87230
86946
  }
87231
86947
  if (heading.properties) {
87232
- const content = lib_plain({ type: 'root', children: heading.children }, { variables: flatVars });
86948
+ const content = lib_plain({ type: 'root', children: heading.children }, { separator: '', variables: flatVars });
87233
86949
  stack[stack.length - 1].children.push(hastscript_lib_h('li', null, hastscript_lib_h('a', { href: `#${heading.properties.id}` }, content)));
87234
86950
  }
87235
86951
  });
@@ -92228,10 +91944,6 @@ const compile_list_item_listItem = (node, parent, state, info) => {
92228
91944
  const plain_plain = (node) => node.value;
92229
91945
  /* harmony default export */ const compile_plain = (plain_plain);
92230
91946
 
92231
- ;// ./processor/compile/variable.ts
92232
- const variable = (node) => `{user.${node.data?.hProperties?.name || ''}}`;
92233
- /* harmony default export */ const compile_variable = (variable);
92234
-
92235
91947
  ;// ./processor/compile/index.ts
92236
91948
 
92237
91949
 
@@ -93900,7 +93612,7 @@ function getComponentName(componentName, components) {
93900
93612
 
93901
93613
 
93902
93614
 
93903
- const mdxish_components_INLINE_COMPONENT_TAGS = new Set(['anchor', 'glossary']);
93615
+ const INLINE_COMPONENT_TAGS = new Set(['anchor', 'glossary']);
93904
93616
  function isElementContentNode(node) {
93905
93617
  return node.type === 'element' || node.type === 'text' || node.type === 'comment';
93906
93618
  }
@@ -93982,7 +93694,7 @@ function parseTextChildren(node, processMarkdown, components) {
93982
93694
  const hast = processMarkdown(child.value.trim());
93983
93695
  const children = (hast.children ?? []).filter(isElementContentNode);
93984
93696
  // For inline components, preserve plain text instead of wrapping in <p>
93985
- if (mdxish_components_INLINE_COMPONENT_TAGS.has(node.tagName.toLowerCase()) && isSingleParagraphTextNode(children)) {
93697
+ if (INLINE_COMPONENT_TAGS.has(node.tagName.toLowerCase()) && isSingleParagraphTextNode(children)) {
93986
93698
  return [child];
93987
93699
  }
93988
93700
  return children;
@@ -94044,6 +93756,14 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
94044
93756
  visit(tree, 'element', (node, index, parent) => {
94045
93757
  if (index === undefined || !parent)
94046
93758
  return;
93759
+ // Parse Image caption as markdown so it renders formatted (bold, code,
93760
+ // decoded entities) in the figcaption instead of as a raw string.
93761
+ // rehypeRaw strips children from <img> (void element), so we must
93762
+ // re-process the caption here, after rehypeRaw.
93763
+ if (node.tagName === 'img' && typeof node.properties?.caption === 'string' && !node.children?.length) {
93764
+ const captionHast = processMarkdown(node.properties.caption);
93765
+ node.children = (captionHast.children ?? []).filter(isElementContentNode);
93766
+ }
94047
93767
  // Skip runtime components and standard HTML tags
94048
93768
  if (RUNTIME_COMPONENT_TAGS.has(node.tagName))
94049
93769
  return;
@@ -94610,110 +94330,468 @@ const evaluateExpressions = ({ context = {} } = {}) => tree => {
94610
94330
  };
94611
94331
  /* harmony default export */ const evaluate_expressions = (evaluateExpressions);
94612
94332
 
94613
- ;// ./processor/transform/mdxish/heading-slugs.ts
94333
+ ;// ./processor/transform/mdxish/heading-slugs.ts
94334
+
94335
+
94336
+ function isHeading(node) {
94337
+ return /^h[1-6]$/.test(node.tagName);
94338
+ }
94339
+ function textContent(node) {
94340
+ if (node.type === 'text')
94341
+ return node.value;
94342
+ // Process variable nodes by using their variable name for the id generation
94343
+ if (node.type === 'element' && node.tagName === 'variable' && node.properties?.name) {
94344
+ if (node.properties.isLegacy) {
94345
+ return node.properties.name;
94346
+ }
94347
+ return `user.${node.properties.name}`;
94348
+ }
94349
+ if ('children' in node)
94350
+ return node.children.map(textContent).join('');
94351
+ return '';
94352
+ }
94353
+ /**
94354
+ * Rehype plugin that constructs ids for headings
94355
+ * Id's are used to construct slug anchor links & Table of Contents during rendering
94356
+ * Use the text / nodes that make up the heading to generate the id
94357
+ */
94358
+ const generateSlugForHeadings = () => (tree) => {
94359
+ const slugger = new BananaSlug();
94360
+ visit(tree, 'element', (node) => {
94361
+ if (isHeading(node) && !node.properties.id) {
94362
+ const text = node.children.map(textContent).join('');
94363
+ node.properties.id = slugger.slug(text);
94364
+ }
94365
+ });
94366
+ return tree;
94367
+ };
94368
+ /* harmony default export */ const heading_slugs = (generateSlugForHeadings);
94369
+
94370
+ // EXTERNAL MODULE: external "@readme/variable"
94371
+ var variable_ = __webpack_require__(8167);
94372
+ var variable_default = /*#__PURE__*/__webpack_require__.n(variable_);
94373
+ ;// ./node_modules/rehype-parse/lib/index.js
94374
+ /**
94375
+ * @import {Root} from 'hast'
94376
+ * @import {Options as FromHtmlOptions} from 'hast-util-from-html'
94377
+ * @import {Parser, Processor} from 'unified'
94378
+ */
94379
+
94380
+ /**
94381
+ * @typedef {Omit<FromHtmlOptions, 'onerror'> & RehypeParseFields} Options
94382
+ * Configuration.
94383
+ *
94384
+ * @typedef RehypeParseFields
94385
+ * Extra fields.
94386
+ * @property {boolean | null | undefined} [emitParseErrors=false]
94387
+ * Whether to emit parse errors while parsing (default: `false`).
94388
+ *
94389
+ * > 👉 **Note**: parse errors are currently being added to HTML.
94390
+ * > Not all errors emitted by parse5 (or us) are specced yet.
94391
+ * > Some documentation may still be missing.
94392
+ */
94393
+
94394
+
94395
+
94396
+ /**
94397
+ * Plugin to add support for parsing from HTML.
94398
+ *
94399
+ * > 👉 **Note**: this is not an XML parser.
94400
+ * > It supports SVG as embedded in HTML.
94401
+ * > It does not support the features available in XML.
94402
+ * > Passing SVG files might break but fragments of modern SVG should be fine.
94403
+ * > Use [`xast-util-from-xml`][xast-util-from-xml] to parse XML.
94404
+ *
94405
+ * @param {Options | null | undefined} [options]
94406
+ * Configuration (optional).
94407
+ * @returns {undefined}
94408
+ * Nothing.
94409
+ */
94410
+ function rehypeParse(options) {
94411
+ /** @type {Processor<Root>} */
94412
+ // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
94413
+ const self = this
94414
+ const {emitParseErrors, ...settings} = {...self.data('settings'), ...options}
94415
+
94416
+ self.parser = parser
94417
+
94418
+ /**
94419
+ * @type {Parser<Root>}
94420
+ */
94421
+ function parser(document, file) {
94422
+ return fromHtml(document, {
94423
+ ...settings,
94424
+ onerror: emitParseErrors
94425
+ ? function (message) {
94426
+ if (file.path) {
94427
+ message.name = file.path + ':' + message.name
94428
+ message.file = file.path
94429
+ }
94430
+
94431
+ file.messages.push(message)
94432
+ }
94433
+ : undefined
94434
+ })
94435
+ }
94436
+ }
94437
+
94438
+ ;// ./lib/mdast-util/empty-task-list-item/index.ts
94439
+ /**
94440
+ * Normalizes list items that are written as only `[ ]` or `[x]` into GFM task
94441
+ * list items during parse, but only when at least one whitespace character
94442
+ * follows the closing bracket (`]`). This matches legacy behaviour for checkboxes
94443
+ *
94444
+ * The issue is `remark-gfm` does not actually classify these as task items when they have no content
94445
+ * after the checkbox, which leaves them as plain text (`"[ ]"`). So a custom extension is needed to
94446
+ * treat these as task items
94447
+ */
94448
+ function exitListItemWithEmptyTaskListItem(token) {
94449
+ const node = this.stack[this.stack.length - 1];
94450
+ if (node &&
94451
+ node.type === 'listItem' &&
94452
+ typeof node.checked !== 'boolean') {
94453
+ const listItem = node;
94454
+ const head = listItem.children[0];
94455
+ if (head && head.type === 'paragraph' && head.children.length === 1) {
94456
+ const text = head.children[0];
94457
+ if (text.type === 'text') {
94458
+ const hasTrailingWhitespace = typeof head.position?.end.offset === 'number' &&
94459
+ typeof text.position?.end.offset === 'number' &&
94460
+ head.position.end.offset > text.position.end.offset;
94461
+ if (!hasTrailingWhitespace) {
94462
+ this.exit(token);
94463
+ return;
94464
+ }
94465
+ const value = text.value;
94466
+ if (value === '[ ]') {
94467
+ listItem.checked = false;
94468
+ head.children = [];
94469
+ }
94470
+ else if (value === '[x]' || value === '[X]') {
94471
+ listItem.checked = true;
94472
+ head.children = [];
94473
+ }
94474
+ }
94475
+ }
94476
+ }
94477
+ this.exit(token);
94478
+ }
94479
+ function emptyTaskListItemFromMarkdown() {
94480
+ return {
94481
+ exit: {
94482
+ listItem: exitListItemWithEmptyTaskListItem,
94483
+ },
94484
+ };
94485
+ }
94486
+
94487
+ ;// ./lib/mdast-util/legacy-variable/index.ts
94488
+
94489
+ const contextMap = new WeakMap();
94490
+ function findlegacyVariableToken() {
94491
+ // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
94492
+ const events = this.tokenStack;
94493
+ for (let i = events.length - 1; i >= 0; i -= 1) {
94494
+ const token = events[i][0];
94495
+ if (token.type === 'legacyVariable')
94496
+ return token;
94497
+ }
94498
+ return undefined;
94499
+ }
94500
+ function enterlegacyVariable(token) {
94501
+ contextMap.set(token, { value: '' });
94502
+ }
94503
+ function exitlegacyVariableValue(token) {
94504
+ const variableToken = findlegacyVariableToken.call(this);
94505
+ if (!variableToken)
94506
+ return;
94507
+ const ctx = contextMap.get(variableToken);
94508
+ // Build up the variable characters
94509
+ if (ctx)
94510
+ ctx.value += this.sliceSerialize(token);
94511
+ }
94512
+ function exitlegacyVariable(token) {
94513
+ const ctx = contextMap.get(token);
94514
+ const serialized = this.sliceSerialize(token);
94515
+ const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
94516
+ ? serialized.slice(2, -2)
94517
+ : ctx?.value ?? '';
94518
+ const nodePosition = {
94519
+ start: {
94520
+ offset: token.start.offset,
94521
+ line: token.start.line,
94522
+ column: token.start.column,
94523
+ },
94524
+ end: {
94525
+ offset: token.end.offset,
94526
+ line: token.end.line,
94527
+ column: token.end.column,
94528
+ },
94529
+ };
94530
+ if (variableName.startsWith('glossary:')) {
94531
+ const term = variableName.slice('glossary:'.length).trim();
94532
+ this.enter({
94533
+ type: NodeTypes.glossary,
94534
+ data: {
94535
+ hName: 'Glossary',
94536
+ hProperties: { term },
94537
+ },
94538
+ children: [{ type: 'text', value: term }],
94539
+ position: nodePosition,
94540
+ }, token);
94541
+ this.exit(token);
94542
+ contextMap.delete(token);
94543
+ return;
94544
+ }
94545
+ this.enter({
94546
+ type: NodeTypes.variable,
94547
+ data: {
94548
+ hName: 'Variable',
94549
+ hProperties: { name: variableName.trim(), isLegacy: true },
94550
+ },
94551
+ value: `<<${variableName}>>`,
94552
+ }, token);
94553
+ this.exit(token);
94554
+ contextMap.delete(token);
94555
+ }
94556
+ function legacyVariableFromMarkdown() {
94557
+ return {
94558
+ enter: {
94559
+ legacyVariable: enterlegacyVariable,
94560
+ },
94561
+ exit: {
94562
+ legacyVariableValue: exitlegacyVariableValue,
94563
+ legacyVariable: exitlegacyVariable,
94564
+ },
94565
+ };
94566
+ }
94567
+
94568
+ ;// ./node_modules/micromark-util-symbol/lib/codes.js
94569
+ /**
94570
+ * Character codes.
94571
+ *
94572
+ * This module is compiled away!
94573
+ *
94574
+ * micromark works based on character codes.
94575
+ * This module contains constants for the ASCII block and the replacement
94576
+ * character.
94577
+ * A couple of them are handled in a special way, such as the line endings
94578
+ * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
94579
+ * tab) and its expansion based on what column it’s at (virtual space),
94580
+ * and the end-of-file (eof) character.
94581
+ * As values are preprocessed before handling them, the actual characters LF,
94582
+ * CR, HT, and NUL (which is present as the replacement character), are
94583
+ * guaranteed to not exist.
94584
+ *
94585
+ * Unicode basic latin block.
94586
+ */
94587
+ const codes = /** @type {const} */ ({
94588
+ carriageReturn: -5,
94589
+ lineFeed: -4,
94590
+ carriageReturnLineFeed: -3,
94591
+ horizontalTab: -2,
94592
+ virtualSpace: -1,
94593
+ eof: null,
94594
+ nul: 0,
94595
+ soh: 1,
94596
+ stx: 2,
94597
+ etx: 3,
94598
+ eot: 4,
94599
+ enq: 5,
94600
+ ack: 6,
94601
+ bel: 7,
94602
+ bs: 8,
94603
+ ht: 9, // `\t`
94604
+ lf: 10, // `\n`
94605
+ vt: 11, // `\v`
94606
+ ff: 12, // `\f`
94607
+ cr: 13, // `\r`
94608
+ so: 14,
94609
+ si: 15,
94610
+ dle: 16,
94611
+ dc1: 17,
94612
+ dc2: 18,
94613
+ dc3: 19,
94614
+ dc4: 20,
94615
+ nak: 21,
94616
+ syn: 22,
94617
+ etb: 23,
94618
+ can: 24,
94619
+ em: 25,
94620
+ sub: 26,
94621
+ esc: 27,
94622
+ fs: 28,
94623
+ gs: 29,
94624
+ rs: 30,
94625
+ us: 31,
94626
+ space: 32,
94627
+ exclamationMark: 33, // `!`
94628
+ quotationMark: 34, // `"`
94629
+ numberSign: 35, // `#`
94630
+ dollarSign: 36, // `$`
94631
+ percentSign: 37, // `%`
94632
+ ampersand: 38, // `&`
94633
+ apostrophe: 39, // `'`
94634
+ leftParenthesis: 40, // `(`
94635
+ rightParenthesis: 41, // `)`
94636
+ asterisk: 42, // `*`
94637
+ plusSign: 43, // `+`
94638
+ comma: 44, // `,`
94639
+ dash: 45, // `-`
94640
+ dot: 46, // `.`
94641
+ slash: 47, // `/`
94642
+ digit0: 48, // `0`
94643
+ digit1: 49, // `1`
94644
+ digit2: 50, // `2`
94645
+ digit3: 51, // `3`
94646
+ digit4: 52, // `4`
94647
+ digit5: 53, // `5`
94648
+ digit6: 54, // `6`
94649
+ digit7: 55, // `7`
94650
+ digit8: 56, // `8`
94651
+ digit9: 57, // `9`
94652
+ colon: 58, // `:`
94653
+ semicolon: 59, // `;`
94654
+ lessThan: 60, // `<`
94655
+ equalsTo: 61, // `=`
94656
+ greaterThan: 62, // `>`
94657
+ questionMark: 63, // `?`
94658
+ atSign: 64, // `@`
94659
+ uppercaseA: 65, // `A`
94660
+ uppercaseB: 66, // `B`
94661
+ uppercaseC: 67, // `C`
94662
+ uppercaseD: 68, // `D`
94663
+ uppercaseE: 69, // `E`
94664
+ uppercaseF: 70, // `F`
94665
+ uppercaseG: 71, // `G`
94666
+ uppercaseH: 72, // `H`
94667
+ uppercaseI: 73, // `I`
94668
+ uppercaseJ: 74, // `J`
94669
+ uppercaseK: 75, // `K`
94670
+ uppercaseL: 76, // `L`
94671
+ uppercaseM: 77, // `M`
94672
+ uppercaseN: 78, // `N`
94673
+ uppercaseO: 79, // `O`
94674
+ uppercaseP: 80, // `P`
94675
+ uppercaseQ: 81, // `Q`
94676
+ uppercaseR: 82, // `R`
94677
+ uppercaseS: 83, // `S`
94678
+ uppercaseT: 84, // `T`
94679
+ uppercaseU: 85, // `U`
94680
+ uppercaseV: 86, // `V`
94681
+ uppercaseW: 87, // `W`
94682
+ uppercaseX: 88, // `X`
94683
+ uppercaseY: 89, // `Y`
94684
+ uppercaseZ: 90, // `Z`
94685
+ leftSquareBracket: 91, // `[`
94686
+ backslash: 92, // `\`
94687
+ rightSquareBracket: 93, // `]`
94688
+ caret: 94, // `^`
94689
+ underscore: 95, // `_`
94690
+ graveAccent: 96, // `` ` ``
94691
+ lowercaseA: 97, // `a`
94692
+ lowercaseB: 98, // `b`
94693
+ lowercaseC: 99, // `c`
94694
+ lowercaseD: 100, // `d`
94695
+ lowercaseE: 101, // `e`
94696
+ lowercaseF: 102, // `f`
94697
+ lowercaseG: 103, // `g`
94698
+ lowercaseH: 104, // `h`
94699
+ lowercaseI: 105, // `i`
94700
+ lowercaseJ: 106, // `j`
94701
+ lowercaseK: 107, // `k`
94702
+ lowercaseL: 108, // `l`
94703
+ lowercaseM: 109, // `m`
94704
+ lowercaseN: 110, // `n`
94705
+ lowercaseO: 111, // `o`
94706
+ lowercaseP: 112, // `p`
94707
+ lowercaseQ: 113, // `q`
94708
+ lowercaseR: 114, // `r`
94709
+ lowercaseS: 115, // `s`
94710
+ lowercaseT: 116, // `t`
94711
+ lowercaseU: 117, // `u`
94712
+ lowercaseV: 118, // `v`
94713
+ lowercaseW: 119, // `w`
94714
+ lowercaseX: 120, // `x`
94715
+ lowercaseY: 121, // `y`
94716
+ lowercaseZ: 122, // `z`
94717
+ leftCurlyBrace: 123, // `{`
94718
+ verticalBar: 124, // `|`
94719
+ rightCurlyBrace: 125, // `}`
94720
+ tilde: 126, // `~`
94721
+ del: 127,
94722
+ // Unicode Specials block.
94723
+ byteOrderMarker: 65_279,
94724
+ // Unicode Specials block.
94725
+ replacementCharacter: 65_533 // `�`
94726
+ })
94727
+
94728
+ ;// ./lib/micromark/legacy-variable/syntax.ts
94614
94729
 
94615
94730
 
94616
- function isHeading(node) {
94617
- return /^h[1-6]$/.test(node.tagName);
94731
+ function isAllowedValueChar(code) {
94732
+ return (code !== null &&
94733
+ code !== codes.lessThan &&
94734
+ code !== codes.greaterThan &&
94735
+ !markdownLineEnding(code));
94618
94736
  }
94619
- function textContent(node) {
94620
- if (node.type === 'text')
94621
- return node.value;
94622
- // Process variable nodes by using their variable name for the id generation
94623
- if (node.type === 'element' && node.tagName === 'variable' && node.properties?.name) {
94624
- if (node.properties.isLegacy) {
94625
- return node.properties.name;
94737
+ const legacyVariableConstruct = {
94738
+ name: 'legacyVariable',
94739
+ tokenize,
94740
+ };
94741
+ function tokenize(effects, ok, nok) {
94742
+ let hasValue = false;
94743
+ const start = (code) => {
94744
+ if (code !== codes.lessThan)
94745
+ return nok(code);
94746
+ effects.enter('legacyVariable');
94747
+ effects.enter('legacyVariableMarkerStart');
94748
+ effects.consume(code); // <
94749
+ return open2;
94750
+ };
94751
+ const open2 = (code) => {
94752
+ if (code !== codes.lessThan)
94753
+ return nok(code);
94754
+ effects.consume(code); // <<
94755
+ effects.exit('legacyVariableMarkerStart');
94756
+ effects.enter('legacyVariableValue');
94757
+ return value;
94758
+ };
94759
+ const value = (code) => {
94760
+ if (code === codes.greaterThan) {
94761
+ if (!hasValue)
94762
+ return nok(code);
94763
+ effects.exit('legacyVariableValue');
94764
+ effects.enter('legacyVariableMarkerEnd');
94765
+ effects.consume(code); // >
94766
+ return close2;
94626
94767
  }
94627
- return `user.${node.properties.name}`;
94628
- }
94629
- if ('children' in node)
94630
- return node.children.map(textContent).join('');
94631
- return '';
94768
+ if (!isAllowedValueChar(code))
94769
+ return nok(code);
94770
+ hasValue = true;
94771
+ effects.consume(code);
94772
+ return value;
94773
+ };
94774
+ const close2 = (code) => {
94775
+ if (code !== codes.greaterThan)
94776
+ return nok(code);
94777
+ effects.consume(code); // >>
94778
+ effects.exit('legacyVariableMarkerEnd');
94779
+ effects.exit('legacyVariable');
94780
+ return ok;
94781
+ };
94782
+ return start;
94783
+ }
94784
+ function legacyVariable() {
94785
+ return {
94786
+ text: { [codes.lessThan]: legacyVariableConstruct },
94787
+ };
94632
94788
  }
94633
- /**
94634
- * Rehype plugin that constructs ids for headings
94635
- * Id's are used to construct slug anchor links & Table of Contents during rendering
94636
- * Use the text / nodes that make up the heading to generate the id
94637
- */
94638
- const generateSlugForHeadings = () => (tree) => {
94639
- const slugger = new BananaSlug();
94640
- visit(tree, 'element', (node) => {
94641
- if (isHeading(node) && !node.properties.id) {
94642
- const text = node.children.map(textContent).join('');
94643
- node.properties.id = slugger.slug(text);
94644
- }
94645
- });
94646
- return tree;
94647
- };
94648
- /* harmony default export */ const heading_slugs = (generateSlugForHeadings);
94649
-
94650
- // EXTERNAL MODULE: external "@readme/variable"
94651
- var variable_ = __webpack_require__(8167);
94652
- var variable_default = /*#__PURE__*/__webpack_require__.n(variable_);
94653
- ;// ./node_modules/rehype-parse/lib/index.js
94654
- /**
94655
- * @import {Root} from 'hast'
94656
- * @import {Options as FromHtmlOptions} from 'hast-util-from-html'
94657
- * @import {Parser, Processor} from 'unified'
94658
- */
94659
-
94660
- /**
94661
- * @typedef {Omit<FromHtmlOptions, 'onerror'> & RehypeParseFields} Options
94662
- * Configuration.
94663
- *
94664
- * @typedef RehypeParseFields
94665
- * Extra fields.
94666
- * @property {boolean | null | undefined} [emitParseErrors=false]
94667
- * Whether to emit parse errors while parsing (default: `false`).
94668
- *
94669
- * > 👉 **Note**: parse errors are currently being added to HTML.
94670
- * > Not all errors emitted by parse5 (or us) are specced yet.
94671
- * > Some documentation may still be missing.
94672
- */
94673
-
94674
-
94675
94789
 
94790
+ ;// ./lib/micromark/legacy-variable/index.ts
94676
94791
  /**
94677
- * Plugin to add support for parsing from HTML.
94678
- *
94679
- * > 👉 **Note**: this is not an XML parser.
94680
- * > It supports SVG as embedded in HTML.
94681
- * > It does not support the features available in XML.
94682
- * > Passing SVG files might break but fragments of modern SVG should be fine.
94683
- * > Use [`xast-util-from-xml`][xast-util-from-xml] to parse XML.
94684
- *
94685
- * @param {Options | null | undefined} [options]
94686
- * Configuration (optional).
94687
- * @returns {undefined}
94688
- * Nothing.
94792
+ * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
94689
94793
  */
94690
- function rehypeParse(options) {
94691
- /** @type {Processor<Root>} */
94692
- // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
94693
- const self = this
94694
- const {emitParseErrors, ...settings} = {...self.data('settings'), ...options}
94695
-
94696
- self.parser = parser
94697
-
94698
- /**
94699
- * @type {Parser<Root>}
94700
- */
94701
- function parser(document, file) {
94702
- return fromHtml(document, {
94703
- ...settings,
94704
- onerror: emitParseErrors
94705
- ? function (message) {
94706
- if (file.path) {
94707
- message.name = file.path + ':' + message.name
94708
- message.file = file.path
94709
- }
94710
94794
 
94711
- file.messages.push(message)
94712
- }
94713
- : undefined
94714
- })
94715
- }
94716
- }
94717
94795
 
94718
94796
  ;// ./node_modules/entities/lib/esm/generated/encode-html.js
94719
94797
  // Generated using scripts/write-encode-map.ts
@@ -95020,349 +95098,6 @@ function looseHtmlEntityFromMarkdown() {
95020
95098
  */
95021
95099
 
95022
95100
 
95023
- ;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
95024
-
95025
- // Marker patterns for multi-node emphasis detection
95026
- const MARKER_PATTERNS = [
95027
- { isBold: true, marker: '**' },
95028
- { isBold: true, marker: '__' },
95029
- { isBold: false, marker: '*' },
95030
- { isBold: false, marker: '_' },
95031
- ];
95032
- // Patterns to detect for bold (** and __) and italic (* and _) syntax:
95033
- // Bold: ** text**, **text **, word** text**, ** text **
95034
- // Italic: * text*, *text *, word* text*, * text *
95035
- // Same patterns for underscore variants
95036
- // We use separate patterns for each marker type to allow this flexibility.
95037
- // Pattern for ** bold **
95038
- // Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
95039
- // trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
95040
- const asteriskBoldRegex = /([^*\s]+)?\s*(\*\*)(?:\s+((?:[^*\n]|\*(?!\*))+?)(\s*)\2|((?:[^*\n]|\*(?!\*))+?)(\s+)\2)(\S|$)?/g;
95041
- // Pattern for __ bold __
95042
- const underscoreBoldRegex = /([^_\s]+)?\s*(__)(?:\s+((?:__(?! )|_(?!_)|[^_\n])+?)(\s*)\2|((?:__(?! )|_(?!_)|[^_\n])+?)(\s+)\2)(\S|$)?/g;
95043
- // Pattern for * italic *
95044
- const asteriskItalicRegex = /([^*\s]+)?\s*(\*)(?!\*)(?:\s+([^*\n]+?)(\s*)\2|([^*\n]+?)(\s+)\2)(\S|$)?/g;
95045
- // Pattern for _ italic _
95046
- const underscoreItalicRegex = /([^_\s]+)?\s*(_)(?!_)(?:\s+((?:[^_\n]|_(?! ))+?)(\s*)\2|((?:[^_\n]|_(?! ))+?)(\s+)\2)(\S|$)?/g;
95047
- // CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
95048
- // Pattern for intraword _word_ in words like hello_world_
95049
- const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
95050
- // Pattern for intraword __word__ in words like hello__world__
95051
- const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
95052
- // Pattern for intraword *word* in words like hello*world*
95053
- const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
95054
- // Pattern for intraword **word** in words like hello**world**
95055
- const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
95056
- /**
95057
- * Finds opening emphasis marker in a text value.
95058
- * Returns marker info if found, null otherwise.
95059
- */
95060
- function findOpeningMarker(text) {
95061
- const results = MARKER_PATTERNS.map(({ isBold, marker }) => {
95062
- if (marker === '*' && text.startsWith('**'))
95063
- return null;
95064
- if (marker === '_' && text.startsWith('__'))
95065
- return null;
95066
- if (text.startsWith(marker) && text.length > marker.length) {
95067
- return { isBold, marker, textAfter: text.slice(marker.length), textBefore: '' };
95068
- }
95069
- const idx = text.indexOf(marker);
95070
- if (idx > 0 && !/\s/.test(text[idx - 1])) {
95071
- if (marker === '*' && text.slice(idx).startsWith('**'))
95072
- return null;
95073
- if (marker === '_' && text.slice(idx).startsWith('__'))
95074
- return null;
95075
- const after = text.slice(idx + marker.length);
95076
- if (after.length > 0) {
95077
- return { isBold, marker, textAfter: after, textBefore: text.slice(0, idx) };
95078
- }
95079
- }
95080
- return null;
95081
- });
95082
- return results.find(r => r !== null) ?? null;
95083
- }
95084
- /**
95085
- * Finds the end/closing marker in a text node for multi-node emphasis.
95086
- */
95087
- function findEndMarker(text, marker) {
95088
- const spacePattern = ` ${marker}`;
95089
- const spaceIdx = text.indexOf(spacePattern);
95090
- if (spaceIdx >= 0) {
95091
- if (marker === '*' && text.slice(spaceIdx + 1).startsWith('**'))
95092
- return null;
95093
- if (marker === '_' && text.slice(spaceIdx + 1).startsWith('__'))
95094
- return null;
95095
- return {
95096
- textAfter: text.slice(spaceIdx + spacePattern.length),
95097
- textBefore: text.slice(0, spaceIdx),
95098
- };
95099
- }
95100
- if (text.startsWith(marker)) {
95101
- if (marker === '*' && text.startsWith('**'))
95102
- return null;
95103
- if (marker === '_' && text.startsWith('__'))
95104
- return null;
95105
- return {
95106
- textAfter: text.slice(marker.length),
95107
- textBefore: '',
95108
- };
95109
- }
95110
- return null;
95111
- }
95112
- /**
95113
- * Scan children for an opening emphasis marker in a text node.
95114
- */
95115
- function findOpeningInChildren(children) {
95116
- let result = null;
95117
- children.some((child, idx) => {
95118
- if (child.type !== 'text')
95119
- return false;
95120
- const found = findOpeningMarker(child.value);
95121
- if (found) {
95122
- result = { idx, opening: found };
95123
- return true;
95124
- }
95125
- return false;
95126
- });
95127
- return result;
95128
- }
95129
- /**
95130
- * Scan children (after openingIdx) for a closing emphasis marker.
95131
- */
95132
- function findClosingInChildren(children, openingIdx, marker) {
95133
- let result = null;
95134
- children.slice(openingIdx + 1).some((child, relativeIdx) => {
95135
- if (child.type !== 'text')
95136
- return false;
95137
- const found = findEndMarker(child.value, marker);
95138
- if (found) {
95139
- result = { closingIdx: openingIdx + 1 + relativeIdx, closing: found };
95140
- return true;
95141
- }
95142
- return false;
95143
- });
95144
- return result;
95145
- }
95146
- /**
95147
- * Build the replacement nodes for a matched emphasis pair.
95148
- */
95149
- function buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx }) {
95150
- const newNodes = [];
95151
- if (opening.textBefore) {
95152
- newNodes.push({ type: 'text', value: `${opening.textBefore} ` });
95153
- }
95154
- const emphasisChildren = [];
95155
- const openingText = opening.textAfter.replace(/^\s+/, '');
95156
- if (openingText) {
95157
- emphasisChildren.push({ type: 'text', value: openingText });
95158
- }
95159
- container.children.slice(openingIdx + 1, closingIdx).forEach(child => {
95160
- emphasisChildren.push(child);
95161
- });
95162
- const closingText = closing.textBefore.replace(/\s+$/, '');
95163
- if (closingText) {
95164
- emphasisChildren.push({ type: 'text', value: closingText });
95165
- }
95166
- if (emphasisChildren.length > 0) {
95167
- const emphasisNode = opening.isBold
95168
- ? { type: 'strong', children: emphasisChildren }
95169
- : { type: 'emphasis', children: emphasisChildren };
95170
- newNodes.push(emphasisNode);
95171
- }
95172
- if (closing.textAfter) {
95173
- newNodes.push({ type: 'text', value: closing.textAfter });
95174
- }
95175
- return newNodes;
95176
- }
95177
- /**
95178
- * Find and transform one multi-node emphasis pair in the container.
95179
- * Returns true if a pair was found and transformed, false otherwise.
95180
- */
95181
- function processOneEmphasisPair(container) {
95182
- const openingResult = findOpeningInChildren(container.children);
95183
- if (!openingResult)
95184
- return false;
95185
- const { idx: openingIdx, opening } = openingResult;
95186
- const closingResult = findClosingInChildren(container.children, openingIdx, opening.marker);
95187
- if (!closingResult)
95188
- return false;
95189
- const { closingIdx, closing } = closingResult;
95190
- const newNodes = buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx });
95191
- const deleteCount = closingIdx - openingIdx + 1;
95192
- container.children.splice(openingIdx, deleteCount, ...newNodes);
95193
- return true;
95194
- }
95195
- /**
95196
- * Handle malformed emphasis that spans multiple AST nodes.
95197
- * E.g., "**bold [link](url)**" where markers are in different text nodes.
95198
- */
95199
- function visitMultiNodeEmphasis(tree) {
95200
- const containerTypes = ['paragraph', 'heading', 'tableCell', 'listItem', 'blockquote'];
95201
- visit(tree, node => {
95202
- if (!containerTypes.includes(node.type))
95203
- return;
95204
- if (!('children' in node) || !Array.isArray(node.children))
95205
- return;
95206
- const container = node;
95207
- let foundPair = true;
95208
- while (foundPair) {
95209
- foundPair = processOneEmphasisPair(container);
95210
- }
95211
- });
95212
- }
95213
- /**
95214
- * A remark plugin that normalizes malformed bold and italic markers in text nodes.
95215
- * Detects patterns like `** bold**`, `Hello** Wrong Bold**`, `__ bold__`, `Hello__ Wrong Bold__`,
95216
- * `* italic*`, `Hello* Wrong Italic*`, `_ italic_`, or `Hello_ Wrong Italic_`
95217
- * and converts them to proper strong/emphasis nodes, matching the behavior of the legacy rdmd engine.
95218
- *
95219
- * Supports both asterisk (`**bold**`, `*italic*`) and underscore (`__bold__`, `_italic_`) syntax.
95220
- * Also supports snake_case content like `** some_snake_case**`.
95221
- *
95222
- * This runs after remark-parse, which (in v11+) is strict and doesn't parse
95223
- * malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
95224
- */
95225
- const normalizeEmphasisAST = () => (tree) => {
95226
- visit(tree, 'text', function visitor(node, index, parent) {
95227
- if (index === undefined || !parent)
95228
- return undefined;
95229
- // Skip if inside code blocks or inline code
95230
- if (parent.type === 'inlineCode' || parent.type === 'code') {
95231
- return undefined;
95232
- }
95233
- const text = node.value;
95234
- const allMatches = [];
95235
- [...text.matchAll(asteriskBoldRegex)].forEach(match => {
95236
- allMatches.push({ isBold: true, marker: '**', match });
95237
- });
95238
- [...text.matchAll(underscoreBoldRegex)].forEach(match => {
95239
- allMatches.push({ isBold: true, marker: '__', match });
95240
- });
95241
- [...text.matchAll(asteriskItalicRegex)].forEach(match => {
95242
- allMatches.push({ isBold: false, marker: '*', match });
95243
- });
95244
- [...text.matchAll(underscoreItalicRegex)].forEach(match => {
95245
- allMatches.push({ isBold: false, marker: '_', match });
95246
- });
95247
- [...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
95248
- allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
95249
- });
95250
- [...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
95251
- allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
95252
- });
95253
- [...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
95254
- allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
95255
- });
95256
- [...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
95257
- allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
95258
- });
95259
- if (allMatches.length === 0)
95260
- return undefined;
95261
- allMatches.sort((a, b) => (a.match.index ?? 0) - (b.match.index ?? 0));
95262
- const filteredMatches = [];
95263
- let lastEnd = 0;
95264
- allMatches.forEach(info => {
95265
- const start = info.match.index ?? 0;
95266
- const end = start + info.match[0].length;
95267
- if (start >= lastEnd) {
95268
- filteredMatches.push(info);
95269
- lastEnd = end;
95270
- }
95271
- });
95272
- if (filteredMatches.length === 0)
95273
- return undefined;
95274
- const parts = [];
95275
- let lastIndex = 0;
95276
- filteredMatches.forEach(({ isBold, isIntraword, marker, match }) => {
95277
- const matchIndex = match.index ?? 0;
95278
- const fullMatch = match[0];
95279
- if (isIntraword) {
95280
- // handles cases like hello_world_ where we only want to italicize 'world'
95281
- const charBefore = match[1] || ''; // e.g., "l" in "hello_world_"
95282
- const content = match[2]; // e.g., "world"
95283
- const combinedBefore = text.slice(lastIndex, matchIndex) + charBefore;
95284
- if (combinedBefore) {
95285
- parts.push({ type: 'text', value: combinedBefore });
95286
- }
95287
- if (isBold) {
95288
- parts.push({
95289
- type: 'strong',
95290
- children: [{ type: 'text', value: content }],
95291
- });
95292
- }
95293
- else {
95294
- parts.push({
95295
- type: 'emphasis',
95296
- children: [{ type: 'text', value: content }],
95297
- });
95298
- }
95299
- lastIndex = matchIndex + fullMatch.length;
95300
- return;
95301
- }
95302
- if (matchIndex > lastIndex) {
95303
- const beforeText = text.slice(lastIndex, matchIndex);
95304
- if (beforeText) {
95305
- parts.push({ type: 'text', value: beforeText });
95306
- }
95307
- }
95308
- const wordBefore = match[1]; // e.g., "Hello" in "Hello** Wrong Bold**"
95309
- const contentWithSpaceAfter = match[3]; // Content when there's a space after opening markers
95310
- const trailingSpace1 = match[4] || ''; // Space before closing markers (for "** text **" pattern)
95311
- const contentWithSpaceBefore = match[5]; // Content when there's only a space before closing markers
95312
- const trailingSpace2 = match[6] || ''; // Space before closing markers (for "**text **" pattern)
95313
- const trailingSpace = trailingSpace1 || trailingSpace2; // Combined trailing space
95314
- const content = (contentWithSpaceAfter || contentWithSpaceBefore || '').trim();
95315
- const afterChar = match[7]; // Character after closing markers (if any)
95316
- const markerPos = fullMatch.indexOf(marker);
95317
- const spacesBeforeMarkers = wordBefore
95318
- ? fullMatch.slice(wordBefore.length, markerPos)
95319
- : fullMatch.slice(0, markerPos);
95320
- const shouldAddSpace = !!contentWithSpaceAfter && !!wordBefore && !spacesBeforeMarkers;
95321
- if (wordBefore) {
95322
- const spacing = spacesBeforeMarkers + (shouldAddSpace ? ' ' : '');
95323
- parts.push({ type: 'text', value: wordBefore + spacing });
95324
- }
95325
- else if (spacesBeforeMarkers) {
95326
- parts.push({ type: 'text', value: spacesBeforeMarkers });
95327
- }
95328
- if (content) {
95329
- if (isBold) {
95330
- parts.push({
95331
- type: 'strong',
95332
- children: [{ type: 'text', value: content }],
95333
- });
95334
- }
95335
- else {
95336
- parts.push({
95337
- type: 'emphasis',
95338
- children: [{ type: 'text', value: content }],
95339
- });
95340
- }
95341
- }
95342
- if (afterChar) {
95343
- const prefix = trailingSpace ? ' ' : '';
95344
- parts.push({ type: 'text', value: prefix + afterChar });
95345
- }
95346
- lastIndex = matchIndex + fullMatch.length;
95347
- });
95348
- if (lastIndex < text.length) {
95349
- const remainingText = text.slice(lastIndex);
95350
- if (remainingText) {
95351
- parts.push({ type: 'text', value: remainingText });
95352
- }
95353
- }
95354
- if (parts.length > 0) {
95355
- parent.children.splice(index, 1, ...parts);
95356
- return [SKIP, index + parts.length];
95357
- }
95358
- return undefined;
95359
- });
95360
- // Handle malformed emphasis spanning multiple nodes (e.g., **text [link](url) **)
95361
- visitMultiNodeEmphasis(tree);
95362
- return tree;
95363
- };
95364
- /* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
95365
-
95366
95101
  ;// ./processor/transform/mdxish/magic-blocks/patterns.ts
95367
95102
  /** Matches HTML tags (open, close, self-closing) with optional attributes. */
95368
95103
  const HTML_TAG_RE = /<\/?([a-zA-Z][a-zA-Z0-9-]*)((?:[^>"']*(?:"[^"]*"|'[^']*'))*[^>"']*)>/g;
@@ -95980,6 +95715,351 @@ const magicBlockTransformer = (options = {}) => tree => {
95980
95715
  };
95981
95716
  /* harmony default export */ const magic_block_transformer = (magicBlockTransformer);
95982
95717
 
95718
+ ;// ./processor/transform/mdxish/constants.ts
95719
+ /**
95720
+ * Inline component tags handled by mdxish-inline-components.ts.
95721
+ * Also excluded from block-level handling in mdxish-component-blocks.ts.
95722
+ */
95723
+ const constants_INLINE_COMPONENT_TAGS = new Set(['Anchor']);
95724
+
95725
+ ;// ./processor/transform/mdxish/mdxish-component-blocks.ts
95726
+
95727
+
95728
+
95729
+
95730
+
95731
+
95732
+
95733
+ const pascalCaseTagPattern = /^<([A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>([\s\S]*)?$/;
95734
+ const tagAttributePattern = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
95735
+ /**
95736
+ * Maximum number of siblings to scan forward when looking for a closing tag
95737
+ * to avoid scanning too far and degrading performance
95738
+ */
95739
+ const MAX_LOOKAHEAD = 30;
95740
+ /**
95741
+ * Tags that have dedicated transformers and should NOT be handled by this plugin.
95742
+ * These components either have special parsing requirements that the generic component
95743
+ * block transformer cannot handle correctly, or are inline components that we don't
95744
+ * want to convert to mdxJsxFlowElement which is a block level element.
95745
+ */
95746
+ const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table', 'Glossary', ...constants_INLINE_COMPONENT_TAGS]);
95747
+ const inlineMdProcessor = unified()
95748
+ .data('micromarkExtensions', [legacyVariable()])
95749
+ .data('fromMarkdownExtensions', [legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown()])
95750
+ .use(remarkParse)
95751
+ .use(remarkGfm);
95752
+ const isClosingTag = (value, tag) => value.trim() === `</${tag}>`;
95753
+ /**
95754
+ * Parse markdown content into mdast children nodes.
95755
+ */
95756
+ const parseMdChildren = (value) => {
95757
+ const parsed = inlineMdProcessor.parse(value);
95758
+ return parsed.children || [];
95759
+ };
95760
+ /**
95761
+ * Convert raw attribute string into mdxJsxAttribute entries.
95762
+ * Handles both key-value attributes (theme="info") and boolean attributes (empty).
95763
+ */
95764
+ const parseAttributes = (raw) => {
95765
+ const attributes = [];
95766
+ const attrString = raw.trim();
95767
+ if (!attrString)
95768
+ return attributes;
95769
+ tagAttributePattern.lastIndex = 0;
95770
+ let match = tagAttributePattern.exec(attrString);
95771
+ while (match !== null) {
95772
+ const [, attrName, attrValue] = match;
95773
+ const value = attrValue ? attrValue.replace(/^['"]|['"]$/g, '') : null;
95774
+ attributes.push({ type: 'mdxJsxAttribute', name: attrName, value });
95775
+ match = tagAttributePattern.exec(attrString);
95776
+ }
95777
+ return attributes;
95778
+ };
95779
+ /**
95780
+ * Parse an HTML tag string into structured data.
95781
+ */
95782
+ const parseTag = (value) => {
95783
+ const match = value.match(pascalCaseTagPattern);
95784
+ if (!match)
95785
+ return null;
95786
+ const [, tag, attrString = '', selfClosing = '', contentAfterTag = ''] = match;
95787
+ return {
95788
+ tag,
95789
+ attributes: parseAttributes(attrString),
95790
+ selfClosing: !!selfClosing,
95791
+ contentAfterTag,
95792
+ };
95793
+ };
95794
+ /**
95795
+ * Parse substring content of a node and update the parent's children to include the new nodes.
95796
+ */
95797
+ const parseSibling = (stack, parent, index, sibling) => {
95798
+ const siblingNodes = parseMdChildren(sibling);
95799
+ // The new sibling nodes might contain new components to be processed
95800
+ if (siblingNodes.length > 0) {
95801
+ parent.children.splice(index + 1, 0, ...siblingNodes);
95802
+ stack.push(parent);
95803
+ }
95804
+ };
95805
+ /**
95806
+ * Create an MdxJsxFlowElement node from component data.
95807
+ */
95808
+ const createComponentNode = ({ tag, attributes, children, startPosition, endPosition }) => ({
95809
+ type: 'mdxJsxFlowElement',
95810
+ name: tag,
95811
+ attributes,
95812
+ children,
95813
+ position: {
95814
+ start: startPosition?.start,
95815
+ end: endPosition?.end ?? startPosition?.end,
95816
+ },
95817
+ });
95818
+ /**
95819
+ * Remove a closing tag from a paragraph's children and return the updated paragraph.
95820
+ */
95821
+ const stripClosingTagFromParagraph = (node, tag) => {
95822
+ if (!Array.isArray(node.children))
95823
+ return { paragraph: node, found: false };
95824
+ const children = [...node.children];
95825
+ const closingIndex = children.findIndex(child => child.type === 'html' && isClosingTag(child.value || '', tag));
95826
+ if (closingIndex === -1)
95827
+ return { paragraph: node, found: false };
95828
+ children.splice(closingIndex, 1);
95829
+ // After removing the closing tag, trim trailing whitespace/newlines from the
95830
+ // preceding text node. Remark parses "Hello\n</Callout>" as text("Hello\n") +
95831
+ // html("</Callout>"), and the leftover \n would be converted to <br> in HAST.
95832
+ if (closingIndex > 0) {
95833
+ const prev = children[closingIndex - 1];
95834
+ if (prev.type === 'text') {
95835
+ const trimmed = prev.value.trimEnd();
95836
+ if (trimmed) {
95837
+ prev.value = trimmed;
95838
+ }
95839
+ else {
95840
+ children.splice(closingIndex - 1, 1);
95841
+ }
95842
+ }
95843
+ }
95844
+ return { paragraph: { ...node, children }, found: true };
95845
+ };
95846
+ /**
95847
+ * Scan forward through siblings to find a closing tag.
95848
+ * Handles:
95849
+ * - Exact match HTML siblings (e.g., `</Tag>`)
95850
+ * - HTML siblings with embedded closing tag (e.g., `...\n</Tag>`)
95851
+ * - Paragraph siblings containing the closing tag as a child
95852
+ *
95853
+ * Returns null if not found within MAX_LOOKAHEAD siblings
95854
+ */
95855
+ const scanForClosingTag = (parent, startIndex, tag) => {
95856
+ const closingTagStr = `</${tag}>`;
95857
+ const maxIndex = Math.min(startIndex + MAX_LOOKAHEAD, parent.children.length);
95858
+ let i = startIndex + 1;
95859
+ for (; i < maxIndex; i += 1) {
95860
+ const sibling = parent.children[i];
95861
+ // Check HTML siblings
95862
+ if (sibling.type === 'html') {
95863
+ const siblingValue = sibling.value || '';
95864
+ // Exact match (standalone closing tag)
95865
+ if (isClosingTag(siblingValue, tag)) {
95866
+ return { closingIndex: i, extraClosingChildren: [] };
95867
+ }
95868
+ // Embedded closing tag (closing tag within HTML block content)
95869
+ if (siblingValue.includes(closingTagStr)) {
95870
+ const closeTagPos = siblingValue.indexOf(closingTagStr);
95871
+ const contentBeforeClose = siblingValue.substring(0, closeTagPos).trim();
95872
+ const contentAfterClose = siblingValue.substring(closeTagPos + closingTagStr.length).trim();
95873
+ const extraChildren = contentBeforeClose
95874
+ ? parseMdChildren(contentBeforeClose)
95875
+ : [];
95876
+ return { closingIndex: i, extraClosingChildren: extraChildren, contentAfterClose: contentAfterClose || undefined };
95877
+ }
95878
+ }
95879
+ // Check paragraph siblings
95880
+ if (sibling.type === 'paragraph') {
95881
+ const { paragraph, found } = stripClosingTagFromParagraph(sibling, tag);
95882
+ if (found) {
95883
+ return { closingIndex: i, extraClosingChildren: [], strippedParagraph: paragraph };
95884
+ }
95885
+ }
95886
+ }
95887
+ if (i < parent.children.length) {
95888
+ // eslint-disable-next-line no-console
95889
+ console.warn(`Closing tag </${tag}> not found within ${MAX_LOOKAHEAD} siblings, stopping scan`);
95890
+ }
95891
+ return null;
95892
+ };
95893
+ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
95894
+ parent.children.splice(index, 1, mdxNode);
95895
+ };
95896
+ /**
95897
+ * Transform PascalCase HTML nodes into mdxJsxFlowElement nodes.
95898
+ *
95899
+ * Remark parses unknown/custom component tags as raw HTML nodes.
95900
+ * These are the custom readme MDX syntax for components.
95901
+ * This transformer identifies these patterns and converts them to proper MDX JSX elements so they
95902
+ * can be accurately recognized and rendered later with their component definition code.
95903
+ * Though for some tags, we need to handle them specially
95904
+ *
95905
+ * ## Supported HTML Structures
95906
+ *
95907
+ * ### 1. Self-closing tags
95908
+ * ```
95909
+ * <Component />
95910
+ * ```
95911
+ * Parsed as: `html: "<Component />"`
95912
+ *
95913
+ * ### 2. Self-contained blocks (entire component in single HTML node)
95914
+ * ```
95915
+ * <Button>Click me</Button>
95916
+ * ```
95917
+ * ```
95918
+ * <Component>
95919
+ * <h2>Title</h2>
95920
+ * <p>Content</p>
95921
+ * </Component>
95922
+ * ```
95923
+ * Parsed as: `html: "<Component>\n <h2>Title</h2>\n <p>Content</p>\n</Component>"`
95924
+ * The opening tag, content, and closing tag are all captured in one HTML node.
95925
+ *
95926
+ * ### 3. Multi-sibling components (closing tag in a following sibling)
95927
+ * Handles various structures where the closing tag is in a later sibling, such as:
95928
+ *
95929
+ * #### 3a. Block components (closing tag in sibling paragraph)
95930
+ * ```
95931
+ * <Callout>
95932
+ * Some **markdown** content
95933
+ * </Callout>
95934
+ * ```
95935
+ *
95936
+ * #### 3b. Multi-paragraph components (closing tag several siblings away)
95937
+ * ```
95938
+ * <Callout>
95939
+ *
95940
+ * First paragraph
95941
+ *
95942
+ * Second paragraph
95943
+ * </Callout>
95944
+ * ```
95945
+ *
95946
+ * #### 3c. Nested components split by blank lines (closing tag embedded in HTML sibling)
95947
+ * ```
95948
+ * <Outer>
95949
+ * <Inner>content</Inner>
95950
+ *
95951
+ * <Inner>content</Inner>
95952
+ * </Outer>
95953
+ * ```
95954
+ */
95955
+ const mdxishComponentBlocks = () => tree => {
95956
+ const stack = [tree];
95957
+ const processChildNode = (parent, index) => {
95958
+ const node = parent.children[index];
95959
+ if (!node)
95960
+ return;
95961
+ if ('children' in node && Array.isArray(node.children)) {
95962
+ stack.push(node);
95963
+ }
95964
+ // Only visit HTML nodes with an actual html tag,
95965
+ // which means a potential unparsed MDX component
95966
+ const value = node.value;
95967
+ if (node.type !== 'html' || typeof value !== 'string')
95968
+ return;
95969
+ const parsed = parseTag(value.trim());
95970
+ if (!parsed)
95971
+ return;
95972
+ const { tag, attributes, selfClosing, contentAfterTag = '' } = parsed;
95973
+ // Skip tags that have dedicated transformers
95974
+ if (EXCLUDED_TAGS.has(tag))
95975
+ return;
95976
+ const closingTagStr = `</${tag}>`;
95977
+ // Case 1: Self-closing tag
95978
+ if (selfClosing) {
95979
+ const componentNode = createComponentNode({
95980
+ tag,
95981
+ attributes,
95982
+ children: [],
95983
+ startPosition: node.position,
95984
+ });
95985
+ substituteNodeWithMdxNode(parent, index, componentNode);
95986
+ // Check and parse if there's relevant content after the current closing tag
95987
+ const remainingContent = contentAfterTag.trim();
95988
+ if (remainingContent) {
95989
+ parseSibling(stack, parent, index, remainingContent);
95990
+ }
95991
+ return;
95992
+ }
95993
+ // Case 2: Self-contained block (closing tag in content)
95994
+ if (contentAfterTag.includes(closingTagStr)) {
95995
+ // Find the first closing tag
95996
+ const closingTagIndex = contentAfterTag.indexOf(closingTagStr);
95997
+ const componentInnerContent = contentAfterTag.substring(0, closingTagIndex).trim();
95998
+ const contentAfterClose = contentAfterTag.substring(closingTagIndex + closingTagStr.length).trim();
95999
+ const componentNode = createComponentNode({
96000
+ tag,
96001
+ attributes,
96002
+ children: componentInnerContent ? parseMdChildren(componentInnerContent) : [],
96003
+ startPosition: node.position,
96004
+ });
96005
+ substituteNodeWithMdxNode(parent, index, componentNode);
96006
+ // After the closing tag, there might be more content to be processed
96007
+ if (contentAfterClose) {
96008
+ parseSibling(stack, parent, index, contentAfterClose);
96009
+ }
96010
+ else if (componentNode.children.length > 0) {
96011
+ // The content inside the component block might contain new components to be processed
96012
+ stack.push(componentNode);
96013
+ }
96014
+ return;
96015
+ }
96016
+ // Case 3: Multi-sibling component (closing tag in a following sibling)
96017
+ // Scans forward through siblings to find closing tag in HTML or paragraph nodes
96018
+ const scanResult = scanForClosingTag(parent, index, tag);
96019
+ if (!scanResult)
96020
+ return;
96021
+ const { closingIndex, extraClosingChildren, strippedParagraph, contentAfterClose: remainingAfterClose } = scanResult;
96022
+ const extraChildren = contentAfterTag ? parseMdChildren(contentAfterTag.trimStart()) : [];
96023
+ // Collect all intermediate siblings between opening tag and closing tag
96024
+ const intermediateChildren = parent.children.slice(index + 1, closingIndex);
96025
+ // For paragraph siblings, include the full paragraph (with closing tag stripped)
96026
+ // For HTML siblings, include any content parsed from before the closing tag
96027
+ const closingChildren = strippedParagraph
96028
+ ? (strippedParagraph.children.length > 0 ? [strippedParagraph] : [])
96029
+ : extraClosingChildren;
96030
+ const componentNode = createComponentNode({
96031
+ tag,
96032
+ attributes,
96033
+ children: [...extraChildren, ...intermediateChildren, ...closingChildren],
96034
+ startPosition: node.position,
96035
+ endPosition: parent.children[closingIndex]?.position,
96036
+ });
96037
+ // Remove all nodes from opening tag to closing tag (inclusive) and replace with component node
96038
+ parent.children.splice(index, closingIndex - index + 1, componentNode);
96039
+ // Since we might be merging sibling nodes together and combining content,
96040
+ // there might be new components to process
96041
+ if (componentNode.children.length > 0) {
96042
+ stack.push(componentNode);
96043
+ }
96044
+ // If the closing tag sibling had content after it (e.g., another component opening tag),
96045
+ // re-insert it as a sibling so it can be processed in subsequent iterations
96046
+ if (remainingAfterClose) {
96047
+ parseSibling(stack, parent, index, remainingAfterClose);
96048
+ }
96049
+ };
96050
+ // Process the nodes with the components depth-first to maintain the correct order of the nodes
96051
+ while (stack.length) {
96052
+ const parent = stack.pop();
96053
+ if (parent?.children) {
96054
+ parent.children.forEach((_child, index) => {
96055
+ processChildNode(parent, index);
96056
+ });
96057
+ }
96058
+ }
96059
+ return tree;
96060
+ };
96061
+ /* harmony default export */ const mdxish_component_blocks = (mdxishComponentBlocks);
96062
+
95983
96063
  ;// ./processor/transform/mdxish/mdxish-html-blocks.ts
95984
96064
 
95985
96065
 
@@ -96345,7 +96425,7 @@ const mdxishInlineComponents = () => tree => {
96345
96425
  if (!match)
96346
96426
  return;
96347
96427
  const [, name, attrStr] = match;
96348
- if (!INLINE_COMPONENT_TAGS.has(name))
96428
+ if (!constants_INLINE_COMPONENT_TAGS.has(name))
96349
96429
  return;
96350
96430
  // Parse attributes directly - preserves all attribute types (strings, booleans, objects, arrays)
96351
96431
  const attributes = parseAttributes(attrStr ?? '');
@@ -96373,6 +96453,7 @@ const mdxishInlineComponents = () => tree => {
96373
96453
 
96374
96454
 
96375
96455
 
96456
+
96376
96457
  const transformAnchor = (jsx) => {
96377
96458
  const attrs = getAttrs(jsx);
96378
96459
  const { href = '', label, target, title } = attrs;
@@ -96412,6 +96493,7 @@ const transformImage = (jsx) => {
96412
96493
  alt,
96413
96494
  border: border !== undefined ? String(border) : undefined,
96414
96495
  caption,
96496
+ children: caption ? lib_mdast(caption).children : [],
96415
96497
  className,
96416
96498
  height: height !== undefined ? String(height) : undefined,
96417
96499
  lazy,
@@ -96646,12 +96728,6 @@ const mdxishMermaidTransformer = () => (tree) => {
96646
96728
  };
96647
96729
  /* harmony default export */ const mdxish_mermaid = (mdxishMermaidTransformer);
96648
96730
 
96649
- ;// ./lib/constants.ts
96650
- /**
96651
- * Pattern to match component tags (PascalCase or snake_case)
96652
- */
96653
- const componentTagPattern = /<(\/?[A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>/g;
96654
-
96655
96731
  ;// ./processor/transform/mdxish/mdxish-snake-case-components.ts
96656
96732
 
96657
96733
 
@@ -97087,6 +97163,49 @@ const variablesTextTransformer = () => tree => {
97087
97163
  };
97088
97164
  /* harmony default export */ const variables_text = (variablesTextTransformer);
97089
97165
 
97166
+ ;// ./lib/mdast-util/jsx-table/index.ts
97167
+ const jsx_table_contextMap = new WeakMap();
97168
+ function findJsxTableToken() {
97169
+ const events = this.tokenStack;
97170
+ for (let i = events.length - 1; i >= 0; i -= 1) {
97171
+ if (events[i][0].type === 'jsxTable')
97172
+ return events[i][0];
97173
+ }
97174
+ return undefined;
97175
+ }
97176
+ function enterJsxTable(token) {
97177
+ jsx_table_contextMap.set(token, { chunks: [] });
97178
+ this.enter({ type: 'html', value: '' }, token);
97179
+ }
97180
+ function exitJsxTableData(token) {
97181
+ const tableToken = findJsxTableToken.call(this);
97182
+ if (!tableToken)
97183
+ return;
97184
+ const ctx = jsx_table_contextMap.get(tableToken);
97185
+ if (ctx)
97186
+ ctx.chunks.push(this.sliceSerialize(token));
97187
+ }
97188
+ function exitJsxTable(token) {
97189
+ const ctx = jsx_table_contextMap.get(token);
97190
+ const node = this.stack[this.stack.length - 1];
97191
+ if (ctx) {
97192
+ node.value = ctx.chunks.join('\n');
97193
+ jsx_table_contextMap.delete(token);
97194
+ }
97195
+ this.exit(token);
97196
+ }
97197
+ function jsxTableFromMarkdown() {
97198
+ return {
97199
+ enter: {
97200
+ jsxTable: enterJsxTable,
97201
+ },
97202
+ exit: {
97203
+ jsxTableData: exitJsxTableData,
97204
+ jsxTable: exitJsxTable,
97205
+ },
97206
+ };
97207
+ }
97208
+
97090
97209
  ;// ./lib/mdast-util/magic-block/index.ts
97091
97210
  const magic_block_contextMap = new WeakMap();
97092
97211
  /**
@@ -97243,6 +97362,685 @@ function magicBlockToMarkdown() {
97243
97362
  };
97244
97363
  }
97245
97364
 
97365
+ ;// ./node_modules/micromark-util-symbol/lib/types.js
97366
+ /**
97367
+ * This module is compiled away!
97368
+ *
97369
+ * Here is the list of all types of tokens exposed by micromark, with a short
97370
+ * explanation of what they include and where they are found.
97371
+ * In picking names, generally, the rule is to be as explicit as possible
97372
+ * instead of reusing names.
97373
+ * For example, there is a `definitionDestination` and a `resourceDestination`,
97374
+ * instead of one shared name.
97375
+ */
97376
+
97377
+ // Note: when changing the next record, you must also change `TokenTypeMap`
97378
+ // in `micromark-util-types/index.d.ts`.
97379
+ const types_types = /** @type {const} */ ({
97380
+ // Generic type for data, such as in a title, a destination, etc.
97381
+ data: 'data',
97382
+
97383
+ // Generic type for syntactic whitespace (tabs, virtual spaces, spaces).
97384
+ // Such as, between a fenced code fence and an info string.
97385
+ whitespace: 'whitespace',
97386
+
97387
+ // Generic type for line endings (line feed, carriage return, carriage return +
97388
+ // line feed).
97389
+ lineEnding: 'lineEnding',
97390
+
97391
+ // A line ending, but ending a blank line.
97392
+ lineEndingBlank: 'lineEndingBlank',
97393
+
97394
+ // Generic type for whitespace (tabs, virtual spaces, spaces) at the start of a
97395
+ // line.
97396
+ linePrefix: 'linePrefix',
97397
+
97398
+ // Generic type for whitespace (tabs, virtual spaces, spaces) at the end of a
97399
+ // line.
97400
+ lineSuffix: 'lineSuffix',
97401
+
97402
+ // Whole ATX heading:
97403
+ //
97404
+ // ```markdown
97405
+ // #
97406
+ // ## Alpha
97407
+ // ### Bravo ###
97408
+ // ```
97409
+ //
97410
+ // Includes `atxHeadingSequence`, `whitespace`, `atxHeadingText`.
97411
+ atxHeading: 'atxHeading',
97412
+
97413
+ // Sequence of number signs in an ATX heading (`###`).
97414
+ atxHeadingSequence: 'atxHeadingSequence',
97415
+
97416
+ // Content in an ATX heading (`alpha`).
97417
+ // Includes text.
97418
+ atxHeadingText: 'atxHeadingText',
97419
+
97420
+ // Whole autolink (`<https://example.com>` or `<admin@example.com>`)
97421
+ // Includes `autolinkMarker` and `autolinkProtocol` or `autolinkEmail`.
97422
+ autolink: 'autolink',
97423
+
97424
+ // Email autolink w/o markers (`admin@example.com`)
97425
+ autolinkEmail: 'autolinkEmail',
97426
+
97427
+ // Marker around an `autolinkProtocol` or `autolinkEmail` (`<` or `>`).
97428
+ autolinkMarker: 'autolinkMarker',
97429
+
97430
+ // Protocol autolink w/o markers (`https://example.com`)
97431
+ autolinkProtocol: 'autolinkProtocol',
97432
+
97433
+ // A whole character escape (`\-`).
97434
+ // Includes `escapeMarker` and `characterEscapeValue`.
97435
+ characterEscape: 'characterEscape',
97436
+
97437
+ // The escaped character (`-`).
97438
+ characterEscapeValue: 'characterEscapeValue',
97439
+
97440
+ // A whole character reference (`&amp;`, `&#8800;`, or `&#x1D306;`).
97441
+ // Includes `characterReferenceMarker`, an optional
97442
+ // `characterReferenceMarkerNumeric`, in which case an optional
97443
+ // `characterReferenceMarkerHexadecimal`, and a `characterReferenceValue`.
97444
+ characterReference: 'characterReference',
97445
+
97446
+ // The start or end marker (`&` or `;`).
97447
+ characterReferenceMarker: 'characterReferenceMarker',
97448
+
97449
+ // Mark reference as numeric (`#`).
97450
+ characterReferenceMarkerNumeric: 'characterReferenceMarkerNumeric',
97451
+
97452
+ // Mark reference as numeric (`x` or `X`).
97453
+ characterReferenceMarkerHexadecimal: 'characterReferenceMarkerHexadecimal',
97454
+
97455
+ // Value of character reference w/o markers (`amp`, `8800`, or `1D306`).
97456
+ characterReferenceValue: 'characterReferenceValue',
97457
+
97458
+ // Whole fenced code:
97459
+ //
97460
+ // ````markdown
97461
+ // ```js
97462
+ // alert(1)
97463
+ // ```
97464
+ // ````
97465
+ codeFenced: 'codeFenced',
97466
+
97467
+ // A fenced code fence, including whitespace, sequence, info, and meta
97468
+ // (` ```js `).
97469
+ codeFencedFence: 'codeFencedFence',
97470
+
97471
+ // Sequence of grave accent or tilde characters (` ``` `) in a fence.
97472
+ codeFencedFenceSequence: 'codeFencedFenceSequence',
97473
+
97474
+ // Info word (`js`) in a fence.
97475
+ // Includes string.
97476
+ codeFencedFenceInfo: 'codeFencedFenceInfo',
97477
+
97478
+ // Meta words (`highlight="1"`) in a fence.
97479
+ // Includes string.
97480
+ codeFencedFenceMeta: 'codeFencedFenceMeta',
97481
+
97482
+ // A line of code.
97483
+ codeFlowValue: 'codeFlowValue',
97484
+
97485
+ // Whole indented code:
97486
+ //
97487
+ // ```markdown
97488
+ // alert(1)
97489
+ // ```
97490
+ //
97491
+ // Includes `lineEnding`, `linePrefix`, and `codeFlowValue`.
97492
+ codeIndented: 'codeIndented',
97493
+
97494
+ // A text code (``` `alpha` ```).
97495
+ // Includes `codeTextSequence`, `codeTextData`, `lineEnding`, and can include
97496
+ // `codeTextPadding`.
97497
+ codeText: 'codeText',
97498
+
97499
+ codeTextData: 'codeTextData',
97500
+
97501
+ // A space or line ending right after or before a tick.
97502
+ codeTextPadding: 'codeTextPadding',
97503
+
97504
+ // A text code fence (` `` `).
97505
+ codeTextSequence: 'codeTextSequence',
97506
+
97507
+ // Whole content:
97508
+ //
97509
+ // ```markdown
97510
+ // [a]: b
97511
+ // c
97512
+ // =
97513
+ // d
97514
+ // ```
97515
+ //
97516
+ // Includes `paragraph` and `definition`.
97517
+ content: 'content',
97518
+ // Whole definition:
97519
+ //
97520
+ // ```markdown
97521
+ // [micromark]: https://github.com/micromark/micromark
97522
+ // ```
97523
+ //
97524
+ // Includes `definitionLabel`, `definitionMarker`, `whitespace`,
97525
+ // `definitionDestination`, and optionally `lineEnding` and `definitionTitle`.
97526
+ definition: 'definition',
97527
+
97528
+ // Destination of a definition (`https://github.com/micromark/micromark` or
97529
+ // `<https://github.com/micromark/micromark>`).
97530
+ // Includes `definitionDestinationLiteral` or `definitionDestinationRaw`.
97531
+ definitionDestination: 'definitionDestination',
97532
+
97533
+ // Enclosed destination of a definition
97534
+ // (`<https://github.com/micromark/micromark>`).
97535
+ // Includes `definitionDestinationLiteralMarker` and optionally
97536
+ // `definitionDestinationString`.
97537
+ definitionDestinationLiteral: 'definitionDestinationLiteral',
97538
+
97539
+ // Markers of an enclosed definition destination (`<` or `>`).
97540
+ definitionDestinationLiteralMarker: 'definitionDestinationLiteralMarker',
97541
+
97542
+ // Unenclosed destination of a definition
97543
+ // (`https://github.com/micromark/micromark`).
97544
+ // Includes `definitionDestinationString`.
97545
+ definitionDestinationRaw: 'definitionDestinationRaw',
97546
+
97547
+ // Text in an destination (`https://github.com/micromark/micromark`).
97548
+ // Includes string.
97549
+ definitionDestinationString: 'definitionDestinationString',
97550
+
97551
+ // Label of a definition (`[micromark]`).
97552
+ // Includes `definitionLabelMarker` and `definitionLabelString`.
97553
+ definitionLabel: 'definitionLabel',
97554
+
97555
+ // Markers of a definition label (`[` or `]`).
97556
+ definitionLabelMarker: 'definitionLabelMarker',
97557
+
97558
+ // Value of a definition label (`micromark`).
97559
+ // Includes string.
97560
+ definitionLabelString: 'definitionLabelString',
97561
+
97562
+ // Marker between a label and a destination (`:`).
97563
+ definitionMarker: 'definitionMarker',
97564
+
97565
+ // Title of a definition (`"x"`, `'y'`, or `(z)`).
97566
+ // Includes `definitionTitleMarker` and optionally `definitionTitleString`.
97567
+ definitionTitle: 'definitionTitle',
97568
+
97569
+ // Marker around a title of a definition (`"`, `'`, `(`, or `)`).
97570
+ definitionTitleMarker: 'definitionTitleMarker',
97571
+
97572
+ // Data without markers in a title (`z`).
97573
+ // Includes string.
97574
+ definitionTitleString: 'definitionTitleString',
97575
+
97576
+ // Emphasis (`*alpha*`).
97577
+ // Includes `emphasisSequence` and `emphasisText`.
97578
+ emphasis: 'emphasis',
97579
+
97580
+ // Sequence of emphasis markers (`*` or `_`).
97581
+ emphasisSequence: 'emphasisSequence',
97582
+
97583
+ // Emphasis text (`alpha`).
97584
+ // Includes text.
97585
+ emphasisText: 'emphasisText',
97586
+
97587
+ // The character escape marker (`\`).
97588
+ escapeMarker: 'escapeMarker',
97589
+
97590
+ // A hard break created with a backslash (`\\n`).
97591
+ // Note: does not include the line ending.
97592
+ hardBreakEscape: 'hardBreakEscape',
97593
+
97594
+ // A hard break created with trailing spaces (` \n`).
97595
+ // Does not include the line ending.
97596
+ hardBreakTrailing: 'hardBreakTrailing',
97597
+
97598
+ // Flow HTML:
97599
+ //
97600
+ // ```markdown
97601
+ // <div
97602
+ // ```
97603
+ //
97604
+ // Inlcudes `lineEnding`, `htmlFlowData`.
97605
+ htmlFlow: 'htmlFlow',
97606
+
97607
+ htmlFlowData: 'htmlFlowData',
97608
+
97609
+ // HTML in text (the tag in `a <i> b`).
97610
+ // Includes `lineEnding`, `htmlTextData`.
97611
+ htmlText: 'htmlText',
97612
+
97613
+ htmlTextData: 'htmlTextData',
97614
+
97615
+ // Whole image (`![alpha](bravo)`, `![alpha][bravo]`, `![alpha][]`, or
97616
+ // `![alpha]`).
97617
+ // Includes `label` and an optional `resource` or `reference`.
97618
+ image: 'image',
97619
+
97620
+ // Whole link label (`[*alpha*]`).
97621
+ // Includes `labelLink` or `labelImage`, `labelText`, and `labelEnd`.
97622
+ label: 'label',
97623
+
97624
+ // Text in an label (`*alpha*`).
97625
+ // Includes text.
97626
+ labelText: 'labelText',
97627
+
97628
+ // Start a link label (`[`).
97629
+ // Includes a `labelMarker`.
97630
+ labelLink: 'labelLink',
97631
+
97632
+ // Start an image label (`![`).
97633
+ // Includes `labelImageMarker` and `labelMarker`.
97634
+ labelImage: 'labelImage',
97635
+
97636
+ // Marker of a label (`[` or `]`).
97637
+ labelMarker: 'labelMarker',
97638
+
97639
+ // Marker to start an image (`!`).
97640
+ labelImageMarker: 'labelImageMarker',
97641
+
97642
+ // End a label (`]`).
97643
+ // Includes `labelMarker`.
97644
+ labelEnd: 'labelEnd',
97645
+
97646
+ // Whole link (`[alpha](bravo)`, `[alpha][bravo]`, `[alpha][]`, or `[alpha]`).
97647
+ // Includes `label` and an optional `resource` or `reference`.
97648
+ link: 'link',
97649
+
97650
+ // Whole paragraph:
97651
+ //
97652
+ // ```markdown
97653
+ // alpha
97654
+ // bravo.
97655
+ // ```
97656
+ //
97657
+ // Includes text.
97658
+ paragraph: 'paragraph',
97659
+
97660
+ // A reference (`[alpha]` or `[]`).
97661
+ // Includes `referenceMarker` and an optional `referenceString`.
97662
+ reference: 'reference',
97663
+
97664
+ // A reference marker (`[` or `]`).
97665
+ referenceMarker: 'referenceMarker',
97666
+
97667
+ // Reference text (`alpha`).
97668
+ // Includes string.
97669
+ referenceString: 'referenceString',
97670
+
97671
+ // A resource (`(https://example.com "alpha")`).
97672
+ // Includes `resourceMarker`, an optional `resourceDestination` with an optional
97673
+ // `whitespace` and `resourceTitle`.
97674
+ resource: 'resource',
97675
+
97676
+ // A resource destination (`https://example.com`).
97677
+ // Includes `resourceDestinationLiteral` or `resourceDestinationRaw`.
97678
+ resourceDestination: 'resourceDestination',
97679
+
97680
+ // A literal resource destination (`<https://example.com>`).
97681
+ // Includes `resourceDestinationLiteralMarker` and optionally
97682
+ // `resourceDestinationString`.
97683
+ resourceDestinationLiteral: 'resourceDestinationLiteral',
97684
+
97685
+ // A resource destination marker (`<` or `>`).
97686
+ resourceDestinationLiteralMarker: 'resourceDestinationLiteralMarker',
97687
+
97688
+ // A raw resource destination (`https://example.com`).
97689
+ // Includes `resourceDestinationString`.
97690
+ resourceDestinationRaw: 'resourceDestinationRaw',
97691
+
97692
+ // Resource destination text (`https://example.com`).
97693
+ // Includes string.
97694
+ resourceDestinationString: 'resourceDestinationString',
97695
+
97696
+ // A resource marker (`(` or `)`).
97697
+ resourceMarker: 'resourceMarker',
97698
+
97699
+ // A resource title (`"alpha"`, `'alpha'`, or `(alpha)`).
97700
+ // Includes `resourceTitleMarker` and optionally `resourceTitleString`.
97701
+ resourceTitle: 'resourceTitle',
97702
+
97703
+ // A resource title marker (`"`, `'`, `(`, or `)`).
97704
+ resourceTitleMarker: 'resourceTitleMarker',
97705
+
97706
+ // Resource destination title (`alpha`).
97707
+ // Includes string.
97708
+ resourceTitleString: 'resourceTitleString',
97709
+
97710
+ // Whole setext heading:
97711
+ //
97712
+ // ```markdown
97713
+ // alpha
97714
+ // bravo
97715
+ // =====
97716
+ // ```
97717
+ //
97718
+ // Includes `setextHeadingText`, `lineEnding`, `linePrefix`, and
97719
+ // `setextHeadingLine`.
97720
+ setextHeading: 'setextHeading',
97721
+
97722
+ // Content in a setext heading (`alpha\nbravo`).
97723
+ // Includes text.
97724
+ setextHeadingText: 'setextHeadingText',
97725
+
97726
+ // Underline in a setext heading, including whitespace suffix (`==`).
97727
+ // Includes `setextHeadingLineSequence`.
97728
+ setextHeadingLine: 'setextHeadingLine',
97729
+
97730
+ // Sequence of equals or dash characters in underline in a setext heading (`-`).
97731
+ setextHeadingLineSequence: 'setextHeadingLineSequence',
97732
+
97733
+ // Strong (`**alpha**`).
97734
+ // Includes `strongSequence` and `strongText`.
97735
+ strong: 'strong',
97736
+
97737
+ // Sequence of strong markers (`**` or `__`).
97738
+ strongSequence: 'strongSequence',
97739
+
97740
+ // Strong text (`alpha`).
97741
+ // Includes text.
97742
+ strongText: 'strongText',
97743
+
97744
+ // Whole thematic break:
97745
+ //
97746
+ // ```markdown
97747
+ // * * *
97748
+ // ```
97749
+ //
97750
+ // Includes `thematicBreakSequence` and `whitespace`.
97751
+ thematicBreak: 'thematicBreak',
97752
+
97753
+ // A sequence of one or more thematic break markers (`***`).
97754
+ thematicBreakSequence: 'thematicBreakSequence',
97755
+
97756
+ // Whole block quote:
97757
+ //
97758
+ // ```markdown
97759
+ // > a
97760
+ // >
97761
+ // > b
97762
+ // ```
97763
+ //
97764
+ // Includes `blockQuotePrefix` and flow.
97765
+ blockQuote: 'blockQuote',
97766
+ // The `>` or `> ` of a block quote.
97767
+ blockQuotePrefix: 'blockQuotePrefix',
97768
+ // The `>` of a block quote prefix.
97769
+ blockQuoteMarker: 'blockQuoteMarker',
97770
+ // The optional ` ` of a block quote prefix.
97771
+ blockQuotePrefixWhitespace: 'blockQuotePrefixWhitespace',
97772
+
97773
+ // Whole ordered list:
97774
+ //
97775
+ // ```markdown
97776
+ // 1. a
97777
+ // b
97778
+ // ```
97779
+ //
97780
+ // Includes `listItemPrefix`, flow, and optionally `listItemIndent` on further
97781
+ // lines.
97782
+ listOrdered: 'listOrdered',
97783
+
97784
+ // Whole unordered list:
97785
+ //
97786
+ // ```markdown
97787
+ // - a
97788
+ // b
97789
+ // ```
97790
+ //
97791
+ // Includes `listItemPrefix`, flow, and optionally `listItemIndent` on further
97792
+ // lines.
97793
+ listUnordered: 'listUnordered',
97794
+
97795
+ // The indent of further list item lines.
97796
+ listItemIndent: 'listItemIndent',
97797
+
97798
+ // A marker, as in, `*`, `+`, `-`, `.`, or `)`.
97799
+ listItemMarker: 'listItemMarker',
97800
+
97801
+ // The thing that starts a list item, such as `1. `.
97802
+ // Includes `listItemValue` if ordered, `listItemMarker`, and
97803
+ // `listItemPrefixWhitespace` (unless followed by a line ending).
97804
+ listItemPrefix: 'listItemPrefix',
97805
+
97806
+ // The whitespace after a marker.
97807
+ listItemPrefixWhitespace: 'listItemPrefixWhitespace',
97808
+
97809
+ // The numerical value of an ordered item.
97810
+ listItemValue: 'listItemValue',
97811
+
97812
+ // Internal types used for subtokenizers, compiled away
97813
+ chunkDocument: 'chunkDocument',
97814
+ chunkContent: 'chunkContent',
97815
+ chunkFlow: 'chunkFlow',
97816
+ chunkText: 'chunkText',
97817
+ chunkString: 'chunkString'
97818
+ })
97819
+
97820
+ ;// ./lib/micromark/jsx-table/syntax.ts
97821
+
97822
+
97823
+ const syntax_nonLazyContinuationStart = {
97824
+ tokenize: syntax_tokenizeNonLazyContinuationStart,
97825
+ partial: true,
97826
+ };
97827
+ function resolveToJsxTable(events) {
97828
+ let index = events.length;
97829
+ while (index > 0) {
97830
+ index -= 1;
97831
+ if (events[index][0] === 'enter' && events[index][1].type === 'jsxTable') {
97832
+ break;
97833
+ }
97834
+ }
97835
+ if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
97836
+ events[index][1].start = events[index - 2][1].start;
97837
+ events[index + 1][1].start = events[index - 2][1].start;
97838
+ events.splice(index - 2, 2);
97839
+ }
97840
+ return events;
97841
+ }
97842
+ const jsxTableConstruct = {
97843
+ name: 'jsxTable',
97844
+ tokenize: tokenizeJsxTable,
97845
+ resolveTo: resolveToJsxTable,
97846
+ concrete: true,
97847
+ };
97848
+ function tokenizeJsxTable(effects, ok, nok) {
97849
+ let codeSpanOpenSize = 0;
97850
+ let codeSpanCloseSize = 0;
97851
+ let depth = 1;
97852
+ const TABLE_NAME = [codes.uppercaseT, codes.lowercaseA, codes.lowercaseB, codes.lowercaseL, codes.lowercaseE];
97853
+ const ABLE_SUFFIX = TABLE_NAME.slice(1);
97854
+ /** Build a state chain that matches a sequence of character codes. */
97855
+ function matchChars(chars, onMatch, onFail) {
97856
+ if (chars.length === 0)
97857
+ return onMatch;
97858
+ return ((code) => {
97859
+ if (code === chars[0]) {
97860
+ effects.consume(code);
97861
+ return matchChars(chars.slice(1), onMatch, onFail);
97862
+ }
97863
+ return onFail(code);
97864
+ });
97865
+ }
97866
+ return start;
97867
+ function start(code) {
97868
+ if (code !== codes.lessThan)
97869
+ return nok(code);
97870
+ effects.enter('jsxTable');
97871
+ effects.enter('jsxTableData');
97872
+ effects.consume(code);
97873
+ return matchChars(TABLE_NAME, afterTagName, nok);
97874
+ }
97875
+ function afterTagName(code) {
97876
+ if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
97877
+ effects.consume(code);
97878
+ return body;
97879
+ }
97880
+ return nok(code);
97881
+ }
97882
+ function body(code) {
97883
+ // Reject unclosed <Table> so it falls back to normal HTML block parsing
97884
+ // instead of swallowing all subsequent content to EOF
97885
+ if (code === null) {
97886
+ return nok(code);
97887
+ }
97888
+ if (markdownLineEnding(code)) {
97889
+ effects.exit('jsxTableData');
97890
+ return continuationStart(code);
97891
+ }
97892
+ if (code === codes.backslash) {
97893
+ effects.consume(code);
97894
+ return escapedChar;
97895
+ }
97896
+ if (code === codes.lessThan) {
97897
+ effects.consume(code);
97898
+ return closeSlash;
97899
+ }
97900
+ // Skip over backtick code spans so `</Table>` in inline code isn't
97901
+ // treated as the closing tag
97902
+ if (code === codes.graveAccent) {
97903
+ codeSpanOpenSize = 0;
97904
+ return countOpenTicks(code);
97905
+ }
97906
+ effects.consume(code);
97907
+ return body;
97908
+ }
97909
+ function countOpenTicks(code) {
97910
+ if (code === codes.graveAccent) {
97911
+ codeSpanOpenSize += 1;
97912
+ effects.consume(code);
97913
+ return countOpenTicks;
97914
+ }
97915
+ return inCodeSpan(code);
97916
+ }
97917
+ function inCodeSpan(code) {
97918
+ if (code === null || markdownLineEnding(code))
97919
+ return body(code);
97920
+ if (code === codes.graveAccent) {
97921
+ codeSpanCloseSize = 0;
97922
+ return countCloseTicks(code);
97923
+ }
97924
+ effects.consume(code);
97925
+ return inCodeSpan;
97926
+ }
97927
+ function countCloseTicks(code) {
97928
+ if (code === codes.graveAccent) {
97929
+ codeSpanCloseSize += 1;
97930
+ effects.consume(code);
97931
+ return countCloseTicks;
97932
+ }
97933
+ return codeSpanCloseSize === codeSpanOpenSize ? body(code) : inCodeSpan(code);
97934
+ }
97935
+ function escapedChar(code) {
97936
+ if (code === null || markdownLineEnding(code)) {
97937
+ return body(code);
97938
+ }
97939
+ effects.consume(code);
97940
+ return body;
97941
+ }
97942
+ function closeSlash(code) {
97943
+ if (code === codes.slash) {
97944
+ effects.consume(code);
97945
+ return matchChars(TABLE_NAME, closeGt, body);
97946
+ }
97947
+ if (code === codes.uppercaseT) {
97948
+ effects.consume(code);
97949
+ return matchChars(ABLE_SUFFIX, openAfterTagName, body);
97950
+ }
97951
+ return body(code);
97952
+ }
97953
+ function openAfterTagName(code) {
97954
+ if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
97955
+ depth += 1;
97956
+ effects.consume(code);
97957
+ return body;
97958
+ }
97959
+ return body(code);
97960
+ }
97961
+ function closeGt(code) {
97962
+ if (code === codes.greaterThan) {
97963
+ depth -= 1;
97964
+ effects.consume(code);
97965
+ if (depth === 0) {
97966
+ return afterClose;
97967
+ }
97968
+ return body;
97969
+ }
97970
+ return body(code);
97971
+ }
97972
+ function afterClose(code) {
97973
+ if (code === null || markdownLineEnding(code)) {
97974
+ effects.exit('jsxTableData');
97975
+ effects.exit('jsxTable');
97976
+ return ok(code);
97977
+ }
97978
+ effects.consume(code);
97979
+ return afterClose;
97980
+ }
97981
+ // Line ending handling — follows the htmlFlow pattern
97982
+ function continuationStart(code) {
97983
+ return effects.check(syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
97984
+ }
97985
+ function continuationStartNonLazy(code) {
97986
+ effects.enter(types_types.lineEnding);
97987
+ effects.consume(code);
97988
+ effects.exit(types_types.lineEnding);
97989
+ return continuationBefore;
97990
+ }
97991
+ function continuationBefore(code) {
97992
+ if (code === null || markdownLineEnding(code)) {
97993
+ return continuationStart(code);
97994
+ }
97995
+ effects.enter('jsxTableData');
97996
+ return body(code);
97997
+ }
97998
+ function continuationAfter(code) {
97999
+ // At EOF without </Table>, reject so content isn't swallowed
98000
+ if (code === null) {
98001
+ return nok(code);
98002
+ }
98003
+ effects.exit('jsxTable');
98004
+ return ok(code);
98005
+ }
98006
+ }
98007
+ function syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
98008
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
98009
+ const self = this;
98010
+ return start;
98011
+ function start(code) {
98012
+ if (markdownLineEnding(code)) {
98013
+ effects.enter(types_types.lineEnding);
98014
+ effects.consume(code);
98015
+ effects.exit(types_types.lineEnding);
98016
+ return after;
98017
+ }
98018
+ return nok(code);
98019
+ }
98020
+ function after(code) {
98021
+ if (self.parser.lazy[self.now().line]) {
98022
+ return nok(code);
98023
+ }
98024
+ return ok(code);
98025
+ }
98026
+ }
98027
+ /**
98028
+ * Micromark extension that tokenizes `<Table>...</Table>` as a single flow block.
98029
+ *
98030
+ * Prevents CommonMark HTML block type 6 from matching `<Table>` (case-insensitive
98031
+ * match against `table`) and fragmenting it at blank lines.
98032
+ */
98033
+ function jsxTable() {
98034
+ return {
98035
+ flow: {
98036
+ [codes.lessThan]: [jsxTableConstruct],
98037
+ },
98038
+ };
98039
+ }
98040
+
98041
+ ;// ./lib/micromark/jsx-table/index.ts
98042
+
98043
+
97246
98044
  ;// ./lib/micromark/magic-block/syntax.ts
97247
98045
 
97248
98046
 
@@ -98171,6 +98969,8 @@ function loadComponents() {
98171
98969
 
98172
98970
 
98173
98971
 
98972
+
98973
+
98174
98974
 
98175
98975
 
98176
98976
 
@@ -98218,11 +99018,11 @@ function mdxishAstProcessor(mdContent, opts = {}) {
98218
99018
  };
98219
99019
  const processor = unified()
98220
99020
  .data('micromarkExtensions', safeMode
98221
- ? [magicBlock(), legacyVariable(), looseHtmlEntity()]
98222
- : [magicBlock(), mdxExprTextOnly, legacyVariable(), looseHtmlEntity()])
99021
+ ? [jsxTable(), magicBlock(), legacyVariable(), looseHtmlEntity()]
99022
+ : [jsxTable(), magicBlock(), mdxExprTextOnly, legacyVariable(), looseHtmlEntity()])
98223
99023
  .data('fromMarkdownExtensions', safeMode
98224
- ? [magicBlockFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()]
98225
- : [magicBlockFromMarkdown(), mdxExpressionFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
99024
+ ? [jsxTableFromMarkdown(), magicBlockFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()]
99025
+ : [jsxTableFromMarkdown(), magicBlockFromMarkdown(), mdxExpressionFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
98226
99026
  .use(remarkParse)
98227
99027
  .use(remarkFrontmatter)
98228
99028
  .use(normalize_malformed_md_syntax)
@@ -98842,6 +99642,8 @@ function restoreMagicBlocks(replaced, blocks) {
98842
99642
 
98843
99643
 
98844
99644
 
99645
+
99646
+
98845
99647
  /**
98846
99648
  * Removes Markdown and MDX comments.
98847
99649
  */
@@ -98853,8 +99655,8 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
98853
99655
  // 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
98854
99656
  if (mdxish) {
98855
99657
  processor
98856
- .data('micromarkExtensions', [mdxExpression({ allowEmpty: true })])
98857
- .data('fromMarkdownExtensions', [mdxExpressionFromMarkdown()])
99658
+ .data('micromarkExtensions', [jsxTable(), mdxExpression({ allowEmpty: true })])
99659
+ .data('fromMarkdownExtensions', [jsxTableFromMarkdown(), mdxExpressionFromMarkdown()])
98858
99660
  .data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
98859
99661
  }
98860
99662
  processor