@readme/markdown 14.1.4 → 14.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.node.js CHANGED
@@ -73519,9 +73519,16 @@ function formatHtmlForMdxish(html) {
73519
73519
  }
73520
73520
  // Removes the leading/trailing newlines
73521
73521
  let cleaned = processed.replace(/^\s*\n|\n\s*$/g, '');
73522
- // Convert literal \n sequences to actual newlines BEFORE processing backticks
73523
- // This prevents the backtick unescaping regex from incorrectly matching \n sequences
73524
- cleaned = cleaned.replace(/\\n/g, '\n');
73522
+ // Convert literal \n sequences to actual newlines only inside <pre> and <code>.
73523
+ // Because <pre> needs to respect the newline visual and
73524
+ // escape characters should be processed in the <code> tag.
73525
+ //
73526
+ // We don't want to unescape every \n because it might break the HTML & cause errors
73527
+ // Example: <script>console.log("\n");</script>
73528
+ // Would get turned into: <script>console.log("
73529
+ // ");</script>
73530
+ // which is invalid javascript and will cause error
73531
+ cleaned = cleaned.replace(/(<(pre|code)\b[^>]*>)([\s\S]*?)(<\/\2>)/gi, (_m, open, _tag, inner, close) => open + inner.replace(/\\n/g, '\n') + close);
73525
73532
  // Unescape backticks: \` -> ` (users escape backticks in template literals)
73526
73533
  // Handle both cases: \` (adjacent) and \ followed by ` (split by markdown parser)
73527
73534
  cleaned = cleaned.replace(/\\`/g, '`');
@@ -91417,6 +91424,87 @@ function gemojiFromMarkdown() {
91417
91424
  };
91418
91425
  }
91419
91426
 
91427
+ ;// ./lib/mdast-util/legacy-variable/index.ts
91428
+
91429
+ const contextMap = new WeakMap();
91430
+ function findlegacyVariableToken() {
91431
+ // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
91432
+ const events = this.tokenStack;
91433
+ for (let i = events.length - 1; i >= 0; i -= 1) {
91434
+ const token = events[i][0];
91435
+ if (token.type === 'legacyVariable')
91436
+ return token;
91437
+ }
91438
+ return undefined;
91439
+ }
91440
+ function enterlegacyVariable(token) {
91441
+ contextMap.set(token, { value: '' });
91442
+ }
91443
+ function exitlegacyVariableValue(token) {
91444
+ const variableToken = findlegacyVariableToken.call(this);
91445
+ if (!variableToken)
91446
+ return;
91447
+ const ctx = contextMap.get(variableToken);
91448
+ // Build up the variable characters
91449
+ if (ctx)
91450
+ ctx.value += this.sliceSerialize(token);
91451
+ }
91452
+ function exitlegacyVariable(token) {
91453
+ const ctx = contextMap.get(token);
91454
+ const serialized = this.sliceSerialize(token);
91455
+ const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
91456
+ ? serialized.slice(2, -2)
91457
+ : ctx?.value ?? '';
91458
+ const nodePosition = {
91459
+ start: {
91460
+ offset: token.start.offset,
91461
+ line: token.start.line,
91462
+ column: token.start.column,
91463
+ },
91464
+ end: {
91465
+ offset: token.end.offset,
91466
+ line: token.end.line,
91467
+ column: token.end.column,
91468
+ },
91469
+ };
91470
+ if (variableName.startsWith('glossary:')) {
91471
+ const term = variableName.slice('glossary:'.length).trim();
91472
+ this.enter({
91473
+ type: NodeTypes.glossary,
91474
+ data: {
91475
+ hName: 'Glossary',
91476
+ hProperties: { term },
91477
+ },
91478
+ children: [{ type: 'text', value: term }],
91479
+ position: nodePosition,
91480
+ }, token);
91481
+ this.exit(token);
91482
+ contextMap.delete(token);
91483
+ return;
91484
+ }
91485
+ this.enter({
91486
+ type: NodeTypes.variable,
91487
+ data: {
91488
+ hName: 'Variable',
91489
+ hProperties: { name: variableName.trim(), isLegacy: true },
91490
+ },
91491
+ value: `<<${variableName}>>`,
91492
+ }, token);
91493
+ this.exit(token);
91494
+ contextMap.delete(token);
91495
+ }
91496
+ function legacyVariableFromMarkdown() {
91497
+ return {
91498
+ enter: {
91499
+ legacyVariable: enterlegacyVariable,
91500
+ },
91501
+ exit: {
91502
+ legacyVariableValue: exitlegacyVariableValue,
91503
+ legacyVariable: exitlegacyVariable,
91504
+ },
91505
+ };
91506
+ }
91507
+
91420
91508
  ;// ./node_modules/micromark-util-symbol/lib/codes.js
