@readme/markdown 14.2.0 → 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
@@ -91424,6 +91424,87 @@ function gemojiFromMarkdown() {
91424
91424
  };
91425
91425
  }
91426
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
+
91427
91508
  ;// ./node_modules/micromark-util-symbol/lib/codes.js
91428
91509
  /**
91429
91510
  * Character codes.
@@ -91677,6 +91758,74 @@ function syntax_gemoji() {
91677
91758
  */
91678
91759
 
91679
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
+
91680
91829
  ;// ./processor/transform/mdxish/normalize-malformed-md-syntax.ts
91681
91830
 
91682
91831
  // Marker patterns for multi-node emphasis detection
@@ -92055,20 +92204,59 @@ const unwrapSoleParagraph = (children) => {
92055
92204
 
92056
92205
 
92057
92206
 
92207
+
92208
+
92209
+
92058
92210
  const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
92059
92211
  const tableTypes = {
92060
92212
  tr: 'tableRow',
92061
92213
  th: 'tableCell',
92062
92214
  td: 'tableCell',
92063
92215
  };
92064
- const tableNodeProcessor = unified()
92065
- .data('micromarkExtensions', [syntax_gemoji()])
92066
- .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
+ ])
92067
92227
  .use(remarkParse)
92068
- .use(remarkMdx)
92069
92228
  .use(normalize_malformed_md_syntax)
92070
92229
  .use([[callouts, { isMdxish: true }], code_tabs])
92071
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
+ };
92072
92260
  /**
92073
92261
  * Check if children are only text nodes that might contain markdown
92074
92262
  */
@@ -92171,27 +92359,54 @@ const processTableNode = (node, index, parent, documentPosition) => {
92171
92359
  }
92172
92360
  // All cells are phrasing-only — convert to markdown table
92173
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]);
92174
92378
  visit(node, isMDXElement, (child) => {
92175
- 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) {
92176
92384
  visit(child, isMDXElement, (row) => {
92177
92385
  if (row.name !== 'tr')
92178
92386
  return;
92179
- const rowChildren = [];
92180
- visit(row, isTableCell, ({ name, children: cellChildren, position: cellPosition }) => {
92181
- const parsedChildren = unwrapSoleParagraph(cellChildren);
92182
- rowChildren.push({
92183
- type: tableTypes[name],
92184
- children: parsedChildren,
92185
- position: cellPosition,
92186
- });
92187
- });
92188
92387
  children.push({
92189
92388
  type: 'tableRow',
92190
- children: rowChildren,
92389
+ children: collectCells(row),
92191
92390
  position: row.position,
92192
92391
  });
92193
92392
  });
92194
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
+ }
92195
92410
  });
92196
92411
  const firstRow = children[0];
92197
92412
  const columnCount = firstRow?.children?.length || 0;
@@ -92224,35 +92439,22 @@ const mdxishTables = () => tree => {
92224
92439
  return;
92225
92440
  if (!node.value.startsWith('<Table') && !node.value.startsWith('<table'))
92226
92441
  return;
92227
- try {
92228
- const parsed = tableNodeProcessor.runSync(tableNodeProcessor.parse(node.value));
92229
- // since we use a subparser in `tableNodeProcessor` to parse `node.value`,
92230
- // positions are relative to that substring. shifting them by the base
92231
- // offset and line number makes them valid in the outer source coordinate space.
92232
- // otherwise, consumers who directly slice based on position would read and grab the
92233
- // wrong content
92234
- const baseOffset = node.position?.start?.offset ?? 0;
92235
- const baseLine = (node.position?.start?.line ?? 1) - 1;
92236
- visit(parsed, child => {
92237
- if (child.position?.start) {
92238
- child.position.start.offset = (child.position.start.offset ?? 0) + baseOffset;
92239
- child.position.start.line += baseLine;
92240
- }
92241
- if (child.position?.end) {
92242
- child.position.end.offset = (child.position.end.offset ?? 0) + baseOffset;
92243
- child.position.end.line += baseLine;
92244
- }
92245
- });
92442
+ const parsed = parseTableNode(tableNodeProcessor, node);
92443
+ if (parsed) {
92246
92444
  visit(parsed, isMDXElement, (tableNode) => {
92247
92445
  if (tableNode.name !== 'Table' && tableNode.name !== 'table')
92248
92446
  return undefined;
92249
92447
  processTableNode(tableNode, index, parent, node.position);
92250
92448
  return EXIT;
92251
92449
  });
92450
+ return;
92252
92451
  }
92253
- catch {
92254
- // If parsing fails, leave the node as-is
92255
- }
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);
92256
92458
  });
92257
92459
  return tree;
92258
92460
  };
@@ -115065,87 +115267,6 @@ function emptyTaskListItemFromMarkdown() {
115065
115267
  };
115066
115268
  }
115067
115269
 
