@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.node.js CHANGED
@@ -19019,6 +19019,7 @@ __webpack_require__.r(__webpack_exports__);
19019
19019
  // EXPORTS
19020
19020
  __webpack_require__.d(__webpack_exports__, {
19021
19021
  Components: () => (/* reexport */ components_namespaceObject),
19022
+ FLOW_TYPES: () => (/* reexport */ FLOW_TYPES),
19022
19023
  Owlmoji: () => (/* reexport */ Owlmoji),
19023
19024
  compile: () => (/* reexport */ lib_compile),
19024
19025
  exports: () => (/* reexport */ lib_exports),
@@ -25091,6 +25092,28 @@ const parseOptions = (userOpts = {}) => {
25091
25092
  return opts;
25092
25093
  };
25093
25094
 
25095
+ ;// ./lib/constants.ts
25096
+ /**
25097
+ * Pattern to match component tags (PascalCase or snake_case)
25098
+ */
25099
+ const componentTagPattern = /<(\/?[A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>/g;
25100
+ /**
25101
+ * MDAST flow (block-level) content types that cannot be represented
25102
+ * inside GFM table cells. Used to decide whether a table should be
25103
+ * serialized as GFM or as JSX `<Table>` syntax.
25104
+ *
25105
+ * @see https://github.com/syntax-tree/mdast#flowcontent
25106
+ */
25107
+ const FLOW_TYPES = new Set([
25108
+ 'blockquote',
25109
+ 'code',
25110
+ 'heading',
25111
+ 'html',
25112
+ 'list',
25113
+ 'table',
25114
+ 'thematicBreak',
25115
+ ]);
25116
+
25094
25117
  ;// ./node_modules/github-slugger/regex.js
25095
25118
  // This module is generated by `script/`.
25096
25119
  /* eslint-disable no-control-regex, no-misleading-character-class, no-useless-escape */
@@ -73196,17 +73219,22 @@ function plain_one(node, opts) {
73196
73219
  function plain_all(node, opts) {
73197
73220
  let index = -1;
73198
73221
  const result = [];
73222
+ const separator = opts.separator ?? ' ';
73199
73223
  // eslint-disable-next-line no-plusplus
73200
73224
  while (++index < node?.children.length) {
73201
73225
  result[index] = plain_one(node.children[index], opts);
73202
73226
  }
73203
- return result.join(' ').replaceAll(/\s+/g, ' ').trim();
73227
+ return result.join(separator).replaceAll(/\s+/g, ' ').trim();
73204
73228
  }
73205
73229
  const plain = (node, opts = {}) => {
73206
73230
  return 'children' in node ? plain_all(node, opts) || plain_one(node, opts) : plain_one(node, opts);
73207
73231
  };
73208
73232
  /* harmony default export */ const lib_plain = (plain);
73209
73233
 
73234
+ ;// ./processor/compile/variable.ts
73235
+ const variable = (node) => `{user.${node.data?.hProperties?.name || ''}}`;
73236
+ /* harmony default export */ const compile_variable = (variable);
73237
+
73210
73238
  ;// ./processor/transform/extract-text.ts
73211
73239
  /**
73212
73240
  * Extracts text content from a single AST node recursively.
@@ -73218,7 +73246,7 @@ const plain = (node, opts = {}) => {
73218
73246
  * @returns The concatenated text content
73219
73247
  */
73220
73248
  const extractText = (node) => {
73221
- if (node.type === 'text' && typeof node.value === 'string') {
73249
+ if ((node.type === 'text' || node.type === 'html') && typeof node.value === 'string') {
73222
73250
  return node.value;
73223
73251
  }
73224
73252
  // When a blockquote contains only an image (no text), treat it as having content
@@ -73251,8 +73279,18 @@ const extractText = (node) => {
73251
73279
 
73252
73280
 
73253
73281
 
73282
+
73283
+
73254
73284
  const titleParser = unified().use(remarkParse).use(remarkGfm);
73255
- const toMarkdownExtensions = [gfmStrikethroughToMarkdown()];
73285
+ // The title paragraph may contain custom AST nodes that `toMarkdown` doesn't
73286
+ // natively understand
73287
+ const toMarkdownExtensions = [
73288
+ gfmStrikethroughToMarkdown(),
73289
+ // For mdx variable syntaxes (e.g., {user.name})
73290
+ mdxExpressionToMarkdown(),
73291
+ // Important: This is required and would crash the parser if there's no variable node handler
73292
+ { handlers: { [NodeTypes.variable]: compile_variable } },
73293
+ ];
73256
73294
  const callouts_regex = `^(${emoji_regex().source}|⚠)(\\s+|$)`;
73257
73295
  const findFirst = (node) => {
73258
73296
  if ('children' in node)
@@ -91073,693 +91111,348 @@ const mdxToHast = () => tree => {
91073
91111
  };
91074
91112
  /* harmony default export */ const mdx_to_hast = (mdxToHast);
91075
91113
 
91076
- ;// ./lib/mdast-util/empty-task-list-item/index.ts
91114
+ ;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
91115
+
91116
+ // Marker patterns for multi-node emphasis detection
91117
+ const MARKER_PATTERNS = [
91118
+ { isBold: true, marker: '**' },
91119
+ { isBold: true, marker: '__' },
91120
+ { isBold: false, marker: '*' },
91121
+ { isBold: false, marker: '_' },
91122
+ ];
91123
+ // Patterns to detect for bold (** and __) and italic (* and _) syntax:
91124
+ // Bold: ** text**, **text **, word** text**, ** text **
91125
+ // Italic: * text*, *text *, word* text*, * text *
91126
+ // Same patterns for underscore variants
91127
+ // We use separate patterns for each marker type to allow this flexibility.
91128
+ // Pattern for ** bold **
91129
+ // Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
91130
+ // trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
91131
+ const asteriskBoldRegex = /([^*\s]+)?\s*(\*\*)(?:\s+((?:[^*\n]|\*(?!\*))+?)(\s*)\2|((?:[^*\n]|\*(?!\*))+?)(\s+)\2)(\S|$)?/g;
91132
+ // Pattern for __ bold __
91133
+ const underscoreBoldRegex = /([^_\s]+)?\s*(__)(?:\s+((?:__(?! )|_(?!_)|[^_\n])+?)(\s*)\2|((?:__(?! )|_(?!_)|[^_\n])+?)(\s+)\2)(\S|$)?/g;
91134
+ // Pattern for * italic *
91135
+ const asteriskItalicRegex = /([^*\s]+)?\s*(\*)(?!\*)(?:\s+([^*\n]+?)(\s*)\2|([^*\n]+?)(\s+)\2)(\S|$)?/g;
91136
+ // Pattern for _ italic _
91137
+ const underscoreItalicRegex = /([^_\s]+)?\s*(_)(?!_)(?:\s+((?:[^_\n]|_(?! ))+?)(\s*)\2|((?:[^_\n]|_(?! ))+?)(\s+)\2)(\S|$)?/g;
91138
+ // CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
91139
+ // Pattern for intraword _word_ in words like hello_world_
91140
+ const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
91141
+ // Pattern for intraword __word__ in words like hello__world__
91142
+ const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
91143
+ // Pattern for intraword *word* in words like hello*world*
91144
+ const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
91145
+ // Pattern for intraword **word** in words like hello**world**
91146
+ const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
91077
91147
  /**
91078
- * Normalizes list items that are written as only `[ ]` or `[x]` into GFM task
91079
- * list items during parse, but only when at least one whitespace character
91080
- * follows the closing bracket (`]`). This matches legacy behaviour for checkboxes
91081
- *
91082
- * The issue is `remark-gfm` does not actually classify these as task items when they have no content
91083
- * after the checkbox, which leaves them as plain text (`"[ ]"`). So a custom extension is needed to
91084
- * treat these as task items
91148
+ * Finds opening emphasis marker in a text value.
91149
+ * Returns marker info if found, null otherwise.
91085
91150
  */
91086
- function exitListItemWithEmptyTaskListItem(token) {
91087
- const node = this.stack[this.stack.length - 1];
91088
- if (node &&
91089
- node.type === 'listItem' &&
91090
- typeof node.checked !== 'boolean') {
91091
- const listItem = node;
91092
- const head = listItem.children[0];
91093
- if (head && head.type === 'paragraph' && head.children.length === 1) {
91094
- const text = head.children[0];
91095
- if (text.type === 'text') {
91096
- const hasTrailingWhitespace = typeof head.position?.end.offset === 'number' &&
91097
- typeof text.position?.end.offset === 'number' &&
91098
- head.position.end.offset > text.position.end.offset;
91099
- if (!hasTrailingWhitespace) {
91100
- this.exit(token);
91101
- return;
91102
- }
91103
- const value = text.value;
91104
- if (value === '[ ]') {
91105
- listItem.checked = false;
91106
- head.children = [];
91107
- }
91108
- else if (value === '[x]' || value === '[X]') {
91109
- listItem.checked = true;
91110
- head.children = [];
91111
- }
91151
+ function findOpeningMarker(text) {
91152
+ const results = MARKER_PATTERNS.map(({ isBold, marker }) => {
91153
+ if (marker === '*' && text.startsWith('**'))
91154
+ return null;
91155
+ if (marker === '_' && text.startsWith('__'))
91156
+ return null;
91157
+ if (text.startsWith(marker) && text.length > marker.length) {
91158
+ return { isBold, marker, textAfter: text.slice(marker.length), textBefore: '' };
91159
+ }
91160
+ const idx = text.indexOf(marker);
91161
+ if (idx > 0 && !/\s/.test(text[idx - 1])) {
91162
+ if (marker === '*' && text.slice(idx).startsWith('**'))
91163
+ return null;
91164
+ if (marker === '_' && text.slice(idx).startsWith('__'))
91165
+ return null;
91166
+ const after = text.slice(idx + marker.length);
91167
+ if (after.length > 0) {
91168
+ return { isBold, marker, textAfter: after, textBefore: text.slice(0, idx) };
91112
91169
  }
91113
91170
  }
91114
- }
91115
- this.exit(token);
91116
- }
91117
- function emptyTaskListItemFromMarkdown() {
91118
- return {
91119
- exit: {
91120
- listItem: exitListItemWithEmptyTaskListItem,
91121
- },
91122
- };
91171
+ return null;
91172
+ });
91173
+ return results.find(r => r !== null) ?? null;
91123
91174
  }
91124
-
91125
- ;// ./lib/mdast-util/legacy-variable/index.ts
91126
-
91127
- const contextMap = new WeakMap();
91128
- function findlegacyVariableToken() {
91129
- // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
91130
- const events = this.tokenStack;
91131
- for (let i = events.length - 1; i >= 0; i -= 1) {
91132
- const token = events[i][0];
91133
- if (token.type === 'legacyVariable')
91134
- return token;
91175
+ /**
91176
+ * Finds the end/closing marker in a text node for multi-node emphasis.
91177
+ */
91178
+ function findEndMarker(text, marker) {
91179
+ const spacePattern = ` ${marker}`;
91180
+ const spaceIdx = text.indexOf(spacePattern);
91181
+ if (spaceIdx >= 0) {
91182
+ if (marker === '*' && text.slice(spaceIdx + 1).startsWith('**'))
91183
+ return null;
91184
+ if (marker === '_' && text.slice(spaceIdx + 1).startsWith('__'))
91185
+ return null;
91186
+ return {
91187
+ textAfter: text.slice(spaceIdx + spacePattern.length),
91188
+ textBefore: text.slice(0, spaceIdx),
91189
+ };
91135
91190
  }
91136
- return undefined;
91137
- }
91138
- function enterlegacyVariable(token) {
91139
- contextMap.set(token, { value: '' });
91140
- }
91141
- function exitlegacyVariableValue(token) {
91142
- const variableToken = findlegacyVariableToken.call(this);
91143
- if (!variableToken)
91144
- return;
91145
- const ctx = contextMap.get(variableToken);
91146
- // Build up the variable characters
91147
- if (ctx)
91148
- ctx.value += this.sliceSerialize(token);
91149
- }
91150
- function exitlegacyVariable(token) {
91151
- const ctx = contextMap.get(token);
91152
- const serialized = this.sliceSerialize(token);
91153
- const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
91154
- ? serialized.slice(2, -2)
91155
- : ctx?.value ?? '';
91156
- const nodePosition = {
91157
- start: {
91158
- offset: token.start.offset,
91159
- line: token.start.line,
91160
- column: token.start.column,
91161
- },
91162
- end: {
91163
- offset: token.end.offset,
91164
- line: token.end.line,
91165
- column: token.end.column,
91166
- },
91167
- };
91168
- if (variableName.startsWith('glossary:')) {
91169
- const term = variableName.slice('glossary:'.length).trim();
91170
- this.enter({
91171
- type: NodeTypes.glossary,
91172
- data: {
91173
- hName: 'Glossary',
91174
- hProperties: { term },
91175
- },
91176
- children: [{ type: 'text', value: term }],
91177
- position: nodePosition,
91178
- }, token);
91179
- this.exit(token);
91180
- contextMap.delete(token);
91181
- return;
91191
+ if (text.startsWith(marker)) {
91192
+ if (marker === '*' && text.startsWith('**'))
91193
+ return null;
91194
+ if (marker === '_' && text.startsWith('__'))
91195
+ return null;
91196
+ return {
91197
+ textAfter: text.slice(marker.length),
91198
+ textBefore: '',
91199
+ };
91182
91200
  }
91183
- this.enter({
91184
- type: NodeTypes.variable,
91185
- data: {
91186
- hName: 'Variable',
91187
- hProperties: { name: variableName.trim(), isLegacy: true },
91188
- },
91189
- value: `<<${variableName}>>`,
91190
- }, token);
91191
- this.exit(token);
91192
- contextMap.delete(token);
91193
- }
91194
- function legacyVariableFromMarkdown() {
91195
- return {
91196
- enter: {
91197
- legacyVariable: enterlegacyVariable,
91198
- },
91199
- exit: {
91200
- legacyVariableValue: exitlegacyVariableValue,
91201
- legacyVariable: exitlegacyVariable,
91202
- },
91203
- };
91201
+ return null;
91204
91202
  }
91205
-
91206
- ;// ./node_modules/micromark-util-symbol/lib/codes.js
91207
91203
  /**
91208
- * Character codes.
91209
- *
91210
- * This module is compiled away!
91211
- *
91212
- * micromark works based on character codes.
91213
- * This module contains constants for the ASCII block and the replacement
91214
- * character.
91215
- * A couple of them are handled in a special way, such as the line endings
91216
- * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
91217
- * tab) and its expansion based on what column it’s at (virtual space),
91218
- * and the end-of-file (eof) character.
91219
- * As values are preprocessed before handling them, the actual characters LF,
91220
- * CR, HT, and NUL (which is present as the replacement character), are
91221
- * guaranteed to not exist.
91222
- *
91223
- * Unicode basic latin block.
91204
+ * Scan children for an opening emphasis marker in a text node.
91224
91205
  */
91225
- const codes = /** @type {const} */ ({
91226
- carriageReturn: -5,
91227
- lineFeed: -4,
91228
- carriageReturnLineFeed: -3,
91229
- horizontalTab: -2,
91230
- virtualSpace: -1,
91231
- eof: null,
91232
- nul: 0,
91233
- soh: 1,
91234
- stx: 2,
91235
- etx: 3,
91236
- eot: 4,
91237
- enq: 5,
91238
- ack: 6,
91239
- bel: 7,
91240
- bs: 8,
91241
- ht: 9, // `\t`
91242
- lf: 10, // `\n`
91243
- vt: 11, // `\v`
91244
- ff: 12, // `\f`
91245
- cr: 13, // `\r`
91246
- so: 14,
91247
- si: 15,
91248
- dle: 16,
91249
- dc1: 17,
91250
- dc2: 18,
91251
- dc3: 19,
91252
- dc4: 20,
91253
- nak: 21,
91254
- syn: 22,
91255
- etb: 23,
91256
- can: 24,
91257
- em: 25,
91258
- sub: 26,
91259
- esc: 27,
91260
- fs: 28,
91261
- gs: 29,
91262
- rs: 30,
91263
- us: 31,
91264
- space: 32,
91265
- exclamationMark: 33, // `!`
91266
- quotationMark: 34, // `"`
91267
- numberSign: 35, // `#`
91268
- dollarSign: 36, // `$`
91269
- percentSign: 37, // `%`
91270
- ampersand: 38, // `&`
91271
- apostrophe: 39, // `'`
91272
- leftParenthesis: 40, // `(`
91273
- rightParenthesis: 41, // `)`
91274
- asterisk: 42, // `*`
91275
- plusSign: 43, // `+`
91276
- comma: 44, // `,`
91277
- dash: 45, // `-`
91278
- dot: 46, // `.`
91279
- slash: 47, // `/`
91280
- digit0: 48, // `0`
91281
- digit1: 49, // `1`
91282
- digit2: 50, // `2`
91283
- digit3: 51, // `3`
91284
- digit4: 52, // `4`
91285
- digit5: 53, // `5`
91286
- digit6: 54, // `6`
91287
- digit7: 55, // `7`
91288
- digit8: 56, // `8`
91289
- digit9: 57, // `9`
91290
- colon: 58, // `:`
91291
- semicolon: 59, // `;`
91292
- lessThan: 60, // `<`
91293
- equalsTo: 61, // `=`
91294
- greaterThan: 62, // `>`
91295
- questionMark: 63, // `?`
91296
- atSign: 64, // `@`
91297
- uppercaseA: 65, // `A`
91298
- uppercaseB: 66, // `B`
91299
- uppercaseC: 67, // `C`
91300
- uppercaseD: 68, // `D`
91301
- uppercaseE: 69, // `E`
91302
- uppercaseF: 70, // `F`
91303
- uppercaseG: 71, // `G`
91304
- uppercaseH: 72, // `H`
91305
- uppercaseI: 73, // `I`
91306
- uppercaseJ: 74, // `J`
91307
- uppercaseK: 75, // `K`
91308
- uppercaseL: 76, // `L`
91309
- uppercaseM: 77, // `M`
91310
- uppercaseN: 78, // `N`
91311
- uppercaseO: 79, // `O`
91312
- uppercaseP: 80, // `P`
91313
- uppercaseQ: 81, // `Q`
91314
- uppercaseR: 82, // `R`
91315
- uppercaseS: 83, // `S`
91316
- uppercaseT: 84, // `T`
91317
- uppercaseU: 85, // `U`
91318
- uppercaseV: 86, // `V`
91319
- uppercaseW: 87, // `W`
91320
- uppercaseX: 88, // `X`
91321
- uppercaseY: 89, // `Y`
91322
- uppercaseZ: 90, // `Z`
91323
- leftSquareBracket: 91, // `[`
91324
- backslash: 92, // `\`
91325
- rightSquareBracket: 93, // `]`
91326
- caret: 94, // `^`
91327
- underscore: 95, // `_`
91328
- graveAccent: 96, // `` ` ``
91329
- lowercaseA: 97, // `a`
91330
- lowercaseB: 98, // `b`
91331
- lowercaseC: 99, // `c`
91332
- lowercaseD: 100, // `d`
91333
- lowercaseE: 101, // `e`
91334
- lowercaseF: 102, // `f`
91335
- lowercaseG: 103, // `g`
91336
- lowercaseH: 104, // `h`
91337
- lowercaseI: 105, // `i`
91338
- lowercaseJ: 106, // `j`
91339
- lowercaseK: 107, // `k`
91340
- lowercaseL: 108, // `l`
91341
- lowercaseM: 109, // `m`
91342
- lowercaseN: 110, // `n`
91343
- lowercaseO: 111, // `o`
91344
- lowercaseP: 112, // `p`
91345
- lowercaseQ: 113, // `q`
91346
- lowercaseR: 114, // `r`
91347
- lowercaseS: 115, // `s`
91348
- lowercaseT: 116, // `t`
91349
- lowercaseU: 117, // `u`
91350
- lowercaseV: 118, // `v`
91351
- lowercaseW: 119, // `w`
91352
- lowercaseX: 120, // `x`
91353
- lowercaseY: 121, // `y`
91354
- lowercaseZ: 122, // `z`
91355
- leftCurlyBrace: 123, // `{`
91356
- verticalBar: 124, // `|`
91357
- rightCurlyBrace: 125, // `}`
91358
- tilde: 126, // `~`
91359
- del: 127,
91360
- // Unicode Specials block.
91361
- byteOrderMarker: 65_279,
91362
- // Unicode Specials block.
91363
- replacementCharacter: 65_533 // `�`
91364
- })
91365
-
91366
- ;// ./lib/micromark/legacy-variable/syntax.ts
91367
-
91368
-
91369
- function isAllowedValueChar(code) {
91370
- return (code !== null &&
91371
- code !== codes.lessThan &&
91372
- code !== codes.greaterThan &&
91373
- !markdownLineEnding(code));
91374
- }
91375
- const legacyVariableConstruct = {
91376
- name: 'legacyVariable',
91377
- tokenize,
91378
- };
91379
- function tokenize(effects, ok, nok) {
91380
- let hasValue = false;
91381
- const start = (code) => {
91382
- if (code !== codes.lessThan)
91383
- return nok(code);
91384
- effects.enter('legacyVariable');
91385
- effects.enter('legacyVariableMarkerStart');
91386
- effects.consume(code); // <
91387
- return open2;
91388
- };
91389
- const open2 = (code) => {
91390
- if (code !== codes.lessThan)
91391
- return nok(code);
91392
- effects.consume(code); // <<
91393
- effects.exit('legacyVariableMarkerStart');
91394
- effects.enter('legacyVariableValue');
91395
- return value;
91396
- };
91397
- const value = (code) => {
91398
- if (code === codes.greaterThan) {
91399
- if (!hasValue)
91400
- return nok(code);
91401
- effects.exit('legacyVariableValue');
91402
- effects.enter('legacyVariableMarkerEnd');
91403
- effects.consume(code); // >
91404
- return close2;
91206
+ function findOpeningInChildren(children) {
91207
+ let result = null;
91208
+ children.some((child, idx) => {
91209
+ if (child.type !== 'text')
91210
+ return false;
91211
+ const found = findOpeningMarker(child.value);
91212
+ if (found) {
91213
+ result = { idx, opening: found };
91214
+ return true;
91405
91215
  }
91406
- if (!isAllowedValueChar(code))
91407
- return nok(code);
91408
- hasValue = true;
91409
- effects.consume(code);
91410
- return value;
91411
- };
91412
- const close2 = (code) => {
91413
- if (code !== codes.greaterThan)
91414
- return nok(code);
91415
- effects.consume(code); // >>
91416
- effects.exit('legacyVariableMarkerEnd');
91417
- effects.exit('legacyVariable');
91418
- return ok;
91419
- };
91420
- return start;
91216
+ return false;
91217
+ });
91218
+ return result;
91421
91219
  }
91422
- function legacyVariable() {
91423
- return {
91424
- text: { [codes.lessThan]: legacyVariableConstruct },
91425
- };
91220
+ /**
91221
+ * Scan children (after openingIdx) for a closing emphasis marker.
91222
+ */
91223
+ function findClosingInChildren(children, openingIdx, marker) {
91224
+ let result = null;
91225
+ children.slice(openingIdx + 1).some((child, relativeIdx) => {
91226
+ if (child.type !== 'text')
91227
+ return false;
91228
+ const found = findEndMarker(child.value, marker);
91229
+ if (found) {
91230
+ result = { closingIdx: openingIdx + 1 + relativeIdx, closing: found };
91231
+ return true;
91232
+ }
91233
+ return false;
91234
+ });
91235
+ return result;
91426
91236
  }
91427
-
91428
- ;// ./lib/micromark/legacy-variable/index.ts
91429
91237
  /**
91430
- * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
91238
+ * Build the replacement nodes for a matched emphasis pair.
91431
91239
  */
91432
-
91433
-
91434
- ;// ./processor/transform/mdxish/constants.ts
91240
+ function buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx }) {
91241
+ const newNodes = [];
91242
+ if (opening.textBefore) {
91243
+ newNodes.push({ type: 'text', value: `${opening.textBefore} ` });
91244
+ }
91245
+ const emphasisChildren = [];
91246
+ const openingText = opening.textAfter.replace(/^\s+/, '');
91247
+ if (openingText) {
91248
+ emphasisChildren.push({ type: 'text', value: openingText });
91249
+ }
91250
+ container.children.slice(openingIdx + 1, closingIdx).forEach(child => {
91251
+ emphasisChildren.push(child);
91252
+ });
91253
+ const closingText = closing.textBefore.replace(/\s+$/, '');
91254
+ if (closingText) {
91255
+ emphasisChildren.push({ type: 'text', value: closingText });
91256
+ }
91257
+ if (emphasisChildren.length > 0) {
91258
+ const emphasisNode = opening.isBold
91259
+ ? { type: 'strong', children: emphasisChildren }
91260
+ : { type: 'emphasis', children: emphasisChildren };
91261
+ newNodes.push(emphasisNode);
91262
+ }
91263
+ if (closing.textAfter) {
91264
+ newNodes.push({ type: 'text', value: closing.textAfter });
91265
+ }
91266
+ return newNodes;
91267
+ }
91435
91268
  /**
91436
- * Inline component tags handled by mdxish-inline-components.ts.
91437
- * Also excluded from block-level handling in mdxish-component-blocks.ts.
91269
+ * Find and transform one multi-node emphasis pair in the container.
91270
+ * Returns true if a pair was found and transformed, false otherwise.
91438
91271
  */
91439
- const INLINE_COMPONENT_TAGS = new Set(['Anchor']);
91440
-
91441
- ;// ./processor/transform/mdxish/mdxish-component-blocks.ts
91442
-
91443
-
91444
-
91445
-
91446
-
91447
-
91448
-
91449
- const pascalCaseTagPattern = /^<([A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>([\s\S]*)?$/;
91450
- const tagAttributePattern = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
91451
- /**
91452
- * Maximum number of siblings to scan forward when looking for a closing tag
91453
- * to avoid scanning too far and degrading performance
91454
- */
91455
- const MAX_LOOKAHEAD = 30;
91456
- /**
91457
- * Tags that have dedicated transformers and should NOT be handled by this plugin.
91458
- * These components either have special parsing requirements that the generic component
91459
- * block transformer cannot handle correctly, or are inline components that we don't
91460
- * want to convert to mdxJsxFlowElement which is a block level element.
91461
- */
91462
- const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table', 'Glossary', ...INLINE_COMPONENT_TAGS]);
91463
- const inlineMdProcessor = unified()
91464
- .data('micromarkExtensions', [legacyVariable()])
91465
- .data('fromMarkdownExtensions', [legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown()])
91466
- .use(remarkParse)
91467
- .use(remarkGfm);
91468
- const isClosingTag = (value, tag) => value.trim() === `</${tag}>`;
91469
- /**
91470
- * Parse markdown content into mdast children nodes.
91471
- */
91472
- const parseMdChildren = (value) => {
91473
- const parsed = inlineMdProcessor.parse(value);
91474
- return parsed.children || [];
91475
- };
91476
- /**
91477
- * Convert raw attribute string into mdxJsxAttribute entries.
91478
- * Handles both key-value attributes (theme="info") and boolean attributes (empty).
91479
- */
91480
- const parseAttributes = (raw) => {
91481
- const attributes = [];
91482
- const attrString = raw.trim();
91483
- if (!attrString)
91484
- return attributes;
91485
- tagAttributePattern.lastIndex = 0;
91486
- let match = tagAttributePattern.exec(attrString);
91487
- while (match !== null) {
91488
- const [, attrName, attrValue] = match;
91489
- const value = attrValue ? attrValue.replace(/^['"]|['"]$/g, '') : null;
91490
- attributes.push({ type: 'mdxJsxAttribute', name: attrName, value });
91491
- match = tagAttributePattern.exec(attrString);
91492
- }
91493
- return attributes;
91494
- };
91495
- /**
91496
- * Parse an HTML tag string into structured data.
91497
- */
91498
- const parseTag = (value) => {
91499
- const match = value.match(pascalCaseTagPattern);
91500
- if (!match)
91501
- return null;
91502
- const [, tag, attrString = '', selfClosing = '', contentAfterTag = ''] = match;
91503
- return {
91504
- tag,
91505
- attributes: parseAttributes(attrString),
91506
- selfClosing: !!selfClosing,
91507
- contentAfterTag,
91508
- };
91509
- };
91510
- /**
91511
- * Parse substring content of a node and update the parent's children to include the new nodes.
91512
- */
91513
- const parseSibling = (stack, parent, index, sibling) => {
91514
- const siblingNodes = parseMdChildren(sibling);
91515
- // The new sibling nodes might contain new components to be processed
91516
- if (siblingNodes.length > 0) {
91517
- parent.children.splice(index + 1, 0, ...siblingNodes);
91518
- stack.push(parent);
91519
- }
91520
- };
91521
- /**
91522
- * Create an MdxJsxFlowElement node from component data.
91523
- */
91524
- const createComponentNode = ({ tag, attributes, children, startPosition, endPosition }) => ({
91525
- type: 'mdxJsxFlowElement',
91526
- name: tag,
91527
- attributes,
91528
- children,
91529
- position: {
91530
- start: startPosition?.start,
91531
- end: endPosition?.end ?? startPosition?.end,
91532
- },
91533
- });
91534
- /**
91535
- * Remove a closing tag from a paragraph's children and return the updated paragraph.
91536
- */
91537
- const stripClosingTagFromParagraph = (node, tag) => {
91538
- if (!Array.isArray(node.children))
91539
- return { paragraph: node, found: false };
91540
- const children = [...node.children];
91541
- const closingIndex = children.findIndex(child => child.type === 'html' && isClosingTag(child.value || '', tag));
91542
- if (closingIndex === -1)
91543
- return { paragraph: node, found: false };
91544
- children.splice(closingIndex, 1);
91545
- return { paragraph: { ...node, children }, found: true };
91546
- };
91272
+ function processOneEmphasisPair(container) {
91273
+ const openingResult = findOpeningInChildren(container.children);
91274
+ if (!openingResult)
91275
+ return false;
91276
+ const { idx: openingIdx, opening } = openingResult;
91277
+ const closingResult = findClosingInChildren(container.children, openingIdx, opening.marker);
91278
+ if (!closingResult)
91279
+ return false;
91280
+ const { closingIdx, closing } = closingResult;
91281
+ const newNodes = buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx });
91282
+ const deleteCount = closingIdx - openingIdx + 1;
91283
+ container.children.splice(openingIdx, deleteCount, ...newNodes);
91284
+ return true;
91285
+ }
91547
91286
  /**
91548
- * Scan forward through siblings to find a closing tag.
91549
- * Handles:
91550
- * - Exact match HTML siblings (e.g., `</Tag>`)
91551
- * - HTML siblings with embedded closing tag (e.g., `...\n</Tag>`)
91552
- * - Paragraph siblings containing the closing tag as a child
91553
- *
91554
- * Returns null if not found within MAX_LOOKAHEAD siblings
91287
+ * Handle malformed emphasis that spans multiple AST nodes.
91288
+ * E.g., "**bold [link](url)**" where markers are in different text nodes.
91555
91289
  */
91556
- const scanForClosingTag = (parent, startIndex, tag) => {
91557
- const closingTagStr = `</${tag}>`;
91558
- const maxIndex = Math.min(startIndex + MAX_LOOKAHEAD, parent.children.length);
91559
- let i = startIndex + 1;
91560
- for (; i < maxIndex; i += 1) {
91561
- const sibling = parent.children[i];
91562
- // Check HTML siblings
91563
- if (sibling.type === 'html') {
91564
- const siblingValue = sibling.value || '';
91565
- // Exact match (standalone closing tag)
91566
- if (isClosingTag(siblingValue, tag)) {
91567
- return { closingIndex: i, extraClosingChildren: [] };
91568
- }
91569
- // Embedded closing tag (closing tag within HTML block content)
91570
- if (siblingValue.includes(closingTagStr)) {
91571
- const closeTagPos = siblingValue.indexOf(closingTagStr);
91572
- const contentBeforeClose = siblingValue.substring(0, closeTagPos).trim();
91573
- const contentAfterClose = siblingValue.substring(closeTagPos + closingTagStr.length).trim();
91574
- const extraChildren = contentBeforeClose
91575
- ? parseMdChildren(contentBeforeClose)
91576
- : [];
91577
- return { closingIndex: i, extraClosingChildren: extraChildren, contentAfterClose: contentAfterClose || undefined };
91578
- }
91579
- }
91580
- // Check paragraph siblings
91581
- if (sibling.type === 'paragraph') {
91582
- const { paragraph, found } = stripClosingTagFromParagraph(sibling, tag);
91583
- if (found) {
91584
- return { closingIndex: i, extraClosingChildren: [], strippedParagraph: paragraph };
91585
- }
91290
+ function visitMultiNodeEmphasis(tree) {
91291
+ const containerTypes = ['paragraph', 'heading', 'tableCell', 'listItem', 'blockquote'];
91292
+ visit(tree, node => {
91293
+ if (!containerTypes.includes(node.type))
91294
+ return;
91295
+ if (!('children' in node) || !Array.isArray(node.children))
91296
+ return;
91297
+ const container = node;
91298
+ let foundPair = true;
91299
+ while (foundPair) {
91300
+ foundPair = processOneEmphasisPair(container);
91586
91301
  }
91587
- }
91588
- if (i < parent.children.length) {
91589
- // eslint-disable-next-line no-console
91590
- console.warn(`Closing tag </${tag}> not found within ${MAX_LOOKAHEAD} siblings, stopping scan`);
91591
- }
91592
- return null;
91593
- };
91594
- const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
91595
- parent.children.splice(index, 1, mdxNode);
91596
- };
91302
+ });
91303
+ }
91597
91304
  /**
91598
- * Transform PascalCase HTML nodes into mdxJsxFlowElement nodes.
91599
- *
91600
- * Remark parses unknown/custom component tags as raw HTML nodes.
91601
- * These are the custom readme MDX syntax for components.
91602
- * This transformer identifies these patterns and converts them to proper MDX JSX elements so they
91603
- * can be accurately recognized and rendered later with their component definition code.
91604
- * Though for some tags, we need to handle them specially
91605
- *
91606
- * ## Supported HTML Structures
91607
- *
91608
- * ### 1. Self-closing tags
91609
- * ```
91610
- * <Component />
91611
- * ```
91612
- * Parsed as: `html: "<Component />"`
91613
- *
91614
- * ### 2. Self-contained blocks (entire component in single HTML node)
91615
- * ```
91616
- * <Button>Click me</Button>
91617
- * ```
91618
- * ```
91619
- * <Component>
91620
- * <h2>Title</h2>
91621
- * <p>Content</p>
91622
- * </Component>
91623
- * ```
91624
- * Parsed as: `html: "<Component>\n <h2>Title</h2>\n <p>Content</p>\n</Component>"`
91625
- * The opening tag, content, and closing tag are all captured in one HTML node.
91626
- *
91627
- * ### 3. Multi-sibling components (closing tag in a following sibling)
91628
- * Handles various structures where the closing tag is in a later sibling, such as:
91629
- *
91630
- * #### 3a. Block components (closing tag in sibling paragraph)
91631
- * ```
91632
- * <Callout>
91633
- * Some **markdown** content
91634
- * </Callout>
91635
- * ```
91636
- *
91637
- * #### 3b. Multi-paragraph components (closing tag several siblings away)
91638
- * ```
91639
- * <Callout>
91640
- *
91641
- * First paragraph
91642
- *
91643
- * Second paragraph
91644
- * </Callout>
91645
- * ```
91305
+ * A remark plugin that normalizes malformed bold and italic markers in text nodes.
91306
+ * Detects patterns like `** bold**`, `Hello** Wrong Bold**`, `__ bold__`, `Hello__ Wrong Bold__`,
91307
+ * `* italic*`, `Hello* Wrong Italic*`, `_ italic_`, or `Hello_ Wrong Italic_`
91308
+ * and converts them to proper strong/emphasis nodes, matching the behavior of the legacy rdmd engine.
91646
91309
  *
91647
- * #### 3c. Nested components split by blank lines (closing tag embedded in HTML sibling)
91648
- * ```
91649
- * <Outer>
91650
- * <Inner>content</Inner>
91310
+ * Supports both asterisk (`**bold**`, `*italic*`) and underscore (`__bold__`, `_italic_`) syntax.
91311
+ * Also supports snake_case content like `** some_snake_case**`.
91651
91312
  *
91652
- * <Inner>content</Inner>
91653
- * </Outer>
91654
- * ```
91313
+ * This runs after remark-parse, which (in v11+) is strict and doesn't parse
91314
+ * malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
91655
91315
  */
91656
- const mdxishComponentBlocks = () => tree => {
91657
- const stack = [tree];
91658
- const processChildNode = (parent, index) => {
91659
- const node = parent.children[index];
91660
- if (!node)
91661
- return;
91662
- if ('children' in node && Array.isArray(node.children)) {
91663
- stack.push(node);
91316
+ const normalizeEmphasisAST = () => (tree) => {
91317
+ visit(tree, 'text', function visitor(node, index, parent) {
91318
+ if (index === undefined || !parent)
91319
+ return undefined;
91320
+ // Skip if inside code blocks or inline code
91321
+ if (parent.type === 'inlineCode' || parent.type === 'code') {
91322
+ return undefined;
91664
91323
  }
91665
- // Only visit HTML nodes with an actual html tag,
91666
- // which means a potential unparsed MDX component
91667
- const value = node.value;
91668
- if (node.type !== 'html' || typeof value !== 'string')
91669
- return;
91670
- const parsed = parseTag(value.trim());
91671
- if (!parsed)
91672
- return;
91673
- const { tag, attributes, selfClosing, contentAfterTag = '' } = parsed;
91674
- // Skip tags that have dedicated transformers
91675
- if (EXCLUDED_TAGS.has(tag))
91676
- return;
91677
- const closingTagStr = `</${tag}>`;
91678
- // Case 1: Self-closing tag
91679
- if (selfClosing) {
91680
- const componentNode = createComponentNode({
91681
- tag,
91682
- attributes,
91683
- children: [],
91684
- startPosition: node.position,
91685
- });
91686
- substituteNodeWithMdxNode(parent, index, componentNode);
91687
- // Check and parse if there's relevant content after the current closing tag
91688
- const remainingContent = contentAfterTag.trim();
91689
- if (remainingContent) {
91690
- parseSibling(stack, parent, index, remainingContent);
91324
+ const text = node.value;
91325
+ const allMatches = [];
91326
+ [...text.matchAll(asteriskBoldRegex)].forEach(match => {
91327
+ allMatches.push({ isBold: true, marker: '**', match });
91328
+ });
91329
+ [...text.matchAll(underscoreBoldRegex)].forEach(match => {
91330
+ allMatches.push({ isBold: true, marker: '__', match });
91331
+ });
91332
+ [...text.matchAll(asteriskItalicRegex)].forEach(match => {
91333
+ allMatches.push({ isBold: false, marker: '*', match });
91334
+ });
91335
+ [...text.matchAll(underscoreItalicRegex)].forEach(match => {
91336
+ allMatches.push({ isBold: false, marker: '_', match });
91337
+ });
91338
+ [...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
91339
+ allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
91340
+ });
91341
+ [...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
91342
+ allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
91343
+ });
91344
+ [...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
91345
+ allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
91346
+ });
91347
+ [...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
91348
+ allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
91349
+ });
91350
+ if (allMatches.length === 0)
91351
+ return undefined;
91352
+ allMatches.sort((a, b) => (a.match.index ?? 0) - (b.match.index ?? 0));
91353
+ const filteredMatches = [];
91354
+ let lastEnd = 0;
91355
+ allMatches.forEach(info => {
91356
+ const start = info.match.index ?? 0;
91357
+ const end = start + info.match[0].length;
91358
+ if (start >= lastEnd) {
91359
+ filteredMatches.push(info);
91360
+ lastEnd = end;
91691
91361
  }
91692
- return;
91693
- }
91694
- // Case 2: Self-contained block (closing tag in content)
91695
- if (contentAfterTag.includes(closingTagStr)) {
91696
- // Find the first closing tag
91697
- const closingTagIndex = contentAfterTag.indexOf(closingTagStr);
91698
- const componentInnerContent = contentAfterTag.substring(0, closingTagIndex).trim();
91699
- const contentAfterClose = contentAfterTag.substring(closingTagIndex + closingTagStr.length).trim();
91700
- const componentNode = createComponentNode({
91701
- tag,
91702
- attributes,
91703
- children: componentInnerContent ? parseMdChildren(componentInnerContent) : [],
91704
- startPosition: node.position,
91705
- });
91706
- substituteNodeWithMdxNode(parent, index, componentNode);
91707
- // After the closing tag, there might be more content to be processed
91708
- if (contentAfterClose) {
91709
- parseSibling(stack, parent, index, contentAfterClose);
91362
+ });
91363
+ if (filteredMatches.length === 0)
91364
+ return undefined;
91365
+ const parts = [];
91366
+ let lastIndex = 0;
91367
+ filteredMatches.forEach(({ isBold, isIntraword, marker, match }) => {
91368
+ const matchIndex = match.index ?? 0;
91369
+ const fullMatch = match[0];
91370
+ if (isIntraword) {
91371
+ // handles cases like hello_world_ where we only want to italicize 'world'
91372
+ const charBefore = match[1] || ''; // e.g., "l" in "hello_world_"
91373
+ const content = match[2]; // e.g., "world"
91374
+ const combinedBefore = text.slice(lastIndex, matchIndex) + charBefore;
91375
+ if (combinedBefore) {
91376
+ parts.push({ type: 'text', value: combinedBefore });
91377
+ }
91378
+ if (isBold) {
91379
+ parts.push({
91380
+ type: 'strong',
91381
+ children: [{ type: 'text', value: content }],
91382
+ });
91383
+ }
91384
+ else {
91385
+ parts.push({
91386
+ type: 'emphasis',
91387
+ children: [{ type: 'text', value: content }],
91388
+ });
91389
+ }
91390
+ lastIndex = matchIndex + fullMatch.length;
91391
+ return;
91710
91392
  }
91711
- else if (componentNode.children.length > 0) {
91712
- // The content inside the component block might contain new components to be processed
91713
- stack.push(componentNode);
91393
+ if (matchIndex > lastIndex) {
91394
+ const beforeText = text.slice(lastIndex, matchIndex);
91395
+ if (beforeText) {
91396
+ parts.push({ type: 'text', value: beforeText });
91397
+ }
91714
91398
  }
91715
- return;
91716
- }
91717
- // Case 3: Multi-sibling component (closing tag in a following sibling)
91718
- // Scans forward through siblings to find closing tag in HTML or paragraph nodes
91719
- const scanResult = scanForClosingTag(parent, index, tag);
91720
- if (!scanResult)
91721
- return;
91722
- const { closingIndex, extraClosingChildren, strippedParagraph, contentAfterClose: remainingAfterClose } = scanResult;
91723
- const extraChildren = contentAfterTag ? parseMdChildren(contentAfterTag.trimStart()) : [];
91724
- // Collect all intermediate siblings between opening tag and closing tag
91725
- const intermediateChildren = parent.children.slice(index + 1, closingIndex);
91726
- // For paragraph siblings, include the full paragraph (with closing tag stripped)
91727
- // For HTML siblings, include any content parsed from before the closing tag
91728
- const closingChildren = strippedParagraph
91729
- ? (strippedParagraph.children.length > 0 ? [strippedParagraph] : [])
91730
- : extraClosingChildren;
91731
- const componentNode = createComponentNode({
91732
- tag,
91733
- attributes,
91734
- children: [...extraChildren, ...intermediateChildren, ...closingChildren],
91735
- startPosition: node.position,
91736
- endPosition: parent.children[closingIndex]?.position,
91399
+ const wordBefore = match[1]; // e.g., "Hello" in "Hello** Wrong Bold**"
91400
+ const contentWithSpaceAfter = match[3]; // Content when there's a space after opening markers
91401
+ const trailingSpace1 = match[4] || ''; // Space before closing markers (for "** text **" pattern)
91402
+ const contentWithSpaceBefore = match[5]; // Content when there's only a space before closing markers
91403
+ const trailingSpace2 = match[6] || ''; // Space before closing markers (for "**text **" pattern)
91404
+ const trailingSpace = trailingSpace1 || trailingSpace2; // Combined trailing space
91405
+ const content = (contentWithSpaceAfter || contentWithSpaceBefore || '').trim();
91406
+ const afterChar = match[7]; // Character after closing markers (if any)
91407
+ const markerPos = fullMatch.indexOf(marker);
91408
+ const spacesBeforeMarkers = wordBefore
91409
+ ? fullMatch.slice(wordBefore.length, markerPos)
91410
+ : fullMatch.slice(0, markerPos);
91411
+ const shouldAddSpace = !!contentWithSpaceAfter && !!wordBefore && !spacesBeforeMarkers;
91412
+ if (wordBefore) {
91413
+ const spacing = spacesBeforeMarkers + (shouldAddSpace ? ' ' : '');
91414
+ parts.push({ type: 'text', value: wordBefore + spacing });
91415
+ }
91416
+ else if (spacesBeforeMarkers) {
91417
+ parts.push({ type: 'text', value: spacesBeforeMarkers });
91418
+ }
91419
+ if (content) {
91420
+ if (isBold) {
91421
+ parts.push({
91422
+ type: 'strong',
91423
+ children: [{ type: 'text', value: content }],
91424
+ });
91425
+ }
91426
+ else {
91427
+ parts.push({
91428
+ type: 'emphasis',
91429
+ children: [{ type: 'text', value: content }],
91430
+ });
91431
+ }
91432
+ }
91433
+ if (afterChar) {
91434
+ const prefix = trailingSpace ? ' ' : '';
91435
+ parts.push({ type: 'text', value: prefix + afterChar });
91436
+ }
91437
+ lastIndex = matchIndex + fullMatch.length;
91737
91438
  });
91738
- // Remove all nodes from opening tag to closing tag (inclusive) and replace with component node
91739
- parent.children.splice(index, closingIndex - index + 1, componentNode);
91740
- // Since we might be merging sibling nodes together and combining content,
91741
- // there might be new components to process
91742
- if (componentNode.children.length > 0) {
91743
- stack.push(componentNode);
91744
- }
91745
- // If the closing tag sibling had content after it (e.g., another component opening tag),
91746
- // re-insert it as a sibling so it can be processed in subsequent iterations
91747
- if (remainingAfterClose) {
91748
- parseSibling(stack, parent, index, remainingAfterClose);
91439
+ if (lastIndex < text.length) {
91440
+ const remainingText = text.slice(lastIndex);
91441
+ if (remainingText) {
91442
+ parts.push({ type: 'text', value: remainingText });
91443
+ }
91749
91444
  }
91750
- };
91751
- // Process the nodes with the components depth-first to maintain the correct order of the nodes
91752
- while (stack.length) {
91753
- const parent = stack.pop();
91754
- if (parent?.children) {
91755
- parent.children.forEach((_child, index) => {
91756
- processChildNode(parent, index);
91757
- });
91445
+ if (parts.length > 0) {
91446
+ parent.children.splice(index, 1, ...parts);
91447
+ return [SKIP, index + parts.length];
91758
91448
  }
91759
- }
91449
+ return undefined;
91450
+ });
91451
+ // Handle malformed emphasis spanning multiple nodes (e.g., **text [link](url) **)
91452
+ visitMultiNodeEmphasis(tree);
91760
91453
  return tree;
91761
91454
  };
91762
- /* harmony default export */ const mdxish_component_blocks = (mdxishComponentBlocks);
91455
+ /* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
91763
91456
 
91764
91457
  ;// ./processor/transform/mdxish/mdxish-tables.ts
91765
91458
 
@@ -91770,14 +91463,22 @@ const mdxishComponentBlocks = () => tree => {
91770
91463
 
91771
91464
 
91772
91465
 
91466
+
91467
+
91468
+
91469
+
91773
91470
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
91774
91471
  const tableTypes = {
91775
91472
  tr: 'tableRow',
91776
91473
  th: 'tableCell',
91777
91474
  td: 'tableCell',
91778
91475
  };
91779
- const mdCellProcessor = unified().use(remarkParse).use(remarkGfm);
91780
- const tableNodeProcessor = unified().use(remarkParse).use(remarkMdx).use(mdxish_component_blocks);
91476
+ const tableNodeProcessor = unified()
91477
+ .use(remarkParse)
91478
+ .use(remarkMdx)
91479
+ .use(normalize_malformed_md_syntax)
91480
+ .use([callouts, gemoji_, code_tabs])
91481
+ .use(remarkGfm);
91781
91482
  /**
91782
91483
  * Check if children are only text nodes that might contain markdown
91783
91484
  */
@@ -91807,14 +91508,14 @@ const extractTextFromChildren = (children) => {
91807
91508
  .join('');
91808
91509
  };
91809
91510
  /**
91810
- * Parse markdown text into MDAST nodes
91511
+ * Returns true if any node in the array is block-level (non-phrasing) content.
91811
91512
  */
91812
- const parseMarkdown = (text) => {
91813
- const tree = mdCellProcessor.runSync(mdCellProcessor.parse(text));
91814
- return (tree.children || []);
91513
+ const hasFlowContent = (nodes) => {
91514
+ return nodes.some(node => !phrasing(node) && node.type !== 'paragraph');
91815
91515
  };
91816
91516
  /**
91817
- * Process a Table node (either MDX JSX element or parsed from HTML) and convert to markdown table
91517
+ * Process a Table node: re-parse text-only cell content, then output as
91518
+ * a markdown table (phrasing-only) or keep as JSX <Table> (has flow content).
91818
91519
  */
91819
91520
  const processTableNode = (node, index, parent) => {
91820
91521
  if (node.name !== 'Table')
@@ -91822,54 +91523,88 @@ const processTableNode = (node, index, parent) => {
91822
91523
  const { position } = node;
91823
91524
  const { align: alignAttr } = getAttrs(node);
91824
91525
  const align = Array.isArray(alignAttr) ? alignAttr : null;
91825
- const children = [];
91826
- // Process rows from thead and tbody
91827
- // The structure is: Table -> thead/tbody -> tr -> td/th
91828
- const processRow = (row) => {
91829
- const rowChildren = [];
91830
- visit(row, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
91831
- let parsedChildren = cellChildren;
91832
- // If cell contains only text nodes, try to re-parse as markdown
91833
- if (isTextOnly(cellChildren)) {
91834
- const textContent = extractTextFromChildren(cellChildren);
91835
- if (textContent.trim()) {
91836
- try {
91837
- const parsed = parseMarkdown(textContent);
91838
- // If parsing produced nodes, use them; otherwise keep original
91839
- if (parsed.length > 0) {
91840
- // Flatten paragraphs if they contain only phrasing content
91841
- parsedChildren = parsed.flatMap(parsedNode => {
91842
- if (parsedNode.type === 'paragraph' && 'children' in parsedNode && parsedNode.children) {
91843
- return parsedNode.children;
91844
- }
91845
- return [parsedNode];
91846
- });
91847
- }
91848
- }
91849
- catch {
91850
- // If parsing fails, keep original children
91851
- }
91526
+ let tableHasFlowContent = false;
91527
+ // Re-parse text-only cells through markdown and detect flow content
91528
+ visit(node, isTableCell, (cell) => {
91529
+ if (!isTextOnly(cell.children))
91530
+ return;
91531
+ const textContent = extractTextFromChildren(cell.children);
91532
+ if (!textContent.trim())
91533
+ return;
91534
+ // Since now we are using remarkMdx, which can fail and error, we need to
91535
+ // gate this behind a try/catch to ensure that malformed syntaxes do not
91536
+ // crash the page
91537
+ try {
91538
+ const parsed = tableNodeProcessor.runSync(tableNodeProcessor.parse(textContent));
91539
+ if (parsed.children.length > 0) {
91540
+ cell.children = parsed.children;
91541
+ if (hasFlowContent(parsed.children)) {
91542
+ tableHasFlowContent = true;
91852
91543
  }
91853
91544
  }
91854
- rowChildren.push({
91855
- type: tableTypes[name],
91856
- children: parsedChildren,
91857
- position: cellPosition,
91858
- });
91859
- });
91860
- children.push({
91861
- type: tableTypes[row.name],
91862
- children: rowChildren,
91863
- position: row.position,
91545
+ }
91546
+ catch {
91547
+ // If parsing fails, keep original children
91548
+ }
91549
+ });
91550
+ // mdast's table node always treats the first tableRow as <thead>, so we can't
91551
+ // represent a header-less table in mdast without the first body row getting
91552
+ // promoted. Keep as JSX instead so remarkRehype renders it correctly
91553
+ let hasThead = false;
91554
+ visit(node, isMDXElement, (child) => {
91555
+ if (child.name === 'thead')
91556
+ hasThead = true;
91557
+ });
91558
+ if (tableHasFlowContent || !hasThead) {
91559
+ // remarkMdx wraps inline elements in paragraph nodes (e.g. <td> on the
91560
+ // same line as content becomes mdxJsxTextElement inside a paragraph).
91561
+ // Unwrap these so <td>/<th> sit directly under <tr>, and strip
91562
+ // whitespace-only text nodes to avoid rendering empty <p>/<br>.
91563
+ const cleanChildren = (children) => children
91564
+ .flatMap(child => {
91565
+ if (child.type === 'paragraph' && 'children' in child && Array.isArray(child.children)) {
91566
+ return child.children;
91567
+ }
91568
+ return [child];
91569
+ })
91570
+ .filter(child => !(child.type === 'text' && 'value' in child && typeof child.value === 'string' && !child.value.trim()));
91571
+ visit(node, isMDXElement, (el) => {
91572
+ if ('children' in el && Array.isArray(el.children)) {
91573
+ el.children = cleanChildren(el.children);
91574
+ }
91864
91575
  });
91865
- };
91866
- // Visit thead and tbody, then find tr elements within them
91576
+ parent.children[index] = {
91577
+ ...node,
91578
+ position,
91579
+ };
91580
+ return;
91581
+ }
91582
+ // All cells are phrasing-only — convert to markdown table
91583
+ const children = [];
91867
91584
  visit(node, isMDXElement, (child) => {
91868
91585
  if (child.name === 'thead' || child.name === 'tbody') {
91869
91586
  visit(child, isMDXElement, (row) => {
91870
- if (row.name === 'tr' && row.type === 'mdxJsxFlowElement') {
91871
- processRow(row);
91872
- }
91587
+ if (row.name !== 'tr')
91588
+ return;
91589
+ const rowChildren = [];
91590
+ visit(row, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
91591
+ const parsedChildren = cellChildren.flatMap(parsedNode => {
91592
+ if (parsedNode.type === 'paragraph' && 'children' in parsedNode && parsedNode.children) {
91593
+ return parsedNode.children;
91594
+ }
91595
+ return [parsedNode];
91596
+ });
91597
+ rowChildren.push({
91598
+ type: tableTypes[name],
91599
+ children: parsedChildren,
91600
+ position: cellPosition,
91601
+ });
91602
+ });
91603
+ children.push({
91604
+ type: 'tableRow',
91605
+ children: rowChildren,
91606
+ position: row.position,
91607
+ });
91873
91608
  });
91874
91609
  }
91875
91610
  });
@@ -91889,54 +91624,35 @@ const processTableNode = (node, index, parent) => {
91889
91624
  /**
91890
91625
  * Converts JSX Table elements to markdown table nodes and re-parses markdown in cells.
91891
91626
  *
91892
- * Since mdxish doesn't use remarkMdx, we manually parse cell contents through
91893
- * remarkParse and remarkGfm to convert markdown to MDAST nodes.
91627
+ * The jsxTable micromark tokenizer captures `<Table>...</Table>` as a single html node,
91628
+ * preventing CommonMark HTML block type 6 from fragmenting it at blank lines. This
91629
+ * transformer then re-parses the html node with remarkMdx to produce proper JSX AST nodes
91630
+ * and converts them to MDAST table/tableRow/tableCell nodes.
91631
+ *
91632
+ * When cell content contains block-level nodes (callouts, code blocks, etc.), the table
91633
+ * is kept as a JSX <Table> element so that remarkRehype can properly handle the flow content.
91894
91634
  */
91895
91635
  const mdxishTables = () => tree => {
91896
- // First, handle MDX JSX elements (already converted by mdxishComponentBlocks)
91897
- visit(tree, isMDXElement, (node, index, parent) => {
91898
- if (node.name === 'Table') {
91899
- processTableNode(node, index, parent);
91900
- return SKIP;
91901
- }
91902
- });
91903
- // Also handle HTML and raw nodes that contain Table tags (in case mdxishComponentBlocks didn't convert them)
91904
- // This happens when the entire <Table>...</Table> block is in a single HTML node, which mdxishComponentBlocks
91905
- // doesn't handle (it only handles split nodes: opening tag, content paragraph, closing tag)
91906
- const handleTableInNode = (node, index, parent) => {
91636
+ visit(tree, 'html', (_node, index, parent) => {
91637
+ const node = _node;
91907
91638
  if (typeof index !== 'number' || !parent || !('children' in parent))
91908
91639
  return;
91909
- if (typeof node.value !== 'string')
91910
- return;
91911
- if (!node.value.includes('<Table') || !node.value.includes('</Table>'))
91640
+ if (!node.value.startsWith('<Table'))
91912
91641
  return;
91913
91642
  try {
91914
- // Parse the HTML content with remarkMdx and mdxishComponentBlocks to convert it to MDX JSX elements
91915
- // This creates a proper AST that we can then process
91916
91643
  const parsed = tableNodeProcessor.runSync(tableNodeProcessor.parse(node.value));
91917
- // Find the Table element in the parsed result and process it
91918
91644
  visit(parsed, isMDXElement, (tableNode) => {
91919
91645
  if (tableNode.name === 'Table') {
91920
- // Process the table and replace the HTML node with a markdown table node
91921
91646
  processTableNode(tableNode, index, parent);
91647
+ // Stop after the outermost Table so nested Tables don't overwrite parent.children[index]
91648
+ // we let it get handled naturally
91649
+ return EXIT;
91922
91650
  }
91923
91651
  });
91924
91652
  }
91925
91653
  catch {
91926
91654
  // If parsing fails, leave the node as-is
91927
91655
  }
91928
- };
91929
- // Handle HTML nodes (created by remark-parse for HTML blocks)
91930
- visit(tree, 'html', (node, index, parent) => {
91931
- if (typeof index === 'number' && parent && 'children' in parent) {
91932
- handleTableInNode(node, index, parent);
91933
- }
91934
- });
91935
- // Handle raw nodes (created by remark-parse for certain HTML structures)
91936
- visit(tree, 'raw', (node, index, parent) => {
91937
- if (typeof index === 'number' && parent && 'children' in parent) {
91938
- handleTableInNode(node, index, parent);
91939
- }
91940
91656
  });
91941
91657
  return tree;
91942
91658
  };
@@ -107433,7 +107149,7 @@ const tocToHast = (headings = [], variables) => {
107433
107149
  stack.pop();
107434
107150
  }
107435
107151
  if (heading.properties) {
107436
- const content = lib_plain({ type: 'root', children: heading.children }, { variables: flatVars });
107152
+ const content = lib_plain({ type: 'root', children: heading.children }, { separator: '', variables: flatVars });
107437
107153
  stack[stack.length - 1].children.push(hastscript_lib_h('li', null, hastscript_lib_h('a', { href: `#${heading.properties.id}` }, content)));
107438
107154
  }
107439
107155
  });
@@ -112432,10 +112148,6 @@ const compile_list_item_listItem = (node, parent, state, info) => {
112432
112148
  const plain_plain = (node) => node.value;
112433
112149
  /* harmony default export */ const compile_plain = (plain_plain);
112434
112150
 
112435
- ;// ./processor/compile/variable.ts
112436
- const variable = (node) => `{user.${node.data?.hProperties?.name || ''}}`;
112437
- /* harmony default export */ const compile_variable = (variable);
112438
-
112439
112151
  ;// ./processor/compile/index.ts
112440
112152
 
112441
112153
 
@@ -114104,7 +113816,7 @@ function getComponentName(componentName, components) {
114104
113816
 
114105
113817
 
114106
113818
 
114107
- const mdxish_components_INLINE_COMPONENT_TAGS = new Set(['anchor', 'glossary']);
113819
+ const INLINE_COMPONENT_TAGS = new Set(['anchor', 'glossary']);
114108
113820
  function isElementContentNode(node) {
114109
113821
  return node.type === 'element' || node.type === 'text' || node.type === 'comment';
114110
113822
  }
@@ -114186,7 +113898,7 @@ function parseTextChildren(node, processMarkdown, components) {
114186
113898
  const hast = processMarkdown(child.value.trim());
114187
113899
  const children = (hast.children ?? []).filter(isElementContentNode);
114188
113900
  // For inline components, preserve plain text instead of wrapping in <p>
114189
- if (mdxish_components_INLINE_COMPONENT_TAGS.has(node.tagName.toLowerCase()) && isSingleParagraphTextNode(children)) {
113901
+ if (INLINE_COMPONENT_TAGS.has(node.tagName.toLowerCase()) && isSingleParagraphTextNode(children)) {
114190
113902
  return [child];
114191
113903
  }
114192
113904
  return children;
@@ -114248,6 +113960,14 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
114248
113960
  visit(tree, 'element', (node, index, parent) => {
114249
113961
  if (index === undefined || !parent)
114250
113962
  return;
113963
+ // Parse Image caption as markdown so it renders formatted (bold, code,
113964
+ // decoded entities) in the figcaption instead of as a raw string.
113965
+ // rehypeRaw strips children from <img> (void element), so we must
113966
+ // re-process the caption here, after rehypeRaw.
113967
+ if (node.tagName === 'img' && typeof node.properties?.caption === 'string' && !node.children?.length) {
113968
+ const captionHast = processMarkdown(node.properties.caption);
113969
+ node.children = (captionHast.children ?? []).filter(isElementContentNode);
113970
+ }
114251
113971
  // Skip runtime components and standard HTML tags
114252
113972
  if (RUNTIME_COMPONENT_TAGS.has(node.tagName))
114253
113973
  return;
@@ -114814,110 +114534,468 @@ const evaluateExpressions = ({ context = {} } = {}) => tree => {
114814
114534
  };
114815
114535
  /* harmony default export */ const evaluate_expressions = (evaluateExpressions);
114816
114536
 
114817
- ;// ./processor/transform/mdxish/heading-slugs.ts
114537
+ ;// ./processor/transform/mdxish/heading-slugs.ts
114538
+
114539
+
114540
+ function isHeading(node) {
114541
+ return /^h[1-6]$/.test(node.tagName);
114542
+ }
114543
+ function textContent(node) {
114544
+ if (node.type === 'text')
114545
+ return node.value;
114546
+ // Process variable nodes by using their variable name for the id generation
114547
+ if (node.type === 'element' && node.tagName === 'variable' && node.properties?.name) {
114548
+ if (node.properties.isLegacy) {
114549
+ return node.properties.name;
114550
+ }
114551
+ return `user.${node.properties.name}`;
114552
+ }
114553
+ if ('children' in node)
114554
+ return node.children.map(textContent).join('');
114555
+ return '';
114556
+ }
114557
+ /**
114558
+ * Rehype plugin that constructs ids for headings
114559
+ * Id's are used to construct slug anchor links & Table of Contents during rendering
114560
+ * Use the text / nodes that make up the heading to generate the id
114561
+ */
114562
+ const generateSlugForHeadings = () => (tree) => {
114563
+ const slugger = new BananaSlug();
114564
+ visit(tree, 'element', (node) => {
114565
+ if (isHeading(node) && !node.properties.id) {
114566
+ const text = node.children.map(textContent).join('');
114567
+ node.properties.id = slugger.slug(text);
114568
+ }
114569
+ });
114570
+ return tree;
114571
+ };
114572
+ /* harmony default export */ const heading_slugs = (generateSlugForHeadings);
114573
+
114574
+ // EXTERNAL MODULE: ./node_modules/@readme/variable/dist/index.js
114575
+ var variable_dist = __webpack_require__(4355);
114576
+ var variable_dist_default = /*#__PURE__*/__webpack_require__.n(variable_dist);
114577
+ ;// ./node_modules/rehype-parse/lib/index.js
114578
+ /**
114579
+ * @import {Root} from 'hast'
114580
+ * @import {Options as FromHtmlOptions} from 'hast-util-from-html'
114581
+ * @import {Parser, Processor} from 'unified'
114582
+ */
114583
+
114584
+ /**
114585
+ * @typedef {Omit<FromHtmlOptions, 'onerror'> & RehypeParseFields} Options
114586
+ * Configuration.
114587
+ *
114588
+ * @typedef RehypeParseFields
114589
+ * Extra fields.
114590
+ * @property {boolean | null | undefined} [emitParseErrors=false]
114591
+ * Whether to emit parse errors while parsing (default: `false`).
114592
+ *
114593
+ * > 👉 **Note**: parse errors are currently being added to HTML.
114594
+ * > Not all errors emitted by parse5 (or us) are specced yet.
114595
+ * > Some documentation may still be missing.
114596
+ */
114597
+
114598
+
114599
+
114600
+ /**
114601
+ * Plugin to add support for parsing from HTML.
114602
+ *
114603
+ * > 👉 **Note**: this is not an XML parser.
114604
+ * > It supports SVG as embedded in HTML.
114605
+ * > It does not support the features available in XML.
114606
+ * > Passing SVG files might break but fragments of modern SVG should be fine.
114607
+ * > Use [`xast-util-from-xml`][xast-util-from-xml] to parse XML.
114608
+ *
114609
+ * @param {Options | null | undefined} [options]
114610
+ * Configuration (optional).
114611
+ * @returns {undefined}
114612
+ * Nothing.
114613
+ */
114614
+ function rehypeParse(options) {
114615
+ /** @type {Processor<Root>} */
114616
+ // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
114617
+ const self = this
114618
+ const {emitParseErrors, ...settings} = {...self.data('settings'), ...options}
114619
+
114620
+ self.parser = parser
114621
+
114622
+ /**
114623
+ * @type {Parser<Root>}
114624
+ */
114625
+ function parser(document, file) {
114626
+ return fromHtml(document, {
114627
+ ...settings,
114628
+ onerror: emitParseErrors
114629
+ ? function (message) {
114630
+ if (file.path) {
114631
+ message.name = file.path + ':' + message.name
114632
+ message.file = file.path
114633
+ }
114634
+
114635
+ file.messages.push(message)
114636
+ }
114637
+ : undefined
114638
+ })
114639
+ }
114640
+ }
114641
+
114642
+ ;// ./lib/mdast-util/empty-task-list-item/index.ts
114643
+ /**
114644
+ * Normalizes list items that are written as only `[ ]` or `[x]` into GFM task
114645
+ * list items during parse, but only when at least one whitespace character
114646
+ * follows the closing bracket (`]`). This matches legacy behaviour for checkboxes
114647
+ *
114648
+ * The issue is `remark-gfm` does not actually classify these as task items when they have no content
114649
+ * after the checkbox, which leaves them as plain text (`"[ ]"`). So a custom extension is needed to
114650
+ * treat these as task items
114651
+ */
114652
+ function exitListItemWithEmptyTaskListItem(token) {
114653
+ const node = this.stack[this.stack.length - 1];
114654
+ if (node &&
114655
+ node.type === 'listItem' &&
114656
+ typeof node.checked !== 'boolean') {
114657
+ const listItem = node;
114658
+ const head = listItem.children[0];
114659
+ if (head && head.type === 'paragraph' && head.children.length === 1) {
114660
+ const text = head.children[0];
114661
+ if (text.type === 'text') {
114662
+ const hasTrailingWhitespace = typeof head.position?.end.offset === 'number' &&
114663
+ typeof text.position?.end.offset === 'number' &&
114664
+ head.position.end.offset > text.position.end.offset;
114665
+ if (!hasTrailingWhitespace) {
114666
+ this.exit(token);
114667
+ return;
114668
+ }
114669
+ const value = text.value;
114670
+ if (value === '[ ]') {
114671
+ listItem.checked = false;
114672
+ head.children = [];
114673
+ }
114674
+ else if (value === '[x]' || value === '[X]') {
114675
+ listItem.checked = true;
114676
+ head.children = [];
114677
+ }
114678
+ }
114679
+ }
114680
+ }
114681
+ this.exit(token);
114682
+ }
114683
+ function emptyTaskListItemFromMarkdown() {
114684
+ return {
114685
+ exit: {
114686
+ listItem: exitListItemWithEmptyTaskListItem,
114687
+ },
114688
+ };
114689
+ }
114690
+
114691
+ ;// ./lib/mdast-util/legacy-variable/index.ts
114692
+
114693
+ const contextMap = new WeakMap();
114694
+ function findlegacyVariableToken() {
114695
+ // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
114696
+ const events = this.tokenStack;
114697
+ for (let i = events.length - 1; i >= 0; i -= 1) {
114698
+ const token = events[i][0];
114699
+ if (token.type === 'legacyVariable')
114700
+ return token;
114701
+ }
114702
+ return undefined;
114703
+ }
114704
+ function enterlegacyVariable(token) {
114705
+ contextMap.set(token, { value: '' });
114706
+ }
114707
+ function exitlegacyVariableValue(token) {
114708
+ const variableToken = findlegacyVariableToken.call(this);
114709
+ if (!variableToken)
114710
+ return;
114711
+ const ctx = contextMap.get(variableToken);
114712
+ // Build up the variable characters
114713
+ if (ctx)
114714
+ ctx.value += this.sliceSerialize(token);
114715
+ }
114716
+ function exitlegacyVariable(token) {
114717
+ const ctx = contextMap.get(token);
114718
+ const serialized = this.sliceSerialize(token);
114719
+ const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
114720
+ ? serialized.slice(2, -2)
114721
+ : ctx?.value ?? '';
114722
+ const nodePosition = {
114723
+ start: {
114724
+ offset: token.start.offset,
114725
+ line: token.start.line,
114726
+ column: token.start.column,
114727
+ },
114728
+ end: {
114729
+ offset: token.end.offset,
114730
+ line: token.end.line,
114731
+ column: token.end.column,
114732
+ },
114733
+ };
114734
+ if (variableName.startsWith('glossary:')) {
114735
+ const term = variableName.slice('glossary:'.length).trim();
114736
+ this.enter({
114737
+ type: NodeTypes.glossary,
114738
+ data: {
114739
+ hName: 'Glossary',
114740
+ hProperties: { term },
114741
+ },
114742
+ children: [{ type: 'text', value: term }],
114743
+ position: nodePosition,
114744
+ }, token);
114745
+ this.exit(token);
114746
+ contextMap.delete(token);
114747
+ return;
114748
+ }
114749
+ this.enter({
114750
+ type: NodeTypes.variable,
114751
+ data: {
114752
+ hName: 'Variable',
114753
+ hProperties: { name: variableName.trim(), isLegacy: true },
114754
+ },
114755
+ value: `<<${variableName}>>`,
114756
+ }, token);
114757
+ this.exit(token);
114758
+ contextMap.delete(token);
114759
+ }
114760
+ function legacyVariableFromMarkdown() {
114761
+ return {
114762
+ enter: {
114763
+ legacyVariable: enterlegacyVariable,
114764
+ },
114765
+ exit: {
114766
+ legacyVariableValue: exitlegacyVariableValue,
114767
+ legacyVariable: exitlegacyVariable,
114768
+ },
114769
+ };
114770
+ }
114771
+
114772
+ ;// ./node_modules/micromark-util-symbol/lib/codes.js
114773
+ /**
114774
+ * Character codes.
114775
+ *
114776
+ * This module is compiled away!
114777
+ *
114778
+ * micromark works based on character codes.
114779
+ * This module contains constants for the ASCII block and the replacement
114780
+ * character.
114781
+ * A couple of them are handled in a special way, such as the line endings
114782
+ * (CR, LF, and CR+LF, commonly known as end-of-line: EOLs), the tab (horizontal
114783
+ * tab) and its expansion based on what column it’s at (virtual space),
114784
+ * and the end-of-file (eof) character.
114785
+ * As values are preprocessed before handling them, the actual characters LF,
114786
+ * CR, HT, and NUL (which is present as the replacement character), are
114787
+ * guaranteed to not exist.
114788
+ *
114789
+ * Unicode basic latin block.
114790
+ */
114791
+ const codes = /** @type {const} */ ({
114792
+ carriageReturn: -5,
114793
+ lineFeed: -4,
114794
+ carriageReturnLineFeed: -3,
114795
+ horizontalTab: -2,
114796
+ virtualSpace: -1,
114797
+ eof: null,
114798
+ nul: 0,
114799
+ soh: 1,
114800
+ stx: 2,
114801
+ etx: 3,
114802
+ eot: 4,
114803
+ enq: 5,
114804
+ ack: 6,
114805
+ bel: 7,
114806
+ bs: 8,
114807
+ ht: 9, // `\t`
114808
+ lf: 10, // `\n`
114809
+ vt: 11, // `\v`
114810
+ ff: 12, // `\f`
114811
+ cr: 13, // `\r`
114812
+ so: 14,
114813
+ si: 15,
114814
+ dle: 16,
114815
+ dc1: 17,
114816
+ dc2: 18,
114817
+ dc3: 19,
114818
+ dc4: 20,
114819
+ nak: 21,
114820
+ syn: 22,
114821
+ etb: 23,
114822
+ can: 24,
114823
+ em: 25,
114824
+ sub: 26,
114825
+ esc: 27,
114826
+ fs: 28,
114827
+ gs: 29,
114828
+ rs: 30,
114829
+ us: 31,
114830
+ space: 32,
114831
+ exclamationMark: 33, // `!`
114832
+ quotationMark: 34, // `"`
114833
+ numberSign: 35, // `#`
114834
+ dollarSign: 36, // `$`
114835
+ percentSign: 37, // `%`
114836
+ ampersand: 38, // `&`
114837
+ apostrophe: 39, // `'`
114838
+ leftParenthesis: 40, // `(`
114839
+ rightParenthesis: 41, // `)`
114840
+ asterisk: 42, // `*`
114841
+ plusSign: 43, // `+`
114842
+ comma: 44, // `,`
114843
+ dash: 45, // `-`
114844
+ dot: 46, // `.`
114845
+ slash: 47, // `/`
114846
+ digit0: 48, // `0`
114847
+ digit1: 49, // `1`
114848
+ digit2: 50, // `2`
114849
+ digit3: 51, // `3`
114850
+ digit4: 52, // `4`
114851
+ digit5: 53, // `5`
114852
+ digit6: 54, // `6`
114853
+ digit7: 55, // `7`
114854
+ digit8: 56, // `8`
114855
+ digit9: 57, // `9`
114856
+ colon: 58, // `:`
114857
+ semicolon: 59, // `;`
114858
+ lessThan: 60, // `<`
114859
+ equalsTo: 61, // `=`
114860
+ greaterThan: 62, // `>`
114861
+ questionMark: 63, // `?`
114862
+ atSign: 64, // `@`
114863
+ uppercaseA: 65, // `A`
114864
+ uppercaseB: 66, // `B`
114865
+ uppercaseC: 67, // `C`
114866
+ uppercaseD: 68, // `D`
114867
+ uppercaseE: 69, // `E`
114868
+ uppercaseF: 70, // `F`
114869
+ uppercaseG: 71, // `G`
114870
+ uppercaseH: 72, // `H`
114871
+ uppercaseI: 73, // `I`
114872
+ uppercaseJ: 74, // `J`
114873
+ uppercaseK: 75, // `K`
114874
+ uppercaseL: 76, // `L`
114875
+ uppercaseM: 77, // `M`
114876
+ uppercaseN: 78, // `N`
114877
+ uppercaseO: 79, // `O`
114878
+ uppercaseP: 80, // `P`
114879
+ uppercaseQ: 81, // `Q`
114880
+ uppercaseR: 82, // `R`
114881
+ uppercaseS: 83, // `S`
114882
+ uppercaseT: 84, // `T`
114883
+ uppercaseU: 85, // `U`
114884
+ uppercaseV: 86, // `V`
114885
+ uppercaseW: 87, // `W`
114886
+ uppercaseX: 88, // `X`
114887
+ uppercaseY: 89, // `Y`
114888
+ uppercaseZ: 90, // `Z`
114889
+ leftSquareBracket: 91, // `[`
114890
+ backslash: 92, // `\`
114891
+ rightSquareBracket: 93, // `]`
114892
+ caret: 94, // `^`
114893
+ underscore: 95, // `_`
114894
+ graveAccent: 96, // `` ` ``
114895
+ lowercaseA: 97, // `a`
114896
+ lowercaseB: 98, // `b`
114897
+ lowercaseC: 99, // `c`
114898
+ lowercaseD: 100, // `d`
114899
+ lowercaseE: 101, // `e`
114900
+ lowercaseF: 102, // `f`
114901
+ lowercaseG: 103, // `g`
114902
+ lowercaseH: 104, // `h`
114903
+ lowercaseI: 105, // `i`
114904
+ lowercaseJ: 106, // `j`
114905
+ lowercaseK: 107, // `k`
114906
+ lowercaseL: 108, // `l`
114907
+ lowercaseM: 109, // `m`
114908
+ lowercaseN: 110, // `n`
114909
+ lowercaseO: 111, // `o`
114910
+ lowercaseP: 112, // `p`
114911
+ lowercaseQ: 113, // `q`
114912
+ lowercaseR: 114, // `r`
114913
+ lowercaseS: 115, // `s`
114914
+ lowercaseT: 116, // `t`
114915
+ lowercaseU: 117, // `u`
114916
+ lowercaseV: 118, // `v`
114917
+ lowercaseW: 119, // `w`
114918
+ lowercaseX: 120, // `x`
114919
+ lowercaseY: 121, // `y`
114920
+ lowercaseZ: 122, // `z`
114921
+ leftCurlyBrace: 123, // `{`
114922
+ verticalBar: 124, // `|`
114923
+ rightCurlyBrace: 125, // `}`
114924
+ tilde: 126, // `~`
114925
+ del: 127,
114926
+ // Unicode Specials block.
114927
+ byteOrderMarker: 65_279,
114928
+ // Unicode Specials block.
114929
+ replacementCharacter: 65_533 // `�`
114930
+ })
114931
+
114932
+ ;// ./lib/micromark/legacy-variable/syntax.ts
114818
114933
 
114819
114934
 
114820
- function isHeading(node) {
114821
- return /^h[1-6]$/.test(node.tagName);
114935
+ function isAllowedValueChar(code) {
114936
+ return (code !== null &&
114937
+ code !== codes.lessThan &&
114938
+ code !== codes.greaterThan &&
114939
+ !markdownLineEnding(code));
114822
114940
  }
114823
- function textContent(node) {
114824
- if (node.type === 'text')
114825
- return node.value;
114826
- // Process variable nodes by using their variable name for the id generation
114827
- if (node.type === 'element' && node.tagName === 'variable' && node.properties?.name) {
114828
- if (node.properties.isLegacy) {
114829
- return node.properties.name;
114941
+ const legacyVariableConstruct = {
114942
+ name: 'legacyVariable',
114943
+ tokenize,
114944
+ };
114945
+ function tokenize(effects, ok, nok) {
114946
+ let hasValue = false;
114947
+ const start = (code) => {
114948
+ if (code !== codes.lessThan)
114949
+ return nok(code);
114950
+ effects.enter('legacyVariable');
114951
+ effects.enter('legacyVariableMarkerStart');
114952
+ effects.consume(code); // <
114953
+ return open2;
114954
+ };
114955
+ const open2 = (code) => {
114956
+ if (code !== codes.lessThan)
114957
+ return nok(code);
114958
+ effects.consume(code); // <<
114959
+ effects.exit('legacyVariableMarkerStart');
114960
+ effects.enter('legacyVariableValue');
114961
+ return value;
114962
+ };
114963
+ const value = (code) => {
114964
+ if (code === codes.greaterThan) {
114965
+ if (!hasValue)
114966
+ return nok(code);
114967
+ effects.exit('legacyVariableValue');
114968
+ effects.enter('legacyVariableMarkerEnd');
114969
+ effects.consume(code); // >
114970
+ return close2;
114830
114971
  }
114831
- return `user.${node.properties.name}`;
114832
- }
114833
- if ('children' in node)
114834
- return node.children.map(textContent).join('');
114835
- return '';
114972
+ if (!isAllowedValueChar(code))
114973
+ return nok(code);
114974
+ hasValue = true;
114975
+ effects.consume(code);
114976
+ return value;
114977
+ };
114978
+ const close2 = (code) => {
114979
+ if (code !== codes.greaterThan)
114980
+ return nok(code);
114981
+ effects.consume(code); // >>
114982
+ effects.exit('legacyVariableMarkerEnd');
114983
+ effects.exit('legacyVariable');
114984
+ return ok;
114985
+ };
114986
+ return start;
114987
+ }
114988
+ function legacyVariable() {
114989
+ return {
114990
+ text: { [codes.lessThan]: legacyVariableConstruct },
114991
+ };
114836
114992
  }
114837
- /**
114838
- * Rehype plugin that constructs ids for headings
114839
- * Id's are used to construct slug anchor links & Table of Contents during rendering
114840
- * Use the text / nodes that make up the heading to generate the id
114841
- */
114842
- const generateSlugForHeadings = () => (tree) => {
114843
- const slugger = new BananaSlug();
114844
- visit(tree, 'element', (node) => {
114845
- if (isHeading(node) && !node.properties.id) {
114846
- const text = node.children.map(textContent).join('');
114847
- node.properties.id = slugger.slug(text);
114848
- }
114849
- });
114850
- return tree;
114851
- };
114852
- /* harmony default export */ const heading_slugs = (generateSlugForHeadings);
114853
-
114854
- // EXTERNAL MODULE: ./node_modules/@readme/variable/dist/index.js
114855
- var variable_dist = __webpack_require__(4355);
114856
- var variable_dist_default = /*#__PURE__*/__webpack_require__.n(variable_dist);
114857
- ;// ./node_modules/rehype-parse/lib/index.js
114858
- /**
114859
- * @import {Root} from 'hast'
114860
- * @import {Options as FromHtmlOptions} from 'hast-util-from-html'
114861
- * @import {Parser, Processor} from 'unified'
114862
- */
114863
-
114864
- /**
114865
- * @typedef {Omit<FromHtmlOptions, 'onerror'> & RehypeParseFields} Options
114866
- * Configuration.
114867
- *
114868
- * @typedef RehypeParseFields
114869
- * Extra fields.
114870
- * @property {boolean | null | undefined} [emitParseErrors=false]
114871
- * Whether to emit parse errors while parsing (default: `false`).
114872
- *
114873
- * > 👉 **Note**: parse errors are currently being added to HTML.
114874
- * > Not all errors emitted by parse5 (or us) are specced yet.
114875
- * > Some documentation may still be missing.
114876
- */
114877
-
114878
-
114879
114993
 
114994
+ ;// ./lib/micromark/legacy-variable/index.ts
114880
114995
  /**
114881
- * Plugin to add support for parsing from HTML.
114882
- *
114883
- * > 👉 **Note**: this is not an XML parser.
114884
- * > It supports SVG as embedded in HTML.
114885
- * > It does not support the features available in XML.
114886
- * > Passing SVG files might break but fragments of modern SVG should be fine.
114887
- * > Use [`xast-util-from-xml`][xast-util-from-xml] to parse XML.
114888
- *
114889
- * @param {Options | null | undefined} [options]
114890
- * Configuration (optional).
114891
- * @returns {undefined}
114892
- * Nothing.
114996
+ * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
114893
114997
  */
114894
- function rehypeParse(options) {
114895
- /** @type {Processor<Root>} */
114896
- // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
114897
- const self = this
114898
- const {emitParseErrors, ...settings} = {...self.data('settings'), ...options}
114899
-
114900
- self.parser = parser
114901
-
114902
- /**
114903
- * @type {Parser<Root>}
114904
- */
114905
- function parser(document, file) {
114906
- return fromHtml(document, {
114907
- ...settings,
114908
- onerror: emitParseErrors
114909
- ? function (message) {
114910
- if (file.path) {
114911
- message.name = file.path + ':' + message.name
114912
- message.file = file.path
114913
- }
114914
114998
 
114915
- file.messages.push(message)
114916
- }
114917
- : undefined
114918
- })
114919
- }
114920
- }
114921
114999
 
114922
115000
  ;// ./node_modules/entities/lib/esm/generated/encode-html.js
114923
115001
  // Generated using scripts/write-encode-map.ts
@@ -115224,349 +115302,6 @@ function looseHtmlEntityFromMarkdown() {
115224
115302
  */
115225
115303
 
115226
115304
 
115227
- ;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
115228
-
115229
- // Marker patterns for multi-node emphasis detection
115230
- const MARKER_PATTERNS = [
115231
- { isBold: true, marker: '**' },
115232
- { isBold: true, marker: '__' },
115233
- { isBold: false, marker: '*' },
115234
- { isBold: false, marker: '_' },
115235
- ];
115236
- // Patterns to detect for bold (** and __) and italic (* and _) syntax:
115237
- // Bold: ** text**, **text **, word** text**, ** text **
115238
- // Italic: * text*, *text *, word* text*, * text *
115239
- // Same patterns for underscore variants
115240
- // We use separate patterns for each marker type to allow this flexibility.
115241
- // Pattern for ** bold **
115242
- // Groups: 1=wordBefore, 2=marker, 3=contentWithSpaceAfter, 4=trailingSpace1, 5=contentWithSpaceBefore, 6=trailingSpace2, 7=afterChar
115243
- // trailingSpace1 is for "** text **" pattern, trailingSpace2 is for "**text **" pattern
115244
- const asteriskBoldRegex = /([^*\s]+)?\s*(\*\*)(?:\s+((?:[^*\n]|\*(?!\*))+?)(\s*)\2|((?:[^*\n]|\*(?!\*))+?)(\s+)\2)(\S|$)?/g;
115245
- // Pattern for __ bold __
115246
- const underscoreBoldRegex = /([^_\s]+)?\s*(__)(?:\s+((?:__(?! )|_(?!_)|[^_\n])+?)(\s*)\2|((?:__(?! )|_(?!_)|[^_\n])+?)(\s+)\2)(\S|$)?/g;
115247
- // Pattern for * italic *
115248
- const asteriskItalicRegex = /([^*\s]+)?\s*(\*)(?!\*)(?:\s+([^*\n]+?)(\s*)\2|([^*\n]+?)(\s+)\2)(\S|$)?/g;
115249
- // Pattern for _ italic _
115250
- const underscoreItalicRegex = /([^_\s]+)?\s*(_)(?!_)(?:\s+((?:[^_\n]|_(?! ))+?)(\s*)\2|((?:[^_\n]|_(?! ))+?)(\s+)\2)(\S|$)?/g;
115251
- // CommonMark ignores intraword underscores or asteriks, but we want to italicize/bold the inner part
115252
- // Pattern for intraword _word_ in words like hello_world_
115253
- const intrawordUnderscoreItalicRegex = /(\w)_(?!_)([a-zA-Z0-9]+)_(?![\w_])/g;
115254
- // Pattern for intraword __word__ in words like hello__world__
115255
- const intrawordUnderscoreBoldRegex = /(\w)__([a-zA-Z0-9]+)__(?![\w_])/g;
115256
- // Pattern for intraword *word* in words like hello*world*
115257
- const intrawordAsteriskItalicRegex = /(\w)\*(?!\*)([a-zA-Z0-9]+)\*(?![\w*])/g;
115258
- // Pattern for intraword **word** in words like hello**world**
115259
- const intrawordAsteriskBoldRegex = /(\w)\*\*([a-zA-Z0-9]+)\*\*(?![\w*])/g;
115260
- /**
115261
- * Finds opening emphasis marker in a text value.
115262
- * Returns marker info if found, null otherwise.
115263
- */
115264
- function findOpeningMarker(text) {
115265
- const results = MARKER_PATTERNS.map(({ isBold, marker }) => {
115266
- if (marker === '*' && text.startsWith('**'))
115267
- return null;
115268
- if (marker === '_' && text.startsWith('__'))
115269
- return null;
115270
- if (text.startsWith(marker) && text.length > marker.length) {
115271
- return { isBold, marker, textAfter: text.slice(marker.length), textBefore: '' };
115272
- }
115273
- const idx = text.indexOf(marker);
115274
- if (idx > 0 && !/\s/.test(text[idx - 1])) {
115275
- if (marker === '*' && text.slice(idx).startsWith('**'))
115276
- return null;
115277
- if (marker === '_' && text.slice(idx).startsWith('__'))
115278
- return null;
115279
- const after = text.slice(idx + marker.length);
115280
- if (after.length > 0) {
115281
- return { isBold, marker, textAfter: after, textBefore: text.slice(0, idx) };
115282
- }
115283
- }
115284
- return null;
115285
- });
115286
- return results.find(r => r !== null) ?? null;
115287
- }
115288
- /**
115289
- * Finds the end/closing marker in a text node for multi-node emphasis.
115290
- */
115291
- function findEndMarker(text, marker) {
115292
- const spacePattern = ` ${marker}`;
115293
- const spaceIdx = text.indexOf(spacePattern);
115294
- if (spaceIdx >= 0) {
115295
- if (marker === '*' && text.slice(spaceIdx + 1).startsWith('**'))
115296
- return null;
115297
- if (marker === '_' && text.slice(spaceIdx + 1).startsWith('__'))
115298
- return null;
115299
- return {
115300
- textAfter: text.slice(spaceIdx + spacePattern.length),
115301
- textBefore: text.slice(0, spaceIdx),
115302
- };
115303
- }
115304
- if (text.startsWith(marker)) {
115305
- if (marker === '*' && text.startsWith('**'))
115306
- return null;
115307
- if (marker === '_' && text.startsWith('__'))
115308
- return null;
115309
- return {
115310
- textAfter: text.slice(marker.length),
115311
- textBefore: '',
115312
- };
115313
- }
115314
- return null;
115315
- }
115316
- /**
115317
- * Scan children for an opening emphasis marker in a text node.
115318
- */
115319
- function findOpeningInChildren(children) {
115320
- let result = null;
115321
- children.some((child, idx) => {
115322
- if (child.type !== 'text')
115323
- return false;
115324
- const found = findOpeningMarker(child.value);
115325
- if (found) {
115326
- result = { idx, opening: found };
115327
- return true;
115328
- }
115329
- return false;
115330
- });
115331
- return result;
115332
- }
115333
- /**
115334
- * Scan children (after openingIdx) for a closing emphasis marker.
115335
- */
115336
- function findClosingInChildren(children, openingIdx, marker) {
115337
- let result = null;
115338
- children.slice(openingIdx + 1).some((child, relativeIdx) => {
115339
- if (child.type !== 'text')
115340
- return false;
115341
- const found = findEndMarker(child.value, marker);
115342
- if (found) {
115343
- result = { closingIdx: openingIdx + 1 + relativeIdx, closing: found };
115344
- return true;
115345
- }
115346
- return false;
115347
- });
115348
- return result;
115349
- }
115350
- /**
115351
- * Build the replacement nodes for a matched emphasis pair.
115352
- */
115353
- function buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx }) {
115354
- const newNodes = [];
115355
- if (opening.textBefore) {
115356
- newNodes.push({ type: 'text', value: `${opening.textBefore} ` });
115357
- }
115358
- const emphasisChildren = [];
115359
- const openingText = opening.textAfter.replace(/^\s+/, '');
115360
- if (openingText) {
115361
- emphasisChildren.push({ type: 'text', value: openingText });
115362
- }
115363
- container.children.slice(openingIdx + 1, closingIdx).forEach(child => {
115364
- emphasisChildren.push(child);
115365
- });
115366
- const closingText = closing.textBefore.replace(/\s+$/, '');
115367
- if (closingText) {
115368
- emphasisChildren.push({ type: 'text', value: closingText });
115369
- }
115370
- if (emphasisChildren.length > 0) {
115371
- const emphasisNode = opening.isBold
115372
- ? { type: 'strong', children: emphasisChildren }
115373
- : { type: 'emphasis', children: emphasisChildren };
115374
- newNodes.push(emphasisNode);
115375
- }
115376
- if (closing.textAfter) {
115377
- newNodes.push({ type: 'text', value: closing.textAfter });
115378
- }
115379
- return newNodes;
115380
- }
115381
- /**
115382
- * Find and transform one multi-node emphasis pair in the container.
115383
- * Returns true if a pair was found and transformed, false otherwise.
115384
- */
115385
- function processOneEmphasisPair(container) {
115386
- const openingResult = findOpeningInChildren(container.children);
115387
- if (!openingResult)
115388
- return false;
115389
- const { idx: openingIdx, opening } = openingResult;
115390
- const closingResult = findClosingInChildren(container.children, openingIdx, opening.marker);
115391
- if (!closingResult)
115392
- return false;
115393
- const { closingIdx, closing } = closingResult;
115394
- const newNodes = buildReplacementNodes(container, { opening, openingIdx, closing, closingIdx });
115395
- const deleteCount = closingIdx - openingIdx + 1;
115396
- container.children.splice(openingIdx, deleteCount, ...newNodes);
115397
- return true;
115398
- }
115399
- /**
115400
- * Handle malformed emphasis that spans multiple AST nodes.
115401
- * E.g., "**bold [link](url)**" where markers are in different text nodes.
115402
- */
115403
- function visitMultiNodeEmphasis(tree) {
115404
- const containerTypes = ['paragraph', 'heading', 'tableCell', 'listItem', 'blockquote'];
115405
- visit(tree, node => {
115406
- if (!containerTypes.includes(node.type))
115407
- return;
115408
- if (!('children' in node) || !Array.isArray(node.children))
115409
- return;
115410
- const container = node;
115411
- let foundPair = true;
115412
- while (foundPair) {
115413
- foundPair = processOneEmphasisPair(container);
115414
- }
115415
- });
115416
- }
115417
- /**
115418
- * A remark plugin that normalizes malformed bold and italic markers in text nodes.
115419
- * Detects patterns like `** bold**`, `Hello** Wrong Bold**`, `__ bold__`, `Hello__ Wrong Bold__`,
115420
- * `* italic*`, `Hello* Wrong Italic*`, `_ italic_`, or `Hello_ Wrong Italic_`
115421
- * and converts them to proper strong/emphasis nodes, matching the behavior of the legacy rdmd engine.
115422
- *
115423
- * Supports both asterisk (`**bold**`, `*italic*`) and underscore (`__bold__`, `_italic_`) syntax.
115424
- * Also supports snake_case content like `** some_snake_case**`.
115425
- *
115426
- * This runs after remark-parse, which (in v11+) is strict and doesn't parse
115427
- * malformed emphasis syntax. This plugin post-processes the AST to handle these cases.
115428
- */
115429
- const normalizeEmphasisAST = () => (tree) => {
115430
- visit(tree, 'text', function visitor(node, index, parent) {
115431
- if (index === undefined || !parent)
115432
- return undefined;
115433
- // Skip if inside code blocks or inline code
115434
- if (parent.type === 'inlineCode' || parent.type === 'code') {
115435
- return undefined;
115436
- }
115437
- const text = node.value;
115438
- const allMatches = [];
115439
- [...text.matchAll(asteriskBoldRegex)].forEach(match => {
115440
- allMatches.push({ isBold: true, marker: '**', match });
115441
- });
115442
- [...text.matchAll(underscoreBoldRegex)].forEach(match => {
115443
- allMatches.push({ isBold: true, marker: '__', match });
115444
- });
115445
- [...text.matchAll(asteriskItalicRegex)].forEach(match => {
115446
- allMatches.push({ isBold: false, marker: '*', match });
115447
- });
115448
- [...text.matchAll(underscoreItalicRegex)].forEach(match => {
115449
- allMatches.push({ isBold: false, marker: '_', match });
115450
- });
115451
- [...text.matchAll(intrawordUnderscoreItalicRegex)].forEach(match => {
115452
- allMatches.push({ isBold: false, isIntraword: true, marker: '_', match });
115453
- });
115454
- [...text.matchAll(intrawordUnderscoreBoldRegex)].forEach(match => {
115455
- allMatches.push({ isBold: true, isIntraword: true, marker: '__', match });
115456
- });
115457
- [...text.matchAll(intrawordAsteriskItalicRegex)].forEach(match => {
115458
- allMatches.push({ isBold: false, isIntraword: true, marker: '*', match });
115459
- });
115460
- [...text.matchAll(intrawordAsteriskBoldRegex)].forEach(match => {
115461
- allMatches.push({ isBold: true, isIntraword: true, marker: '**', match });
115462
- });
115463
- if (allMatches.length === 0)
115464
- return undefined;
115465
- allMatches.sort((a, b) => (a.match.index ?? 0) - (b.match.index ?? 0));
115466
- const filteredMatches = [];
115467
- let lastEnd = 0;
115468
- allMatches.forEach(info => {
115469
- const start = info.match.index ?? 0;
115470
- const end = start + info.match[0].length;
115471
- if (start >= lastEnd) {
115472
- filteredMatches.push(info);
115473
- lastEnd = end;
115474
- }
115475
- });
115476
- if (filteredMatches.length === 0)
115477
- return undefined;
115478
- const parts = [];
115479
- let lastIndex = 0;
115480
- filteredMatches.forEach(({ isBold, isIntraword, marker, match }) => {
115481
- const matchIndex = match.index ?? 0;
115482
- const fullMatch = match[0];
115483
- if (isIntraword) {
115484
- // handles cases like hello_world_ where we only want to italicize 'world'
115485
- const charBefore = match[1] || ''; // e.g., "l" in "hello_world_"
115486
- const content = match[2]; // e.g., "world"
115487
- const combinedBefore = text.slice(lastIndex, matchIndex) + charBefore;
115488
- if (combinedBefore) {
115489
- parts.push({ type: 'text', value: combinedBefore });
115490
- }
115491
- if (isBold) {
115492
- parts.push({
115493
- type: 'strong',
115494
- children: [{ type: 'text', value: content }],
115495
- });
115496
- }
115497
- else {
115498
- parts.push({
115499
- type: 'emphasis',
115500
- children: [{ type: 'text', value: content }],
115501
- });
115502
- }
115503
- lastIndex = matchIndex + fullMatch.length;
115504
- return;
115505
- }
115506
- if (matchIndex > lastIndex) {
115507
- const beforeText = text.slice(lastIndex, matchIndex);
115508
- if (beforeText) {
115509
- parts.push({ type: 'text', value: beforeText });
115510
- }
115511
- }
115512
- const wordBefore = match[1]; // e.g., "Hello" in "Hello** Wrong Bold**"
115513
- const contentWithSpaceAfter = match[3]; // Content when there's a space after opening markers
115514
- const trailingSpace1 = match[4] || ''; // Space before closing markers (for "** text **" pattern)
115515
- const contentWithSpaceBefore = match[5]; // Content when there's only a space before closing markers
115516
- const trailingSpace2 = match[6] || ''; // Space before closing markers (for "**text **" pattern)
115517
- const trailingSpace = trailingSpace1 || trailingSpace2; // Combined trailing space
115518
- const content = (contentWithSpaceAfter || contentWithSpaceBefore || '').trim();
115519
- const afterChar = match[7]; // Character after closing markers (if any)
115520
- const markerPos = fullMatch.indexOf(marker);
115521
- const spacesBeforeMarkers = wordBefore
115522
- ? fullMatch.slice(wordBefore.length, markerPos)
115523
- : fullMatch.slice(0, markerPos);
115524
- const shouldAddSpace = !!contentWithSpaceAfter && !!wordBefore && !spacesBeforeMarkers;
115525
- if (wordBefore) {
115526
- const spacing = spacesBeforeMarkers + (shouldAddSpace ? ' ' : '');
115527
- parts.push({ type: 'text', value: wordBefore + spacing });
115528
- }
115529
- else if (spacesBeforeMarkers) {
115530
- parts.push({ type: 'text', value: spacesBeforeMarkers });
115531
- }
115532
- if (content) {
115533
- if (isBold) {
115534
- parts.push({
115535
- type: 'strong',
115536
- children: [{ type: 'text', value: content }],
115537
- });
115538
- }
115539
- else {
115540
- parts.push({
115541
- type: 'emphasis',
115542
- children: [{ type: 'text', value: content }],
115543
- });
115544
- }
115545
- }
115546
- if (afterChar) {
115547
- const prefix = trailingSpace ? ' ' : '';
115548
- parts.push({ type: 'text', value: prefix + afterChar });
115549
- }
115550
- lastIndex = matchIndex + fullMatch.length;
115551
- });
115552
- if (lastIndex < text.length) {
115553
- const remainingText = text.slice(lastIndex);
115554
- if (remainingText) {
115555
- parts.push({ type: 'text', value: remainingText });
115556
- }
115557
- }
115558
- if (parts.length > 0) {
115559
- parent.children.splice(index, 1, ...parts);
115560
- return [SKIP, index + parts.length];
115561
- }
115562
- return undefined;
115563
- });
115564
- // Handle malformed emphasis spanning multiple nodes (e.g., **text [link](url) **)
115565
- visitMultiNodeEmphasis(tree);
115566
- return tree;
115567
- };
115568
- /* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
115569
-
115570
115305
  ;// ./processor/transform/mdxish/magic-blocks/patterns.ts
115571
115306
  /** Matches HTML tags (open, close, self-closing) with optional attributes. */
115572
115307
  const HTML_TAG_RE = /<\/?([a-zA-Z][a-zA-Z0-9-]*)((?:[^>"']*(?:"[^"]*"|'[^']*'))*[^>"']*)>/g;
@@ -116184,6 +115919,351 @@ const magicBlockTransformer = (options = {}) => tree => {
116184
115919
  };
116185
115920
  /* harmony default export */ const magic_block_transformer = (magicBlockTransformer);
116186
115921
 
115922
+ ;// ./processor/transform/mdxish/constants.ts
115923
+ /**
115924
+ * Inline component tags handled by mdxish-inline-components.ts.
115925
+ * Also excluded from block-level handling in mdxish-component-blocks.ts.
115926
+ */
115927
+ const constants_INLINE_COMPONENT_TAGS = new Set(['Anchor']);
115928
+
115929
+ ;// ./processor/transform/mdxish/mdxish-component-blocks.ts
115930
+
115931
+
115932
+
115933
+
115934
+
115935
+
115936
+
115937
+ const pascalCaseTagPattern = /^<([A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>([\s\S]*)?$/;
115938
+ const tagAttributePattern = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
115939
+ /**
115940
+ * Maximum number of siblings to scan forward when looking for a closing tag
115941
+ * to avoid scanning too far and degrading performance
115942
+ */
115943
+ const MAX_LOOKAHEAD = 30;
115944
+ /**
115945
+ * Tags that have dedicated transformers and should NOT be handled by this plugin.
115946
+ * These components either have special parsing requirements that the generic component
115947
+ * block transformer cannot handle correctly, or are inline components that we don't
115948
+ * want to convert to mdxJsxFlowElement which is a block level element.
115949
+ */
115950
+ const EXCLUDED_TAGS = new Set(['HTMLBlock', 'Table', 'Glossary', ...constants_INLINE_COMPONENT_TAGS]);
115951
+ const inlineMdProcessor = unified()
115952
+ .data('micromarkExtensions', [legacyVariable()])
115953
+ .data('fromMarkdownExtensions', [legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown()])
115954
+ .use(remarkParse)
115955
+ .use(remarkGfm);
115956
+ const isClosingTag = (value, tag) => value.trim() === `</${tag}>`;
115957
+ /**
115958
+ * Parse markdown content into mdast children nodes.
115959
+ */
115960
+ const parseMdChildren = (value) => {
115961
+ const parsed = inlineMdProcessor.parse(value);
115962
+ return parsed.children || [];
115963
+ };
115964
+ /**
115965
+ * Convert raw attribute string into mdxJsxAttribute entries.
115966
+ * Handles both key-value attributes (theme="info") and boolean attributes (empty).
115967
+ */
115968
+ const parseAttributes = (raw) => {
115969
+ const attributes = [];
115970
+ const attrString = raw.trim();
115971
+ if (!attrString)
115972
+ return attributes;
115973
+ tagAttributePattern.lastIndex = 0;
115974
+ let match = tagAttributePattern.exec(attrString);
115975
+ while (match !== null) {
115976
+ const [, attrName, attrValue] = match;
115977
+ const value = attrValue ? attrValue.replace(/^['"]|['"]$/g, '') : null;
115978
+ attributes.push({ type: 'mdxJsxAttribute', name: attrName, value });
115979
+ match = tagAttributePattern.exec(attrString);
115980
+ }
115981
+ return attributes;
115982
+ };
115983
+ /**
115984
+ * Parse an HTML tag string into structured data.
115985
+ */
115986
+ const parseTag = (value) => {
115987
+ const match = value.match(pascalCaseTagPattern);
115988
+ if (!match)
115989
+ return null;
115990
+ const [, tag, attrString = '', selfClosing = '', contentAfterTag = ''] = match;
115991
+ return {
115992
+ tag,
115993
+ attributes: parseAttributes(attrString),
115994
+ selfClosing: !!selfClosing,
115995
+ contentAfterTag,
115996
+ };
115997
+ };
115998
+ /**
115999
+ * Parse substring content of a node and update the parent's children to include the new nodes.
116000
+ */
116001
+ const parseSibling = (stack, parent, index, sibling) => {
116002
+ const siblingNodes = parseMdChildren(sibling);
116003
+ // The new sibling nodes might contain new components to be processed
116004
+ if (siblingNodes.length > 0) {
116005
+ parent.children.splice(index + 1, 0, ...siblingNodes);
116006
+ stack.push(parent);
116007
+ }
116008
+ };
116009
+ /**
116010
+ * Create an MdxJsxFlowElement node from component data.
116011
+ */
116012
+ const createComponentNode = ({ tag, attributes, children, startPosition, endPosition }) => ({
116013
+ type: 'mdxJsxFlowElement',
116014
+ name: tag,
116015
+ attributes,
116016
+ children,
116017
+ position: {
116018
+ start: startPosition?.start,
116019
+ end: endPosition?.end ?? startPosition?.end,
116020
+ },
116021
+ });
116022
+ /**
116023
+ * Remove a closing tag from a paragraph's children and return the updated paragraph.
116024
+ */
116025
+ const stripClosingTagFromParagraph = (node, tag) => {
116026
+ if (!Array.isArray(node.children))
116027
+ return { paragraph: node, found: false };
116028
+ const children = [...node.children];
116029
+ const closingIndex = children.findIndex(child => child.type === 'html' && isClosingTag(child.value || '', tag));
116030
+ if (closingIndex === -1)
116031
+ return { paragraph: node, found: false };
116032
+ children.splice(closingIndex, 1);
116033
+ // After removing the closing tag, trim trailing whitespace/newlines from the
116034
+ // preceding text node. Remark parses "Hello\n</Callout>" as text("Hello\n") +
116035
+ // html("</Callout>"), and the leftover \n would be converted to <br> in HAST.
116036
+ if (closingIndex > 0) {
116037
+ const prev = children[closingIndex - 1];
116038
+ if (prev.type === 'text') {
116039
+ const trimmed = prev.value.trimEnd();
116040
+ if (trimmed) {
116041
+ prev.value = trimmed;
116042
+ }
116043
+ else {
116044
+ children.splice(closingIndex - 1, 1);
116045
+ }
116046
+ }
116047
+ }
116048
+ return { paragraph: { ...node, children }, found: true };
116049
+ };
116050
+ /**
116051
+ * Scan forward through siblings to find a closing tag.
116052
+ * Handles:
116053
+ * - Exact match HTML siblings (e.g., `</Tag>`)
116054
+ * - HTML siblings with embedded closing tag (e.g., `...\n</Tag>`)
116055
+ * - Paragraph siblings containing the closing tag as a child
116056
+ *
116057
+ * Returns null if not found within MAX_LOOKAHEAD siblings
116058
+ */
116059
+ const scanForClosingTag = (parent, startIndex, tag) => {
116060
+ const closingTagStr = `</${tag}>`;
116061
+ const maxIndex = Math.min(startIndex + MAX_LOOKAHEAD, parent.children.length);
116062
+ let i = startIndex + 1;
116063
+ for (; i < maxIndex; i += 1) {
116064
+ const sibling = parent.children[i];
116065
+ // Check HTML siblings
116066
+ if (sibling.type === 'html') {
116067
+ const siblingValue = sibling.value || '';
116068
+ // Exact match (standalone closing tag)
116069
+ if (isClosingTag(siblingValue, tag)) {
116070
+ return { closingIndex: i, extraClosingChildren: [] };
116071
+ }
116072
+ // Embedded closing tag (closing tag within HTML block content)
116073
+ if (siblingValue.includes(closingTagStr)) {
116074
+ const closeTagPos = siblingValue.indexOf(closingTagStr);
116075
+ const contentBeforeClose = siblingValue.substring(0, closeTagPos).trim();
116076
+ const contentAfterClose = siblingValue.substring(closeTagPos + closingTagStr.length).trim();
116077
+ const extraChildren = contentBeforeClose
116078
+ ? parseMdChildren(contentBeforeClose)
116079
+ : [];
116080
+ return { closingIndex: i, extraClosingChildren: extraChildren, contentAfterClose: contentAfterClose || undefined };
116081
+ }
116082
+ }
116083
+ // Check paragraph siblings
116084
+ if (sibling.type === 'paragraph') {
116085
+ const { paragraph, found } = stripClosingTagFromParagraph(sibling, tag);
116086
+ if (found) {
116087
+ return { closingIndex: i, extraClosingChildren: [], strippedParagraph: paragraph };
116088
+ }
116089
+ }
116090
+ }
116091
+ if (i < parent.children.length) {
116092
+ // eslint-disable-next-line no-console
116093
+ console.warn(`Closing tag </${tag}> not found within ${MAX_LOOKAHEAD} siblings, stopping scan`);
116094
+ }
116095
+ return null;
116096
+ };
116097
+ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
116098
+ parent.children.splice(index, 1, mdxNode);
116099
+ };
116100
+ /**
116101
+ * Transform PascalCase HTML nodes into mdxJsxFlowElement nodes.
116102
+ *
116103
+ * Remark parses unknown/custom component tags as raw HTML nodes.
116104
+ * These are the custom readme MDX syntax for components.
116105
+ * This transformer identifies these patterns and converts them to proper MDX JSX elements so they
116106
+ * can be accurately recognized and rendered later with their component definition code.
116107
+ * Though for some tags, we need to handle them specially
116108
+ *
116109
+ * ## Supported HTML Structures
116110
+ *
116111
+ * ### 1. Self-closing tags
116112
+ * ```
116113
+ * <Component />
116114
+ * ```
116115
+ * Parsed as: `html: "<Component />"`
116116
+ *
116117
+ * ### 2. Self-contained blocks (entire component in single HTML node)
116118
+ * ```
116119
+ * <Button>Click me</Button>
116120
+ * ```
116121
+ * ```
116122
+ * <Component>
116123
+ * <h2>Title</h2>
116124
+ * <p>Content</p>
116125
+ * </Component>
116126
+ * ```
116127
+ * Parsed as: `html: "<Component>\n <h2>Title</h2>\n <p>Content</p>\n</Component>"`
116128
+ * The opening tag, content, and closing tag are all captured in one HTML node.
116129
+ *
116130
+ * ### 3. Multi-sibling components (closing tag in a following sibling)
116131
+ * Handles various structures where the closing tag is in a later sibling, such as:
116132
+ *
116133
+ * #### 3a. Block components (closing tag in sibling paragraph)
116134
+ * ```
116135
+ * <Callout>
116136
+ * Some **markdown** content
116137
+ * </Callout>
116138
+ * ```
116139
+ *
116140
+ * #### 3b. Multi-paragraph components (closing tag several siblings away)
116141
+ * ```
116142
+ * <Callout>
116143
+ *
116144
+ * First paragraph
116145
+ *
116146
+ * Second paragraph
116147
+ * </Callout>
116148
+ * ```
116149
+ *
116150
+ * #### 3c. Nested components split by blank lines (closing tag embedded in HTML sibling)
116151
+ * ```
116152
+ * <Outer>
116153
+ * <Inner>content</Inner>
116154
+ *
116155
+ * <Inner>content</Inner>
116156
+ * </Outer>
116157
+ * ```
116158
+ */
116159
+ const mdxishComponentBlocks = () => tree => {
116160
+ const stack = [tree];
116161
+ const processChildNode = (parent, index) => {
116162
+ const node = parent.children[index];
116163
+ if (!node)
116164
+ return;
116165
+ if ('children' in node && Array.isArray(node.children)) {
116166
+ stack.push(node);
116167
+ }
116168
+ // Only visit HTML nodes with an actual html tag,
116169
+ // which means a potential unparsed MDX component
116170
+ const value = node.value;
116171
+ if (node.type !== 'html' || typeof value !== 'string')
116172
+ return;
116173
+ const parsed = parseTag(value.trim());
116174
+ if (!parsed)
116175
+ return;
116176
+ const { tag, attributes, selfClosing, contentAfterTag = '' } = parsed;
116177
+ // Skip tags that have dedicated transformers
116178
+ if (EXCLUDED_TAGS.has(tag))
116179
+ return;
116180
+ const closingTagStr = `</${tag}>`;
116181
+ // Case 1: Self-closing tag
116182
+ if (selfClosing) {
116183
+ const componentNode = createComponentNode({
116184
+ tag,
116185
+ attributes,
116186
+ children: [],
116187
+ startPosition: node.position,
116188
+ });
116189
+ substituteNodeWithMdxNode(parent, index, componentNode);
116190
+ // Check and parse if there's relevant content after the current closing tag
116191
+ const remainingContent = contentAfterTag.trim();
116192
+ if (remainingContent) {
116193
+ parseSibling(stack, parent, index, remainingContent);
116194
+ }
116195
+ return;
116196
+ }
116197
+ // Case 2: Self-contained block (closing tag in content)
116198
+ if (contentAfterTag.includes(closingTagStr)) {
116199
+ // Find the first closing tag
116200
+ const closingTagIndex = contentAfterTag.indexOf(closingTagStr);
116201
+ const componentInnerContent = contentAfterTag.substring(0, closingTagIndex).trim();
116202
+ const contentAfterClose = contentAfterTag.substring(closingTagIndex + closingTagStr.length).trim();
116203
+ const componentNode = createComponentNode({
116204
+ tag,
116205
+ attributes,
116206
+ children: componentInnerContent ? parseMdChildren(componentInnerContent) : [],
116207
+ startPosition: node.position,
116208
+ });
116209
+ substituteNodeWithMdxNode(parent, index, componentNode);
116210
+ // After the closing tag, there might be more content to be processed
116211
+ if (contentAfterClose) {
116212
+ parseSibling(stack, parent, index, contentAfterClose);
116213
+ }
116214
+ else if (componentNode.children.length > 0) {
116215
+ // The content inside the component block might contain new components to be processed
116216
+ stack.push(componentNode);
116217
+ }
116218
+ return;
116219
+ }
116220
+ // Case 3: Multi-sibling component (closing tag in a following sibling)
116221
+ // Scans forward through siblings to find closing tag in HTML or paragraph nodes
116222
+ const scanResult = scanForClosingTag(parent, index, tag);
116223
+ if (!scanResult)
116224
+ return;
116225
+ const { closingIndex, extraClosingChildren, strippedParagraph, contentAfterClose: remainingAfterClose } = scanResult;
116226
+ const extraChildren = contentAfterTag ? parseMdChildren(contentAfterTag.trimStart()) : [];
116227
+ // Collect all intermediate siblings between opening tag and closing tag
116228
+ const intermediateChildren = parent.children.slice(index + 1, closingIndex);
116229
+ // For paragraph siblings, include the full paragraph (with closing tag stripped)
116230
+ // For HTML siblings, include any content parsed from before the closing tag
116231
+ const closingChildren = strippedParagraph
116232
+ ? (strippedParagraph.children.length > 0 ? [strippedParagraph] : [])
116233
+ : extraClosingChildren;
116234
+ const componentNode = createComponentNode({
116235
+ tag,
116236
+ attributes,
116237
+ children: [...extraChildren, ...intermediateChildren, ...closingChildren],
116238
+ startPosition: node.position,
116239
+ endPosition: parent.children[closingIndex]?.position,
116240
+ });
116241
+ // Remove all nodes from opening tag to closing tag (inclusive) and replace with component node
116242
+ parent.children.splice(index, closingIndex - index + 1, componentNode);
116243
+ // Since we might be merging sibling nodes together and combining content,
116244
+ // there might be new components to process
116245
+ if (componentNode.children.length > 0) {
116246
+ stack.push(componentNode);
116247
+ }
116248
+ // If the closing tag sibling had content after it (e.g., another component opening tag),
116249
+ // re-insert it as a sibling so it can be processed in subsequent iterations
116250
+ if (remainingAfterClose) {
116251
+ parseSibling(stack, parent, index, remainingAfterClose);
116252
+ }
116253
+ };
116254
+ // Process the nodes with the components depth-first to maintain the correct order of the nodes
116255
+ while (stack.length) {
116256
+ const parent = stack.pop();
116257
+ if (parent?.children) {
116258
+ parent.children.forEach((_child, index) => {
116259
+ processChildNode(parent, index);
116260
+ });
116261
+ }
116262
+ }
116263
+ return tree;
116264
+ };
116265
+ /* harmony default export */ const mdxish_component_blocks = (mdxishComponentBlocks);
116266
+
116187
116267
  ;// ./processor/transform/mdxish/mdxish-html-blocks.ts
116188
116268
 
116189
116269
 
@@ -116549,7 +116629,7 @@ const mdxishInlineComponents = () => tree => {
116549
116629
  if (!match)
116550
116630
  return;
116551
116631
  const [, name, attrStr] = match;
116552
- if (!INLINE_COMPONENT_TAGS.has(name))
116632
+ if (!constants_INLINE_COMPONENT_TAGS.has(name))
116553
116633
  return;
116554
116634
  // Parse attributes directly - preserves all attribute types (strings, booleans, objects, arrays)
116555
116635
  const attributes = parseAttributes(attrStr ?? '');
@@ -116577,6 +116657,7 @@ const mdxishInlineComponents = () => tree => {
116577
116657
 
116578
116658
 
116579
116659
 
116660
+
116580
116661
  const transformAnchor = (jsx) => {
116581
116662
  const attrs = getAttrs(jsx);
116582
116663
  const { href = '', label, target, title } = attrs;
@@ -116616,6 +116697,7 @@ const transformImage = (jsx) => {
116616
116697
  alt,
116617
116698
  border: border !== undefined ? String(border) : undefined,
116618
116699
  caption,
116700
+ children: caption ? lib_mdast(caption).children : [],
116619
116701
  className,
116620
116702
  height: height !== undefined ? String(height) : undefined,
116621
116703
  lazy,
@@ -116850,12 +116932,6 @@ const mdxishMermaidTransformer = () => (tree) => {
116850
116932
  };
116851
116933
  /* harmony default export */ const mdxish_mermaid = (mdxishMermaidTransformer);
116852
116934
 
116853
- ;// ./lib/constants.ts
116854
- /**
116855
- * Pattern to match component tags (PascalCase or snake_case)
116856
- */
116857
- const componentTagPattern = /<(\/?[A-Z][A-Za-z0-9_]*)([^>]*?)(\/?)>/g;
116858
-
116859
116935
  ;// ./processor/transform/mdxish/mdxish-snake-case-components.ts
116860
116936
 
116861
116937
 
@@ -117291,6 +117367,49 @@ const variablesTextTransformer = () => tree => {
117291
117367
  };
117292
117368
  /* harmony default export */ const variables_text = (variablesTextTransformer);
117293
117369
 
117370
+ ;// ./lib/mdast-util/jsx-table/index.ts
117371
+ const jsx_table_contextMap = new WeakMap();
117372
+ function findJsxTableToken() {
117373
+ const events = this.tokenStack;
117374
+ for (let i = events.length - 1; i >= 0; i -= 1) {
117375
+ if (events[i][0].type === 'jsxTable')
117376
+ return events[i][0];
117377
+ }
117378
+ return undefined;
117379
+ }
117380
+ function enterJsxTable(token) {
117381
+ jsx_table_contextMap.set(token, { chunks: [] });
117382
+ this.enter({ type: 'html', value: '' }, token);
117383
+ }
117384
+ function exitJsxTableData(token) {
117385
+ const tableToken = findJsxTableToken.call(this);
117386
+ if (!tableToken)
117387
+ return;
117388
+ const ctx = jsx_table_contextMap.get(tableToken);
117389
+ if (ctx)
117390
+ ctx.chunks.push(this.sliceSerialize(token));
117391
+ }
117392
+ function exitJsxTable(token) {
117393
+ const ctx = jsx_table_contextMap.get(token);
117394
+ const node = this.stack[this.stack.length - 1];
117395
+ if (ctx) {
117396
+ node.value = ctx.chunks.join('\n');
117397
+ jsx_table_contextMap.delete(token);
117398
+ }
117399
+ this.exit(token);
117400
+ }
117401
+ function jsxTableFromMarkdown() {
117402
+ return {
117403
+ enter: {
117404
+ jsxTable: enterJsxTable,
117405
+ },
117406
+ exit: {
117407
+ jsxTableData: exitJsxTableData,
117408
+ jsxTable: exitJsxTable,
117409
+ },
117410
+ };
117411
+ }
117412
+
117294
117413
  ;// ./lib/mdast-util/magic-block/index.ts
117295
117414
  const magic_block_contextMap = new WeakMap();
117296
117415
  /**
@@ -117447,6 +117566,685 @@ function magicBlockToMarkdown() {
117447
117566
  };
117448
117567
  }
117449
117568
 
117569
+ ;// ./node_modules/micromark-util-symbol/lib/types.js
117570
+ /**
117571
+ * This module is compiled away!
117572
+ *
117573
+ * Here is the list of all types of tokens exposed by micromark, with a short
117574
+ * explanation of what they include and where they are found.
117575
+ * In picking names, generally, the rule is to be as explicit as possible
117576
+ * instead of reusing names.
117577
+ * For example, there is a `definitionDestination` and a `resourceDestination`,
117578
+ * instead of one shared name.
117579
+ */
117580
+
117581
+ // Note: when changing the next record, you must also change `TokenTypeMap`
117582
+ // in `micromark-util-types/index.d.ts`.
117583
+ const types_types = /** @type {const} */ ({
117584
+ // Generic type for data, such as in a title, a destination, etc.
117585
+ data: 'data',
117586
+
117587
+ // Generic type for syntactic whitespace (tabs, virtual spaces, spaces).
117588
+ // Such as, between a fenced code fence and an info string.
117589
+ whitespace: 'whitespace',
117590
+
117591
+ // Generic type for line endings (line feed, carriage return, carriage return +
117592
+ // line feed).
117593
+ lineEnding: 'lineEnding',
117594
+
117595
+ // A line ending, but ending a blank line.
117596
+ lineEndingBlank: 'lineEndingBlank',
117597
+
117598
+ // Generic type for whitespace (tabs, virtual spaces, spaces) at the start of a
117599
+ // line.
117600
+ linePrefix: 'linePrefix',
117601
+
117602
+ // Generic type for whitespace (tabs, virtual spaces, spaces) at the end of a
117603
+ // line.
117604
+ lineSuffix: 'lineSuffix',
117605
+
117606
+ // Whole ATX heading:
117607
+ //
117608
+ // ```markdown
117609
+ // #
117610
+ // ## Alpha
117611
+ // ### Bravo ###
117612
+ // ```
117613
+ //
117614
+ // Includes `atxHeadingSequence`, `whitespace`, `atxHeadingText`.
117615
+ atxHeading: 'atxHeading',
117616
+
117617
+ // Sequence of number signs in an ATX heading (`###`).
117618
+ atxHeadingSequence: 'atxHeadingSequence',
117619
+
117620
+ // Content in an ATX heading (`alpha`).
117621
+ // Includes text.
117622
+ atxHeadingText: 'atxHeadingText',
117623
+
117624
+ // Whole autolink (`<https://example.com>` or `<admin@example.com>`)
117625
+ // Includes `autolinkMarker` and `autolinkProtocol` or `autolinkEmail`.
117626
+ autolink: 'autolink',
117627
+
117628
+ // Email autolink w/o markers (`admin@example.com`)
117629
+ autolinkEmail: 'autolinkEmail',
117630
+
117631
+ // Marker around an `autolinkProtocol` or `autolinkEmail` (`<` or `>`).
117632
+ autolinkMarker: 'autolinkMarker',
117633
+
117634
+ // Protocol autolink w/o markers (`https://example.com`)
117635
+ autolinkProtocol: 'autolinkProtocol',
117636
+
117637
+ // A whole character escape (`\-`).
117638
+ // Includes `escapeMarker` and `characterEscapeValue`.
117639
+ characterEscape: 'characterEscape',
117640
+
117641
+ // The escaped character (`-`).
117642
+ characterEscapeValue: 'characterEscapeValue',
117643
+
117644
+ // A whole character reference (`&amp;`, `&#8800;`, or `&#x1D306;`).
117645
+ // Includes `characterReferenceMarker`, an optional
117646
+ // `characterReferenceMarkerNumeric`, in which case an optional
117647
+ // `characterReferenceMarkerHexadecimal`, and a `characterReferenceValue`.
117648
+ characterReference: 'characterReference',
117649
+
117650
+ // The start or end marker (`&` or `;`).
117651
+ characterReferenceMarker: 'characterReferenceMarker',
117652
+
117653
+ // Mark reference as numeric (`#`).
117654
+ characterReferenceMarkerNumeric: 'characterReferenceMarkerNumeric',
117655
+
117656
+ // Mark reference as numeric (`x` or `X`).
117657
+ characterReferenceMarkerHexadecimal: 'characterReferenceMarkerHexadecimal',
117658
+
117659
+ // Value of character reference w/o markers (`amp`, `8800`, or `1D306`).
117660
+ characterReferenceValue: 'characterReferenceValue',
117661
+
117662
+ // Whole fenced code:
117663
+ //
117664
+ // ````markdown
117665
+ // ```js
117666
+ // alert(1)
117667
+ // ```
117668
+ // ````
117669
+ codeFenced: 'codeFenced',
117670
+
117671
+ // A fenced code fence, including whitespace, sequence, info, and meta
117672
+ // (` ```js `).
117673
+ codeFencedFence: 'codeFencedFence',
117674
+
117675
+ // Sequence of grave accent or tilde characters (` ``` `) in a fence.
117676
+ codeFencedFenceSequence: 'codeFencedFenceSequence',
117677
+
117678
+ // Info word (`js`) in a fence.
117679
+ // Includes string.
117680
+ codeFencedFenceInfo: 'codeFencedFenceInfo',
117681
+
117682
+ // Meta words (`highlight="1"`) in a fence.
117683
+ // Includes string.
117684
+ codeFencedFenceMeta: 'codeFencedFenceMeta',
117685
+
117686
+ // A line of code.
117687
+ codeFlowValue: 'codeFlowValue',
117688
+
117689
+ // Whole indented code:
117690
+ //
117691
+ // ```markdown
117692
+ // alert(1)
117693
+ // ```
117694
+ //
117695
+ // Includes `lineEnding`, `linePrefix`, and `codeFlowValue`.
117696
+ codeIndented: 'codeIndented',
117697
+
117698
+ // A text code (``` `alpha` ```).
117699
+ // Includes `codeTextSequence`, `codeTextData`, `lineEnding`, and can include
117700
+ // `codeTextPadding`.
117701
+ codeText: 'codeText',
117702
+
117703
+ codeTextData: 'codeTextData',
117704
+
117705
+ // A space or line ending right after or before a tick.
117706
+ codeTextPadding: 'codeTextPadding',
117707
+
117708
+ // A text code fence (` `` `).
117709
+ codeTextSequence: 'codeTextSequence',
117710
+
117711
+ // Whole content:
117712
+ //
117713
+ // ```markdown
117714
+ // [a]: b
117715
+ // c
117716
+ // =
117717
+ // d
117718
+ // ```
117719
+ //
117720
+ // Includes `paragraph` and `definition`.
117721
+ content: 'content',
117722
+ // Whole definition:
117723
+ //
117724
+ // ```markdown
117725
+ // [micromark]: https://github.com/micromark/micromark
117726
+ // ```
117727
+ //
117728
+ // Includes `definitionLabel`, `definitionMarker`, `whitespace`,
117729
+ // `definitionDestination`, and optionally `lineEnding` and `definitionTitle`.
117730
+ definition: 'definition',
117731
+
117732
+ // Destination of a definition (`https://github.com/micromark/micromark` or
117733
+ // `<https://github.com/micromark/micromark>`).
117734
+ // Includes `definitionDestinationLiteral` or `definitionDestinationRaw`.
117735
+ definitionDestination: 'definitionDestination',
117736
+
117737
+ // Enclosed destination of a definition
117738
+ // (`<https://github.com/micromark/micromark>`).
117739
+ // Includes `definitionDestinationLiteralMarker` and optionally
117740
+ // `definitionDestinationString`.
117741
+ definitionDestinationLiteral: 'definitionDestinationLiteral',
117742
+
117743
+ // Markers of an enclosed definition destination (`<` or `>`).
117744
+ definitionDestinationLiteralMarker: 'definitionDestinationLiteralMarker',
117745
+
117746
+ // Unenclosed destination of a definition
117747
+ // (`https://github.com/micromark/micromark`).
117748
+ // Includes `definitionDestinationString`.
117749
+ definitionDestinationRaw: 'definitionDestinationRaw',
117750
+
117751
+ // Text in an destination (`https://github.com/micromark/micromark`).
117752
+ // Includes string.
117753
+ definitionDestinationString: 'definitionDestinationString',
117754
+
117755
+ // Label of a definition (`[micromark]`).
117756
+ // Includes `definitionLabelMarker` and `definitionLabelString`.
117757
+ definitionLabel: 'definitionLabel',
117758
+
117759
+ // Markers of a definition label (`[` or `]`).
117760
+ definitionLabelMarker: 'definitionLabelMarker',
117761
+
117762
+ // Value of a definition label (`micromark`).
117763
+ // Includes string.
117764
+ definitionLabelString: 'definitionLabelString',
117765
+
117766
+ // Marker between a label and a destination (`:`).
117767
+ definitionMarker: 'definitionMarker',
117768
+
117769
+ // Title of a definition (`"x"`, `'y'`, or `(z)`).
117770
+ // Includes `definitionTitleMarker` and optionally `definitionTitleString`.
117771
+ definitionTitle: 'definitionTitle',
117772
+
117773
+ // Marker around a title of a definition (`"`, `'`, `(`, or `)`).
117774
+ definitionTitleMarker: 'definitionTitleMarker',
117775
+
117776
+ // Data without markers in a title (`z`).
117777
+ // Includes string.
117778
+ definitionTitleString: 'definitionTitleString',
117779
+
117780
+ // Emphasis (`*alpha*`).
117781
+ // Includes `emphasisSequence` and `emphasisText`.
117782
+ emphasis: 'emphasis',
117783
+
117784
+ // Sequence of emphasis markers (`*` or `_`).
117785
+ emphasisSequence: 'emphasisSequence',
117786
+
117787
+ // Emphasis text (`alpha`).
117788
+ // Includes text.
117789
+ emphasisText: 'emphasisText',
117790
+
117791
+ // The character escape marker (`\`).
117792
+ escapeMarker: 'escapeMarker',
117793
+
117794
+ // A hard break created with a backslash (`\\n`).
117795
+ // Note: does not include the line ending.
117796
+ hardBreakEscape: 'hardBreakEscape',
117797
+
117798
+ // A hard break created with trailing spaces (` \n`).
117799
+ // Does not include the line ending.
117800
+ hardBreakTrailing: 'hardBreakTrailing',
117801
+
117802
+ // Flow HTML:
117803
+ //
117804
+ // ```markdown
117805
+ // <div
117806
+ // ```
117807
+ //
117808
+ // Inlcudes `lineEnding`, `htmlFlowData`.
117809
+ htmlFlow: 'htmlFlow',
117810
+
117811
+ htmlFlowData: 'htmlFlowData',
117812
+
117813
+ // HTML in text (the tag in `a <i> b`).
117814
+ // Includes `lineEnding`, `htmlTextData`.
117815
+ htmlText: 'htmlText',
117816
+
117817
+ htmlTextData: 'htmlTextData',
117818
+
117819
+ // Whole image (`![alpha](bravo)`, `![alpha][bravo]`, `![alpha][]`, or
117820
+ // `![alpha]`).
117821
+ // Includes `label` and an optional `resource` or `reference`.
117822
+ image: 'image',
117823
+
117824
+ // Whole link label (`[*alpha*]`).
117825
+ // Includes `labelLink` or `labelImage`, `labelText`, and `labelEnd`.
117826
+ label: 'label',
117827
+
117828
+ // Text in an label (`*alpha*`).
117829
+ // Includes text.
117830
+ labelText: 'labelText',
117831
+
117832
+ // Start a link label (`[`).
117833
+ // Includes a `labelMarker`.
117834
+ labelLink: 'labelLink',
117835
+
117836
+ // Start an image label (`![`).
117837
+ // Includes `labelImageMarker` and `labelMarker`.
117838
+ labelImage: 'labelImage',
117839
+
117840
+ // Marker of a label (`[` or `]`).
117841
+ labelMarker: 'labelMarker',
117842
+
117843
+ // Marker to start an image (`!`).
117844
+ labelImageMarker: 'labelImageMarker',
117845
+
117846
+ // End a label (`]`).
117847
+ // Includes `labelMarker`.
117848
+ labelEnd: 'labelEnd',
117849
+
117850
+ // Whole link (`[alpha](bravo)`, `[alpha][bravo]`, `[alpha][]`, or `[alpha]`).
117851
+ // Includes `label` and an optional `resource` or `reference`.
117852
+ link: 'link',
117853
+
117854
+ // Whole paragraph:
117855
+ //
117856
+ // ```markdown
117857
+ // alpha
117858
+ // bravo.
117859
+ // ```
117860
+ //
117861
+ // Includes text.
117862
+ paragraph: 'paragraph',
117863
+
117864
+ // A reference (`[alpha]` or `[]`).
117865
+ // Includes `referenceMarker` and an optional `referenceString`.
117866
+ reference: 'reference',
117867
+
117868
+ // A reference marker (`[` or `]`).
117869
+ referenceMarker: 'referenceMarker',
117870
+
117871
+ // Reference text (`alpha`).
117872
+ // Includes string.
117873
+ referenceString: 'referenceString',
117874
+
117875
+ // A resource (`(https://example.com "alpha")`).
117876
+ // Includes `resourceMarker`, an optional `resourceDestination` with an optional
117877
+ // `whitespace` and `resourceTitle`.
117878
+ resource: 'resource',
117879
+
117880
+ // A resource destination (`https://example.com`).
117881
+ // Includes `resourceDestinationLiteral` or `resourceDestinationRaw`.
117882
+ resourceDestination: 'resourceDestination',
117883
+
117884
+ // A literal resource destination (`<https://example.com>`).
117885
+ // Includes `resourceDestinationLiteralMarker` and optionally
117886
+ // `resourceDestinationString`.
117887
+ resourceDestinationLiteral: 'resourceDestinationLiteral',
117888
+
117889
+ // A resource destination marker (`<` or `>`).
117890
+ resourceDestinationLiteralMarker: 'resourceDestinationLiteralMarker',
117891
+
117892
+ // A raw resource destination (`https://example.com`).
117893
+ // Includes `resourceDestinationString`.
117894
+ resourceDestinationRaw: 'resourceDestinationRaw',
117895
+
117896
+ // Resource destination text (`https://example.com`).
117897
+ // Includes string.
117898
+ resourceDestinationString: 'resourceDestinationString',
117899
+
117900
+ // A resource marker (`(` or `)`).
117901
+ resourceMarker: 'resourceMarker',
117902
+
117903
+ // A resource title (`"alpha"`, `'alpha'`, or `(alpha)`).
117904
+ // Includes `resourceTitleMarker` and optionally `resourceTitleString`.
117905
+ resourceTitle: 'resourceTitle',
117906
+
117907
+ // A resource title marker (`"`, `'`, `(`, or `)`).
117908
+ resourceTitleMarker: 'resourceTitleMarker',
117909
+
117910
+ // Resource destination title (`alpha`).
117911
+ // Includes string.
117912
+ resourceTitleString: 'resourceTitleString',
117913
+
117914
+ // Whole setext heading:
117915
+ //
117916
+ // ```markdown
117917
+ // alpha
117918
+ // bravo
117919
+ // =====
117920
+ // ```
117921
+ //
117922
+ // Includes `setextHeadingText`, `lineEnding`, `linePrefix`, and
117923
+ // `setextHeadingLine`.
117924
+ setextHeading: 'setextHeading',
117925
+
117926
+ // Content in a setext heading (`alpha\nbravo`).
117927
+ // Includes text.
117928
+ setextHeadingText: 'setextHeadingText',
117929
+
117930
+ // Underline in a setext heading, including whitespace suffix (`==`).
117931
+ // Includes `setextHeadingLineSequence`.
117932
+ setextHeadingLine: 'setextHeadingLine',
117933
+
117934
+ // Sequence of equals or dash characters in underline in a setext heading (`-`).
117935
+ setextHeadingLineSequence: 'setextHeadingLineSequence',
117936
+
117937
+ // Strong (`**alpha**`).
117938
+ // Includes `strongSequence` and `strongText`.
117939
+ strong: 'strong',
117940
+
117941
+ // Sequence of strong markers (`**` or `__`).
117942
+ strongSequence: 'strongSequence',
117943
+
117944
+ // Strong text (`alpha`).
117945
+ // Includes text.
117946
+ strongText: 'strongText',
117947
+
117948
+ // Whole thematic break:
117949
+ //
117950
+ // ```markdown
117951
+ // * * *
117952
+ // ```
117953
+ //
117954
+ // Includes `thematicBreakSequence` and `whitespace`.
117955
+ thematicBreak: 'thematicBreak',
117956
+
117957
+ // A sequence of one or more thematic break markers (`***`).
117958
+ thematicBreakSequence: 'thematicBreakSequence',
117959
+
117960
+ // Whole block quote:
117961
+ //
117962
+ // ```markdown
117963
+ // > a
117964
+ // >
117965
+ // > b
117966
+ // ```
117967
+ //
117968
+ // Includes `blockQuotePrefix` and flow.
117969
+ blockQuote: 'blockQuote',
117970
+ // The `>` or `> ` of a block quote.
117971
+ blockQuotePrefix: 'blockQuotePrefix',
117972
+ // The `>` of a block quote prefix.
117973
+ blockQuoteMarker: 'blockQuoteMarker',
117974
+ // The optional ` ` of a block quote prefix.
117975
+ blockQuotePrefixWhitespace: 'blockQuotePrefixWhitespace',
117976
+
117977
+ // Whole ordered list:
117978
+ //
117979
+ // ```markdown
117980
+ // 1. a
117981
+ // b
117982
+ // ```
117983
+ //
117984
+ // Includes `listItemPrefix`, flow, and optionally `listItemIndent` on further
117985
+ // lines.
117986
+ listOrdered: 'listOrdered',
117987
+
117988
+ // Whole unordered list:
117989
+ //
117990
+ // ```markdown
117991
+ // - a
117992
+ // b
117993
+ // ```
117994
+ //
117995
+ // Includes `listItemPrefix`, flow, and optionally `listItemIndent` on further
117996
+ // lines.
117997
+ listUnordered: 'listUnordered',
117998
+
117999
+ // The indent of further list item lines.
118000
+ listItemIndent: 'listItemIndent',
118001
+
118002
+ // A marker, as in, `*`, `+`, `-`, `.`, or `)`.
118003
+ listItemMarker: 'listItemMarker',
118004
+
118005
+ // The thing that starts a list item, such as `1. `.
118006
+ // Includes `listItemValue` if ordered, `listItemMarker`, and
118007
+ // `listItemPrefixWhitespace` (unless followed by a line ending).
118008
+ listItemPrefix: 'listItemPrefix',
118009
+
118010
+ // The whitespace after a marker.
118011
+ listItemPrefixWhitespace: 'listItemPrefixWhitespace',
118012
+
118013
+ // The numerical value of an ordered item.
118014
+ listItemValue: 'listItemValue',
118015
+
118016
+ // Internal types used for subtokenizers, compiled away
118017
+ chunkDocument: 'chunkDocument',
118018
+ chunkContent: 'chunkContent',
118019
+ chunkFlow: 'chunkFlow',
118020
+ chunkText: 'chunkText',
118021
+ chunkString: 'chunkString'
118022
+ })
118023
+
118024
+ ;// ./lib/micromark/jsx-table/syntax.ts
118025
+
118026
+
118027
+ const syntax_nonLazyContinuationStart = {
118028
+ tokenize: syntax_tokenizeNonLazyContinuationStart,
118029
+ partial: true,
118030
+ };
118031
+ function resolveToJsxTable(events) {
118032
+ let index = events.length;
118033
+ while (index > 0) {
118034
+ index -= 1;
118035
+ if (events[index][0] === 'enter' && events[index][1].type === 'jsxTable') {
118036
+ break;
118037
+ }
118038
+ }
118039
+ if (index > 1 && events[index - 2][1].type === types_types.linePrefix) {
118040
+ events[index][1].start = events[index - 2][1].start;
118041
+ events[index + 1][1].start = events[index - 2][1].start;
118042
+ events.splice(index - 2, 2);
118043
+ }
118044
+ return events;
118045
+ }
118046
+ const jsxTableConstruct = {
118047
+ name: 'jsxTable',
118048
+ tokenize: tokenizeJsxTable,
118049
+ resolveTo: resolveToJsxTable,
118050
+ concrete: true,
118051
+ };
118052
+ function tokenizeJsxTable(effects, ok, nok) {
118053
+ let codeSpanOpenSize = 0;
118054
+ let codeSpanCloseSize = 0;
118055
+ let depth = 1;
118056
+ const TABLE_NAME = [codes.uppercaseT, codes.lowercaseA, codes.lowercaseB, codes.lowercaseL, codes.lowercaseE];
118057
+ const ABLE_SUFFIX = TABLE_NAME.slice(1);
118058
+ /** Build a state chain that matches a sequence of character codes. */
118059
+ function matchChars(chars, onMatch, onFail) {
118060
+ if (chars.length === 0)
118061
+ return onMatch;
118062
+ return ((code) => {
118063
+ if (code === chars[0]) {
118064
+ effects.consume(code);
118065
+ return matchChars(chars.slice(1), onMatch, onFail);
118066
+ }
118067
+ return onFail(code);
118068
+ });
118069
+ }
118070
+ return start;
118071
+ function start(code) {
118072
+ if (code !== codes.lessThan)
118073
+ return nok(code);
118074
+ effects.enter('jsxTable');
118075
+ effects.enter('jsxTableData');
118076
+ effects.consume(code);
118077
+ return matchChars(TABLE_NAME, afterTagName, nok);
118078
+ }
118079
+ function afterTagName(code) {
118080
+ if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
118081
+ effects.consume(code);
118082
+ return body;
118083
+ }
118084
+ return nok(code);
118085
+ }
118086
+ function body(code) {
118087
+ // Reject unclosed <Table> so it falls back to normal HTML block parsing
118088
+ // instead of swallowing all subsequent content to EOF
118089
+ if (code === null) {
118090
+ return nok(code);
118091
+ }
118092
+ if (markdownLineEnding(code)) {
118093
+ effects.exit('jsxTableData');
118094
+ return continuationStart(code);
118095
+ }
118096
+ if (code === codes.backslash) {
118097
+ effects.consume(code);
118098
+ return escapedChar;
118099
+ }
118100
+ if (code === codes.lessThan) {
118101
+ effects.consume(code);
118102
+ return closeSlash;
118103
+ }
118104
+ // Skip over backtick code spans so `</Table>` in inline code isn't
118105
+ // treated as the closing tag
118106
+ if (code === codes.graveAccent) {
118107
+ codeSpanOpenSize = 0;
118108
+ return countOpenTicks(code);
118109
+ }
118110
+ effects.consume(code);
118111
+ return body;
118112
+ }
118113
+ function countOpenTicks(code) {
118114
+ if (code === codes.graveAccent) {
118115
+ codeSpanOpenSize += 1;
118116
+ effects.consume(code);
118117
+ return countOpenTicks;
118118
+ }
118119
+ return inCodeSpan(code);
118120
+ }
118121
+ function inCodeSpan(code) {
118122
+ if (code === null || markdownLineEnding(code))
118123
+ return body(code);
118124
+ if (code === codes.graveAccent) {
118125
+ codeSpanCloseSize = 0;
118126
+ return countCloseTicks(code);
118127
+ }
118128
+ effects.consume(code);
118129
+ return inCodeSpan;
118130
+ }
118131
+ function countCloseTicks(code) {
118132
+ if (code === codes.graveAccent) {
118133
+ codeSpanCloseSize += 1;
118134
+ effects.consume(code);
118135
+ return countCloseTicks;
118136
+ }
118137
+ return codeSpanCloseSize === codeSpanOpenSize ? body(code) : inCodeSpan(code);
118138
+ }
118139
+ function escapedChar(code) {
118140
+ if (code === null || markdownLineEnding(code)) {
118141
+ return body(code);
118142
+ }
118143
+ effects.consume(code);
118144
+ return body;
118145
+ }
118146
+ function closeSlash(code) {
118147
+ if (code === codes.slash) {
118148
+ effects.consume(code);
118149
+ return matchChars(TABLE_NAME, closeGt, body);
118150
+ }
118151
+ if (code === codes.uppercaseT) {
118152
+ effects.consume(code);
118153
+ return matchChars(ABLE_SUFFIX, openAfterTagName, body);
118154
+ }
118155
+ return body(code);
118156
+ }
118157
+ function openAfterTagName(code) {
118158
+ if (code === codes.greaterThan || code === codes.slash || code === codes.space || code === codes.horizontalTab) {
118159
+ depth += 1;
118160
+ effects.consume(code);
118161
+ return body;
118162
+ }
118163
+ return body(code);
118164
+ }
118165
+ function closeGt(code) {
118166
+ if (code === codes.greaterThan) {
118167
+ depth -= 1;
118168
+ effects.consume(code);
118169
+ if (depth === 0) {
118170
+ return afterClose;
118171
+ }
118172
+ return body;
118173
+ }
118174
+ return body(code);
118175
+ }
118176
+ function afterClose(code) {
118177
+ if (code === null || markdownLineEnding(code)) {
118178
+ effects.exit('jsxTableData');
118179
+ effects.exit('jsxTable');
118180
+ return ok(code);
118181
+ }
118182
+ effects.consume(code);
118183
+ return afterClose;
118184
+ }
118185
+ // Line ending handling — follows the htmlFlow pattern
118186
+ function continuationStart(code) {
118187
+ return effects.check(syntax_nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
118188
+ }
118189
+ function continuationStartNonLazy(code) {
118190
+ effects.enter(types_types.lineEnding);
118191
+ effects.consume(code);
118192
+ effects.exit(types_types.lineEnding);
118193
+ return continuationBefore;
118194
+ }
118195
+ function continuationBefore(code) {
118196
+ if (code === null || markdownLineEnding(code)) {
118197
+ return continuationStart(code);
118198
+ }
118199
+ effects.enter('jsxTableData');
118200
+ return body(code);
118201
+ }
118202
+ function continuationAfter(code) {
118203
+ // At EOF without </Table>, reject so content isn't swallowed
118204
+ if (code === null) {
118205
+ return nok(code);
118206
+ }
118207
+ effects.exit('jsxTable');
118208
+ return ok(code);
118209
+ }
118210
+ }
118211
+ function syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
118212
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
118213
+ const self = this;
118214
+ return start;
118215
+ function start(code) {
118216
+ if (markdownLineEnding(code)) {
118217
+ effects.enter(types_types.lineEnding);
118218
+ effects.consume(code);
118219
+ effects.exit(types_types.lineEnding);
118220
+ return after;
118221
+ }
118222
+ return nok(code);
118223
+ }
118224
+ function after(code) {
118225
+ if (self.parser.lazy[self.now().line]) {
118226
+ return nok(code);
118227
+ }
118228
+ return ok(code);
118229
+ }
118230
+ }
118231
+ /**
118232
+ * Micromark extension that tokenizes `<Table>...</Table>` as a single flow block.
118233
+ *
118234
+ * Prevents CommonMark HTML block type 6 from matching `<Table>` (case-insensitive
118235
+ * match against `table`) and fragmenting it at blank lines.
118236
+ */
118237
+ function jsxTable() {
118238
+ return {
118239
+ flow: {
118240
+ [codes.lessThan]: [jsxTableConstruct],
118241
+ },
118242
+ };
118243
+ }
118244
+
118245
+ ;// ./lib/micromark/jsx-table/index.ts
118246
+
118247
+
117450
118248
  ;// ./lib/micromark/magic-block/syntax.ts
117451
118249
 
117452
118250
 
@@ -118375,6 +119173,8 @@ function loadComponents() {
118375
119173
 
118376
119174
 
118377
119175
 
119176
+
119177
+
118378
119178
 
118379
119179
 
118380
119180
 
@@ -118422,11 +119222,11 @@ function mdxishAstProcessor(mdContent, opts = {}) {
118422
119222
  };
118423
119223
  const processor = unified()
118424
119224
  .data('micromarkExtensions', safeMode
118425
- ? [magicBlock(), legacyVariable(), looseHtmlEntity()]
118426
- : [magicBlock(), mdxExprTextOnly, legacyVariable(), looseHtmlEntity()])
119225
+ ? [jsxTable(), magicBlock(), legacyVariable(), looseHtmlEntity()]
119226
+ : [jsxTable(), magicBlock(), mdxExprTextOnly, legacyVariable(), looseHtmlEntity()])
118427
119227
  .data('fromMarkdownExtensions', safeMode
118428
- ? [magicBlockFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()]
118429
- : [magicBlockFromMarkdown(), mdxExpressionFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
119228
+ ? [jsxTableFromMarkdown(), magicBlockFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()]
119229
+ : [jsxTableFromMarkdown(), magicBlockFromMarkdown(), mdxExpressionFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
118430
119230
  .use(remarkParse)
118431
119231
  .use(remarkFrontmatter)
118432
119232
  .use(normalize_malformed_md_syntax)
@@ -119046,6 +119846,8 @@ function restoreMagicBlocks(replaced, blocks) {
119046
119846
 
119047
119847
 
119048
119848
 
119849
+
119850
+
119049
119851
  /**
119050
119852
  * Removes Markdown and MDX comments.
119051
119853
  */
@@ -119057,8 +119859,8 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
119057
119859
  // 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
119058
119860
  if (mdxish) {
119059
119861
  processor
119060
- .data('micromarkExtensions', [mdxExpression({ allowEmpty: true })])
119061
- .data('fromMarkdownExtensions', [mdxExpressionFromMarkdown()])
119862
+ .data('micromarkExtensions', [jsxTable(), mdxExpression({ allowEmpty: true })])
119863
+ .data('fromMarkdownExtensions', [jsxTableFromMarkdown(), mdxExpressionFromMarkdown()])
119062
119864
  .data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
119063
119865
  }
119064
119866
  processor