91421
91509
  /**
91422
91510
  * Character codes.
@@ -91670,6 +91758,74 @@ function syntax_gemoji() {
91670
91758
  */
91671
91759
 
91672
91760
 
91761
+ ;// ./lib/micromark/legacy-variable/syntax.ts
91762
+
91763
+
91764
+ function isAllowedValueChar(code) {
91765
+ return (code !== null &&
91766
+ code !== codes.lessThan &&
91767
+ code !== codes.greaterThan &&
91768
+ !markdownLineEnding(code));
91769
+ }
91770
+ const legacyVariableConstruct = {
91771
+ name: 'legacyVariable',
91772
+ tokenize: syntax_tokenize,
91773
+ };
91774
+ function syntax_tokenize(effects, ok, nok) {
91775
+ let hasValue = false;
91776
+ const start = (code) => {
91777
+ if (code !== codes.lessThan)
91778
+ return nok(code);
91779
+ effects.enter('legacyVariable');
91780
+ effects.enter('legacyVariableMarkerStart');
91781
+ effects.consume(code); // <
91782
+ return open2;
91783
+ };
91784
+ const open2 = (code) => {
91785
+ if (code !== codes.lessThan)
91786
+ return nok(code);
91787
+ effects.consume(code); // <<
91788
+ effects.exit('legacyVariableMarkerStart');
91789
+ effects.enter('legacyVariableValue');
91790
+ return value;
91791
+ };
91792
+ const value = (code) => {
91793
+ if (code === codes.greaterThan) {
91794
+ if (!hasValue)
91795
+ return nok(code);
91796
+ effects.exit('legacyVariableValue');
91797
+ effects.enter('legacyVariableMarkerEnd');
91798
+ effects.consume(code); // >
91799
+ return close2;
91800
+ }
91801
+ if (!isAllowedValueChar(code))
91802
+ return nok(code);
91803
+ hasValue = true;
91804
+ effects.consume(code);
91805
+ return value;
91806
+ };
91807
+ const close2 = (code) => {
91808
+ if (code !== codes.greaterThan)
91809
+ return nok(code);
91810
+ effects.consume(code); // >>
91811
+ effects.exit('legacyVariableMarkerEnd');
91812
+ effects.exit('legacyVariable');
91813
+ return ok;
91814
+ };
91815
+ return start;
91816
+ }
91817
+ function legacyVariable() {
91818
+ return {
91819
+ text: { [codes.lessThan]: legacyVariableConstruct },
91820
+ };
91821
+ }
91822
+
91823
+ ;// ./lib/micromark/legacy-variable/index.ts
91824
+ /**
91825
+ * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
91826
+ */
91827
+
91828
+
91673
91829
  ;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
91674
91830
 
91675
91831
  // Marker patterns for multi-node emphasis detection