115068
- ;// ./lib/mdast-util/legacy-variable/index.ts
115069
-
115070
- const contextMap = new WeakMap();
115071
- function findlegacyVariableToken() {
115072
- // tokenStack is micromark's current open token ancestry; find the nearest legacyVariable token.
115073
- const events = this.tokenStack;
115074
- for (let i = events.length - 1; i >= 0; i -= 1) {
115075
- const token = events[i][0];
115076
- if (token.type === 'legacyVariable')
115077
- return token;
115078
- }
115079
- return undefined;
115080
- }
115081
- function enterlegacyVariable(token) {
115082
- contextMap.set(token, { value: '' });
115083
- }
115084
- function exitlegacyVariableValue(token) {
115085
- const variableToken = findlegacyVariableToken.call(this);
115086
- if (!variableToken)
115087
- return;
115088
- const ctx = contextMap.get(variableToken);
115089
- // Build up the variable characters
115090
- if (ctx)
115091
- ctx.value += this.sliceSerialize(token);
115092
- }
115093
- function exitlegacyVariable(token) {
115094
- const ctx = contextMap.get(token);
115095
- const serialized = this.sliceSerialize(token);
115096
- const variableName = serialized.startsWith('<<') && serialized.endsWith('>>')
115097
- ? serialized.slice(2, -2)
115098
- : ctx?.value ?? '';
115099
- const nodePosition = {
115100
- start: {
115101
- offset: token.start.offset,
115102
- line: token.start.line,
115103
- column: token.start.column,
115104
- },
115105
- end: {
115106
- offset: token.end.offset,
115107
- line: token.end.line,
115108
- column: token.end.column,
115109
- },
115110
- };
115111
- if (variableName.startsWith('glossary:')) {
115112
- const term = variableName.slice('glossary:'.length).trim();
115113
- this.enter({
115114
- type: NodeTypes.glossary,
115115
- data: {
115116
- hName: 'Glossary',
115117
- hProperties: { term },
115118
- },
115119
- children: [{ type: 'text', value: term }],
115120
- position: nodePosition,
115121
- }, token);
115122
- this.exit(token);
115123
- contextMap.delete(token);
115124
- return;
115125
- }
115126
- this.enter({
115127
- type: NodeTypes.variable,
115128
- data: {
115129
- hName: 'Variable',
115130
- hProperties: { name: variableName.trim(), isLegacy: true },
115131
- },
115132
- value: `<<${variableName}>>`,
115133
- }, token);
115134
- this.exit(token);
115135
- contextMap.delete(token);
115136
- }
115137
- function legacyVariableFromMarkdown() {
115138
- return {
115139
- enter: {
115140
- legacyVariable: enterlegacyVariable,
115141
- },
115142
- exit: {
115143
- legacyVariableValue: exitlegacyVariableValue,
115144
- legacyVariable: exitlegacyVariable,
115145
- },
115146
- };
115147
- }
115148
-
115149
115270
  ;// ./lib/mdast-util/magic-block/index.ts
115150
115271
  const magic_block_contextMap = new WeakMap();
115151
115272
  /**
@@ -115335,74 +115456,6 @@ function mdxComponentFromMarkdown() {
115335
115456
  };
115336
115457
  }
115337
115458
 
115338
- ;// ./lib/micromark/legacy-variable/syntax.ts
115339
-
115340
-
115341
- function isAllowedValueChar(code) {
115342
- return (code !== null &&
115343
- code !== codes.lessThan &&
115344
- code !== codes.greaterThan &&
115345
- !markdownLineEnding(code));
115346
- }
115347
- const legacyVariableConstruct = {
115348
- name: 'legacyVariable',
115349
- tokenize: syntax_tokenize,
115350
- };
115351
- function syntax_tokenize(effects, ok, nok) {
115352
- let hasValue = false;
115353
- const start = (code) => {
115354
- if (code !== codes.lessThan)
115355
- return nok(code);
115356
- effects.enter('legacyVariable');
115357
- effects.enter('legacyVariableMarkerStart');
115358
- effects.consume(code); // <
115359
- return open2;
115360
- };
115361
- const open2 = (code) => {
115362
- if (code !== codes.lessThan)
115363
- return nok(code);
115364
- effects.consume(code); // <<
115365
- effects.exit('legacyVariableMarkerStart');
115366
- effects.enter('legacyVariableValue');
115367
- return value;
115368
- };
115369
- const value = (code) => {
115370
- if (code === codes.greaterThan) {
115371
- if (!hasValue)
115372
- return nok(code);
115373
- effects.exit('legacyVariableValue');
115374
- effects.enter('legacyVariableMarkerEnd');
115375
- effects.consume(code); // >
115376
- return close2;
115377
- }
115378
- if (!isAllowedValueChar(code))
115379
- return nok(code);
115380
- hasValue = true;
115381
- effects.consume(code);
115382
- return value;
115383
- };
115384
- const close2 = (code) => {
115385
- if (code !== codes.greaterThan)
115386
- return nok(code);
115387
- effects.consume(code); // >>
115388
- effects.exit('legacyVariableMarkerEnd');
115389
- effects.exit('legacyVariable');
115390
- return ok;
115391
- };
115392
- return start;
115393
- }
115394
- function legacyVariable() {
115395
- return {
115396
- text: { [codes.lessThan]: legacyVariableConstruct },
115397
- };
115398
- }
115399
-
115400
- ;// ./lib/micromark/legacy-variable/index.ts
115401
- /**
115402
- * Micromark extension for <<variable>> / <<glossary:term>> inline syntax.
115403
- */
115404
-
115405
-
115406
115459
  ;// ./lib/micromark/magic-block/syntax.ts
115407
115460
 
115408
115461
 
@@ -120721,11 +120774,43 @@ const transformMagicBlockEmbed = (node) => {
120721
120774
  };
120722
120775
  };
120723
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
+ };
120724
120808
  /**
120725
120809
  * Converts a JSX <Table> element to an MDAST table node with alignment.
120726
120810
  * Returns null for header-less tables since MDAST always promotes the first row to <thead>.
120727
120811
  */
120728
120812
  const transformTable = (jsx) => {
120813
+ wrapBareCellsInRow(jsx);
120729
120814
  let hasThead = false;
120730
120815
  visit(jsx, isMDXElement, (child) => {
120731
120816
  if (child.name === 'thead')