@@ -92048,20 +92204,59 @@ const unwrapSoleParagraph = (children) => {
92048
92204
 
92049
92205
 
92050
92206
 
92207
+
92208
+
92209
+
92051
92210
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
92052
92211
  const tableTypes = {
92053
92212
  tr: 'tableRow',
92054
92213
  th: 'tableCell',
92055
92214
  td: 'tableCell',
92056
92215
  };
92057
- const tableNodeProcessor = unified()
92058
- .data('micromarkExtensions', [syntax_gemoji()])
92059
- .data('fromMarkdownExtensions', [gemojiFromMarkdown()])
92216
+ // `mdxjs` + `mdxFromMarkdown` is what `remarkMdx` registers internally; we
92217
+ // register them manually so we control ordering against our other tokenizers.
92218
+ // The fallback omits these so blank-line-separated markdown inside cells still
92219
+ // parses when mdxjs throws on malformed JSX.
92220
+ const buildTableNodeProcessor = (withMdx) => unified()
92221
+ .data('micromarkExtensions', [...(withMdx ? [mdxjs()] : []), syntax_gemoji(), legacyVariable()])
92222
+ .data('fromMarkdownExtensions', [
92223
+ ...(withMdx ? [mdxFromMarkdown()] : []),
92224
+ gemojiFromMarkdown(),
92225
+ legacyVariableFromMarkdown(),
92226
+ ])
92060
92227
  .use(remarkParse)
92061
- .use(remarkMdx)
92062
92228
  .use(normalize_malformed_md_syntax)
92063
92229
  .use([[callouts, { isMdxish: true }], code_tabs])
92064
92230
  .use(remarkGfm);
92231
+ const tableNodeProcessor = buildTableNodeProcessor(true);
92232
+ const fallbackTableNodeProcessor = buildTableNodeProcessor(false);
92233
+ // Since we use a subparser in `tableNodeProcessor` to parse `node.value`,
92234
+ // positions are relative to that substring. Shifting them by the base
92235
+ // offset and line number makes them valid in the outer source coordinate space.
92236
+ // Otherwise, consumers who directly slice based on position would read and grab the
92237
+ // wrong content
92238
+ const parseTableNode = (processor, node) => {
92239
+ let parsed;
92240
+ try {
92241
+ parsed = processor.runSync(processor.parse(node.value));
92242
+ }
92243
+ catch {
92244
+ return undefined;
92245
+ }
92246
+ const baseOffset = node.position?.start?.offset ?? 0;
92247
+ const baseLine = (node.position?.start?.line ?? 1) - 1;
92248
+ visit(parsed, child => {
92249
+ if (child.position?.start) {
92250
+ child.position.start.offset = (child.position.start.offset ?? 0) + baseOffset;
92251
+ child.position.start.line += baseLine;
92252
+ }
92253
+ if (child.position?.end) {
92254
+ child.position.end.offset = (child.position.end.offset ?? 0) + baseOffset;
92255
+ child.position.end.line += baseLine;
92256
+ }
92257
+ });
92258
+ return parsed;
92259
+ };
92065
92260
  /**
92066
92261
  * Check if children are only text nodes that might contain markdown
92067
92262
  */
@@ -92164,27 +92359,54 @@ const processTableNode = (node, index, parent, documentPosition) => {
92164
92359
  }
92165
92360
  // All cells are phrasing-only — convert to markdown table
92166
92361
  const children = [];
92362
+ // Collect `<td>`/`<th>` cells under any container (a `<tr>`, or a section
92363
+ // when cells are bare).
92364
+ const collectCells = (container) => {
92365
+ const cells = [];
92366
+ visit(container, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
92367
+ cells.push({
92368
+ type: tableTypes[name],
92369
+ children: unwrapSoleParagraph(cellChildren),
92370
+ position: cellPosition,
92371
+ });
92372
+ });
92373
+ return cells;
92374
+ };
92375
+ // remarkMdx wraps inline `<tr>`s in a paragraph; unwrap one level so the
92376
+ // hasRow check below sees them.
92377
+ const flattenSectionChildren = (nodes) => nodes.flatMap(n => n.type === 'paragraph' && 'children' in n && Array.isArray(n.children) ? n.children : [n]);
92167
92378
  visit(node, isMDXElement, (child) => {
92168
- if (child.name === 'thead' || child.name === 'tbody') {
92379
+ if (child.name !== 'thead' && child.name !== 'tbody')
92380
+ return;
92381
+ const sectionChildren = flattenSectionChildren(child.children);
92382
+ const hasRow = sectionChildren.some(c => isMDXElement(c) && c.name === 'tr');
92383
+ if (hasRow) {
92169
92384
  visit(child, isMDXElement, (row) => {
92170
92385
  if (row.name !== 'tr')
92171
92386
  return;
92172
- const rowChildren = [];
92173
- visit(row, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
92174
- const parsedChildren = unwrapSoleParagraph(cellChildren);
92175
- rowChildren.push({
92176
- type: tableTypes[name],
92177
- children: parsedChildren,
92178
- position: cellPosition,
92179
- });
92180
- });
92181
92387
  children.push({
92182
92388
  type: 'tableRow',
92183
- children: rowChildren,
92389
+ children: collectCells(row),
92184
92390
  position: row.position,
92185
92391
  });
92186
92392
  });
92187
92393
  }
92394
+ else {
92395
+ // No `<tr>`, chunk bare cells into rows using the prior row's column
92396
+ // count (e.g. from `<thead>`), so 4 bare `<td>`s under a 2-col header
92397
+ // become 2 rows of 2.
92398
+ const cells = collectCells(child);
92399
+ if (cells.length === 0)
92400
+ return;
92401
+ const cols = children[0]?.children?.length || cells.length;
92402
+ for (let i = 0; i < cells.length; i += cols) {
92403
+ children.push({
92404
+ type: 'tableRow',
92405
+ children: cells.slice(i, i + cols),
92406
+ position: child.position,
92407
+ });
92408
+ }
92409
+ }
92188
92410
  });
92189
92411
  const firstRow = children[0];
92190
92412
  const columnCount = firstRow?.children?.length || 0;
@@ -92217,35 +92439,22 @@ const mdxishTables = () => tree => {
92217
92439
  return;
92218
92440
  if (!node.value.startsWith('<Table') && !node.value.startsWith('<table'))
92219
92441
  return;
92220
- try {
92221
- const parsed = tableNodeProcessor.runSync(tableNodeProcessor.parse(node.value));
92222
- // since we use a subparser in `tableNodeProcessor` to parse `node.value`,
92223
- // positions are relative to that substring. shifting them by the base
92224
- // offset and line number makes them valid in the outer source coordinate space.
92225
- // otherwise, consumers who directly slice based on position would read and grab the
92226
- // wrong content
92227
- const baseOffset = node.position?.start?.offset ?? 0;
92228
- const baseLine = (node.position?.start?.line ?? 1) - 1;
92229
- visit(parsed, child => {
92230
- if (child.position?.start) {
92231
- child.position.start.offset = (child.position.start.offset ?? 0) + baseOffset;
92232
- child.position.start.line += baseLine;
92233
- }
92234
- if (child.position?.end) {
92235
- child.position.end.offset = (child.position.end.offset ?? 0) + baseOffset;
92236
- child.position.end.line += baseLine;
92237
- }
92238
- });
92442
+ const parsed = parseTableNode(tableNodeProcessor, node);
92443
+ if (parsed) {
92239
92444
  visit(parsed, isMDXElement, (tableNode) => {
92240
92445
  if (tableNode.name !== 'Table' && tableNode.name !== 'table')
92241
92446
  return undefined;
92242
92447
  processTableNode(tableNode, index, parent, node.position);
92243
92448
  return EXIT;
92244
92449
  });
92450
+ return;
92245
92451
  }
92246
- catch {
92247
- // If parsing fails, leave the node as-is
92248
- }
92452
+ // MDX parse failed (usually unbalanced JSX). Re-parse without MDX so
92453
+ // markdown between `<td>` and `</td>` still renders; tags stay as raw HTML.
92454
+ const fallback = parseTableNode(fallbackTableNodeProcessor, node);
92455
+ if (!fallback || fallback.children.length <= 1)
92456
+ return;
92457
+ parent.children.splice(index, 1, ...fallback.children);
92249
92458
  });
92250
92459
  return tree;
92251
92460
  };
@@ -104996,6 +105205,63 @@ function rehypeSanitize(options) {
104996
105205
  }
104997
105206
  }
104998
105207
 
105208
+ ;// ./node_modules/mdast-util-newline-to-break/lib/index.js
105209
+ /**
105210
+ * @typedef {import('mdast').Nodes} Nodes
105211
+ * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction
105212
+ */
105213
+
105214
+
105215
+
105216
+ /**
105217
+ * Turn normal line endings into hard breaks.
105218
+ *
105219
+ * @param {Nodes} tree
105220
+ * Tree to change.
105221
+ * @returns {undefined}
105222
+ * Nothing.
105223
+ */
105224
+ function newlineToBreak(tree) {
105225
+ findAndReplace(tree, [/\r?\n|\r/g, lib_replace])
105226
+ }
105227
+
105228
+ /**
105229
+ * Replace line endings.
105230
+ *
105231
+ * @type {ReplaceFunction}
105232
+ */
105233
+ function lib_replace() {
105234
+ return {type: 'break'}
105235
+ }
105236
+
105237
+ ;// ./node_modules/remark-breaks/lib/index.js
105238
+ /**
105239
+ * @typedef {import('mdast').Root} Root
105240
+ */
105241
+
105242
+
105243
+
105244
+ /**
105245
+ * Support hard breaks without needing spaces or escapes (turns enters into
105246
+ * `<br>`s).
105247
+ *
105248
+ * @returns
105249
+ * Transform.
105250
+ */
105251
+ function remarkBreaks() {
105252
+ /**
105253
+ * Transform.
105254
+ *
105255
+ * @param {Root} tree
105256
+ * Tree.
105257
+ * @returns {undefined}
105258
+ * Nothing.
105259
+ */
105260
+ return function (tree) {
105261
+ newlineToBreak(tree)
105262
+ }
105263
+ }
105264
+
104999
105265
  ;// ./errors/mdx-syntax-error.ts
105000
105266
  class MdxSyntaxError extends SyntaxError {
105001
105267
  original = null;
@@ -107801,6 +108067,7 @@ const tocHastToMdx = (toc, components, variables) => {
107801
108067
 
107802
108068
 
107803
108069
 
108070
+
107804
108071
  const sanitizeSchema = cjs_default()(defaultSchema, {
107805
108072
  attributes: {
107806
108073
  a: ['target'],
@@ -107809,12 +108076,13 @@ const sanitizeSchema = cjs_default()(defaultSchema, {
107809
108076
  href: ['doc', 'ref', 'blog', 'changelog', 'page'],
107810
108077
  },
107811
108078
  });
107812
- const compile_compile = (text, { components = {}, missingComponents, copyButtons, useTailwind, ...opts } = {}) => {
108079
+ const compile_compile = (text, { components = {}, missingComponents, copyButtons, useTailwind, hardBreaks, ...opts } = {}) => {
107813
108080
  // Destructure at runtime to avoid circular dependency issues
107814
108081
  const { codeTabsTransformer, ...transforms } = defaultTransforms;
107815
108082
  const remarkPlugins = [
107816
108083
  remarkFrontmatter,
107817
108084
  remarkGfm,
108085
+ ...(hardBreaks ? [remarkBreaks] : []),
107818
108086
  ...Object.values(transforms),
107819
108087
  [codeTabsTransformer, { copyButtons }],
107820
108088
  [
@@ -114220,63 +114488,6 @@ function rehypeStringify(options) {
114220
114488
  }
114221
114489
  }
114222
114490
 
114223
- ;// ./node_modules/mdast-util-newline-to-break/lib/index.js
114224
- /**
114225
- * @typedef {import('mdast').Nodes} Nodes
114226
- * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction
114227
- */
114228
-
114229
-
114230
-
114231
- /**
114232
- * Turn normal line endings into hard breaks.
114233
- *
114234
- * @param {Nodes} tree
114235
- * Tree to change.
114236
- * @returns {undefined}
114237
- * Nothing.
114238
- */
114239
- function newlineToBreak(tree) {
114240
- findAndReplace(tree, [/\r?\n|\r/g, lib_replace])
114241
- }
114242
-
114243
- /**
114244
- * Replace line endings.
114245
- *
114246
- * @type {ReplaceFunction}
114247
- */
114248
- function lib_replace() {
114249
- return {type: 'break'}
114250
- }
114251
-
114252
- ;// ./node_modules/remark-breaks/lib/index.js
114253
- /**
114254
- * @typedef {import('mdast').Root} Root
114255
- */
114256
-
114257
-
114258
-
114259
- /**
114260
- * Support hard breaks without needing spaces or escapes (turns enters into
114261
- * `<br>`s).
114262
- *
114263
- * @returns
114264
- * Transform.
114265
- */
114266
- function remarkBreaks() {
114267
- /**
114268
- * Transform.
114269
- *
114270
- * @param {Root} tree
114271
- * Tree.
114272
- * @returns {undefined}
114273
- * Nothing.
114274
- */
114275
- return function (tree) {
114276
- newlineToBreak(tree)
114277
- }
114278
- }
114279
-
114280
114491
  ;// ./processor/plugin/flatten-table-cell-paragraphs.ts
114281
114492
 
114282
114493
  /** List elements that cause margin issues when adjacent to paragraphs */
@@ -115056,87 +115267,6 @@ function emptyTaskListItemFromMarkdown() {
115056
115267
  };
115057
115268
  }
115058
115269
 
115059
- ;// ./lib/mdast-util/legacy-variable/index.ts
115060
-
115061
- const contextMap = new WeakMap();
115062
- function findlegacyVariableToken() {
115063
- // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
115064
- const events = this.tokenStack;
115065
- for (let i = events.length - 1; i >= 0; i -= 1) {
115066
- const token = events[i][0];
115067
- if (token.type === 'legacyVariable')
115068
- return token;
115069
- }
115070
- return undefined;
115071
- }
115072
- function enterlegacyVariable(token) {
115073
- contextMap.set(token, { value: '' });
115074
- }
115075
- function exitlegacyVariableValue(token) {
115076
- const variableToken = findlegacyVariableToken.call(this);
115077
- if (!variableToken)
115078
- return;
115079
- const ctx = contextMap.get(variableToken);
115080
- // Build up the variable characters
115081
- if (ctx)
115082
- ctx.value += this.sliceSerialize(token);
115083
- }
115084
- function exitlegacyVariable(token) {
115085
- const ctx = contextMap.get(token);
115086
- const serialized = this.sliceSerialize(token);
115087
- const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
115088
- ? serialized.slice(2, -2)
115089
- : ctx?.value ?? '';
115090
- const nodePosition = {
115091
- start: {
115092
- offset: token.start.offset,
115093
- line: token.start.line,
115094
- column: token.start.column,
115095
- },
115096
- end: {
115097
- offset: token.end.offset,
115098
- line: token.end.line,
115099
- column: token.end.column,
115100
- },
115101
- };
115102
- if (variableName.startsWith('glossary:')) {
115103
- const term = variableName.slice('glossary:'.length).trim();
115104
- this.enter({
115105
- type: NodeTypes.glossary,
115106
- data: {
115107
- hName: 'Glossary',
115108
- hProperties: { term },
115109
- },
115110
- children: [{ type: 'text', value: term }],
115111
- position: nodePosition,
115112
- }, token);
115113
- this.exit(token);
115114
- contextMap.delete(token);
115115
- return;
115116
- }
115117
- this.enter({
115118
- type: NodeTypes.variable,
115119
- data: {
115120
- hName: 'Variable',
115121
- hProperties: { name: variableName.trim(), isLegacy: true },
115122
- },
115123
- value: `<<${variableName}>>`,
115124
- }, token);
115125
- this.exit(token);
115126
- contextMap.delete(token);
115127
- }
115128
- function legacyVariableFromMarkdown() {
115129
- return {
115130
- enter: {
115131
- legacyVariable: enterlegacyVariable,
115132
- },
115133
- exit: {
115134
- legacyVariableValue: exitlegacyVariableValue,
115135
- legacyVariable: exitlegacyVariable,
115136
- },
115137
- };
115138
- }
115139
-
115140
115270
  ;// ./lib/mdast-util/magic-block/index.ts
115141
115271
  const magic_block_contextMap = new WeakMap();
115142
115272
  /**
@@ -115326,74 +115456,6 @@ function mdxComponentFromMarkdown() {
115326
115456
  };
115327
115457
  }
115328
115458
 
115329
- ;// ./lib/micromark/legacy-variable/syntax.ts
115330
-
115331
-
115332
- function isAllowedValueChar(code) {
115333
- return (code !== null &&
115334
- code !== codes.lessThan &&
115335
- code !== codes.greaterThan &&
115336
- !markdownLineEnding(code));
115337
- }
115338
- const legacyVariableConstruct = {
115339
- name: 'legacyVariable',
115340
- tokenize: syntax_tokenize,
115341
- };
115342
- function syntax_tokenize(effects, ok, nok) {
115343
- let hasValue = false;
115344
- const start = (code) => {
115345
- if (code !== codes.lessThan)
115346
- return nok(code);
115347
- effects.enter('legacyVariable');
115348
- effects.enter('legacyVariableMarkerStart');
115349
- effects.consume(code); // <
115350
- return open2;
115351
- };
115352
- const open2 = (code) => {
115353
- if (code !== codes.lessThan)
115354
- return nok(code);
115355
- effects.consume(code); // <<
115356
- effects.exit('legacyVariableMarkerStart');
115357
- effects.enter('legacyVariableValue');
115358
- return value;
115359
- };
115360
- const value = (code) => {
115361
- if (code === codes.greaterThan) {
115362
- if (!hasValue)
115363
- return nok(code);
115364
- effects.exit('legacyVariableValue');
115365
- effects.enter('legacyVariableMarkerEnd');
115366
- effects.consume(code); // >
115367
- return close2;
115368
- }
115369
- if (!isAllowedValueChar(code))
115370
- return nok(code);
115371
- hasValue = true;
115372
- effects.consume(code);
115373
- return value;
115374
- };
115375
- const close2 = (code) => {
115376
- if (code !== codes.greaterThan)
115377
- return nok(code);
115378
- effects.consume(code); // >>
115379
- effects.exit('legacyVariableMarkerEnd');
115380
- effects.exit('legacyVariable');
115381
- return ok;
115382
- };
115383
- return start;
115384
- }
115385
- function legacyVariable() {
115386
- return {
115387
- text: { [codes.lessThan]: legacyVariableConstruct },
115388
- };
115389
- }
115390
-
115391
- ;// ./lib/micromark/legacy-variable/index.ts
115392
- /**
115393
- * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
115394
- */
115395
-
115396
-
115397
115459
  ;// ./lib/micromark/magic-block/syntax.ts
115398
115460
 
115399
115461
 
@@ -120712,11 +120774,43 @@ const transformMagicBlockEmbed = (node) => {
120712
120774
  };
120713
120775
  };
120714
120776
  const mdxish_jsx_to_mdast_isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
120777
+ /**
120778
+ * Wraps bare `<td>`/`<th>` cells directly inside `<thead>`/`<tbody>` with an
120779
+ * implicit `<tr>`. remarkMdx may wrap inline JSX elements in paragraph nodes,
120780
+ * so unwrap those first.
120781
+ */
120782
+ const wrapBareCellsInRow = (node) => {
120783
+ visit(node, isMDXElement, (section) => {
120784
+ if (section.name !== 'thead' && section.name !== 'tbody')
120785
+ return;
120786
+ const children = section.children;
120787
+ const hasRow = children.some(c => isMDXElement(c) && c.name === 'tr');
120788
+ if (hasRow)
120789
+ return;
120790
+ const unwrapped = children.flatMap(c => {
120791
+ if (c.type === 'paragraph' && 'children' in c && Array.isArray(c.children)) {
120792
+ return c.children;
120793
+ }
120794
+ return [c];
120795
+ });
120796
+ const cells = unwrapped.filter(c => mdxish_jsx_to_mdast_isTableCell(c));
120797
+ if (cells.length === 0)
120798
+ return;
120799
+ const tr = {
120800
+ type: 'mdxJsxFlowElement',
120801
+ name: 'tr',
120802
+ attributes: [],
120803
+ children: cells,
120804
+ };
120805
+ section.children = [tr];
120806
+ });
120807
+ };
120715
120808
  /**
120716
120809
  * Converts a JSX <Table> element to an MDAST table node with alignment.
120717
120810
  * Returns null for header-less tables since MDAST always promotes the first row to <thead>.
120718
120811
  */
120719
120812
  const transformTable = (jsx) => {
120813
+ wrapBareCellsInRow(jsx);
120720
120814
  let hasThead = false;
120721
120815
  visit(jsx, isMDXElement, (child) => {
120722
120816
  if (child.name === 'thead')