@readme/markdown 14.2.5 → 14.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -100232,6 +100232,14 @@ function createTokenize(mode) {
100232
100232
  let fenceLength = 0;
100233
100233
  let fenceCloseLength = 0;
100234
100234
  let atLineStart = false;
100235
+ // Bail when the opener line has unmatched tag-like tokens in its body.
100236
+ // `<Foo>_<Bar>.csv` leaves opens > closes; matched shapes like
100237
+ // `<Callout>x <strong>y</strong>` balance to 0. Without this,
100238
+ // `concrete: true` causes orphan openers to eat sibling blockquotes.
100239
+ let onOpenerLine = false;
100240
+ let openerLineHasContent = false;
100241
+ let openerLineOpens = 0;
100242
+ let openerLineCloses = 0;
100235
100243
  // Attribute parsing state
100236
100244
  let quoteChar = null;
100237
100245
  let braceDepth = 0;
@@ -100320,6 +100328,7 @@ function createTokenize(mode) {
100320
100328
  if (isLowercaseTag && !sawBraceAttr)
100321
100329
  return nok(code);
100322
100330
  effects.consume(code);
100331
+ onOpenerLine = isFlow;
100323
100332
  return body;
100324
100333
  }
100325
100334
  // Quoted attribute value
@@ -100529,10 +100538,19 @@ function createTokenize(mode) {
100529
100538
  if (markdownLineEnding(code)) {
100530
100539
  if (!isFlow)
100531
100540
  return nok(code);
100541
+ // See `onOpenerLine` declaration. Bail iff the opener line had
100542
+ // content AND more opener-shaped tokens than closer-shaped tokens.
100543
+ if (onOpenerLine && openerLineHasContent && openerLineOpens > openerLineCloses) {
100544
+ return nok(code);
100545
+ }
100546
+ onOpenerLine = false;
100532
100547
  effects.exit('mdxComponentData');
100533
100548
  atLineStart = true;
100534
100549
  return bodyContinuationStart(code);
100535
100550
  }
100551
+ if (code !== codes.space && code !== codes.horizontalTab) {
100552
+ openerLineHasContent = true;
100553
+ }
100536
100554
  if (code === codes.backslash) {
100537
100555
  effects.consume(code);
100538
100556
  return bodyEscapedChar;
@@ -100680,16 +100698,26 @@ function createTokenize(mode) {
100680
100698
  // ── Tag detection inside body ──────────────────────────────────────────
100681
100699
  function bodyLessThan(code) {
100682
100700
  if (code === codes.slash) {
100701
+ if (onOpenerLine)
100702
+ openerLineCloses += 1;
100683
100703
  effects.consume(code);
100684
100704
  closingTagName = '';
100685
100705
  return closingTagNameFirst;
100686
100706
  }
100687
100707
  // Potential nested opening tag (same case class as the outer tag)
100688
100708
  if (code !== null && isAlpha(code) && isSameCaseAsTag(code)) {
100709
+ if (onOpenerLine)
100710
+ openerLineOpens += 1;
100689
100711
  closingTagName = String.fromCharCode(code);
100690
100712
  effects.consume(code);
100691
100713
  return nestedOpenTagName;
100692
100714
  }
100715
+ // Tag-like token but not in nested-tracking case (different case).
100716
+ // Count it for the opener-line bail heuristic anyway: `<strong>` in
100717
+ // `<Callout>x <strong>y</strong></Callout>` should pair with `</strong>`.
100718
+ if (code !== null && isAlpha(code) && onOpenerLine) {
100719
+ openerLineOpens += 1;
100720
+ }
100693
100721
  atLineStart = false;
100694
100722
  return body(code);
100695
100723
  }
@@ -103165,14 +103193,24 @@ const transformImage = (jsx) => {
103165
103193
  */
103166
103194
  const transformCallout = (jsx) => {
103167
103195
  const attrs = getAttrs(jsx);
103168
- const { empty = false, icon = '', theme = '' } = attrs;
103196
+ const { empty: explicitEmpty = false, icon = '', theme = '' } = attrs;
103197
+ // children[0] is the title slot. Prepend an empty-paragraph placeholder
103198
+ // when JSX has no leading heading, otherwise the body round-trips into it.
103199
+ const jsxChildren = jsx.children;
103200
+ const hasHeadingFirst = jsxChildren[0]?.type === 'heading';
103201
+ const children = hasHeadingFirst
103202
+ ? jsxChildren
103203
+ : [
103204
+ { type: 'paragraph', children: [{ type: 'text', value: '' }] },
103205
+ ...jsxChildren,
103206
+ ];
103169
103207
  return {
103170
103208
  type: NodeTypes.callout,
103171
- children: jsx.children,
103209
+ children,
103172
103210
  data: {
103173
103211
  hName: 'Callout',
103174
103212
  hProperties: {
103175
- empty,
103213
+ empty: explicitEmpty || !hasHeadingFirst,
103176
103214
  icon,
103177
103215
  theme,
103178
103216
  },
@@ -103449,6 +103487,10 @@ const mdxishJsxToMdast = () => tree => {
103449
103487
  return SKIP;
103450
103488
  if (parent.type === 'paragraph')
103451
103489
  return SKIP;
103490
+ // `![](url)` in any tableCell stays inline. Authors who want a captioned figure use
103491
+ // `<Image caption="…" />` JSX, which becomes `image-block` via `COMPONENT_MAP` above.
103492
+ if (parent.type === 'tableCell')
103493
+ return SKIP;
103452
103494
  const newNode = transformMagicBlockImage(node);
103453
103495
  parent.children[index] = newNode;
103454
103496
  return SKIP;
@@ -104051,6 +104093,8 @@ const variablesCodeResolver = ({ variables } = {}) => tree => {
104051
104093
  visit(tree, 'code', (node) => {
104052
104094
  if (!node.value)
104053
104095
  return;
104096
+ if (node.lang === 'mermaid')
104097
+ return;
104054
104098
  const nextValue = resolveCodeVariables(node.value, resolvedVariables);
104055
104099
  node.value = nextValue;
104056
104100
  // Keep code-tabs/readme-components hProperties in sync with node.value
package/dist/main.node.js CHANGED
@@ -120426,6 +120426,14 @@ function createTokenize(mode) {
120426
120426
  let fenceLength = 0;
120427
120427
  let fenceCloseLength = 0;
120428
120428
  let atLineStart = false;
120429
+ // Bail when the opener line has unmatched tag-like tokens in its body.
120430
+ // `<Foo>_<Bar>.csv` leaves opens > closes; matched shapes like
120431
+ // `<Callout>x <strong>y</strong>` balance to 0. Without this,
120432
+ // `concrete: true` causes orphan openers to eat sibling blockquotes.
120433
+ let onOpenerLine = false;
120434
+ let openerLineHasContent = false;
120435
+ let openerLineOpens = 0;
120436
+ let openerLineCloses = 0;
120429
120437
  // Attribute parsing state
120430
120438
  let quoteChar = null;
120431
120439
  let braceDepth = 0;
@@ -120514,6 +120522,7 @@ function createTokenize(mode) {
120514
120522
  if (isLowercaseTag && !sawBraceAttr)
120515
120523
  return nok(code);
120516
120524
  effects.consume(code);
120525
+ onOpenerLine = isFlow;
120517
120526
  return body;
120518
120527
  }
120519
120528
  // Quoted attribute value
@@ -120723,10 +120732,19 @@ function createTokenize(mode) {
120723
120732
  if (markdownLineEnding(code)) {
120724
120733
  if (!isFlow)
120725
120734
  return nok(code);
120735
+ // See `onOpenerLine` declaration. Bail iff the opener line had
120736
+ // content AND more opener-shaped tokens than closer-shaped tokens.
120737
+ if (onOpenerLine && openerLineHasContent && openerLineOpens > openerLineCloses) {
120738
+ return nok(code);
120739
+ }
120740
+ onOpenerLine = false;
120726
120741
  effects.exit('mdxComponentData');
120727
120742
  atLineStart = true;
120728
120743
  return bodyContinuationStart(code);
120729
120744
  }
120745
+ if (code !== codes.space && code !== codes.horizontalTab) {
120746
+ openerLineHasContent = true;
120747
+ }
120730
120748
  if (code === codes.backslash) {
120731
120749
  effects.consume(code);
120732
120750
  return bodyEscapedChar;
@@ -120874,16 +120892,26 @@ function createTokenize(mode) {
120874
120892
  // ── Tag detection inside body ──────────────────────────────────────────
120875
120893
  function bodyLessThan(code) {
120876
120894
  if (code === codes.slash) {
120895
+ if (onOpenerLine)
120896
+ openerLineCloses += 1;
120877
120897
  effects.consume(code);
120878
120898
  closingTagName = '';
120879
120899
  return closingTagNameFirst;
120880
120900
  }
120881
120901
  // Potential nested opening tag (same case class as the outer tag)
120882
120902
  if (code !== null && isAlpha(code) && isSameCaseAsTag(code)) {
120903
+ if (onOpenerLine)
120904
+ openerLineOpens += 1;
120883
120905
  closingTagName = String.fromCharCode(code);
120884
120906
  effects.consume(code);
120885
120907
  return nestedOpenTagName;
120886
120908
  }
120909
+ // Tag-like token but not in nested-tracking case (different case).
120910
+ // Count it for the opener-line bail heuristic anyway: `<strong>` in
120911
+ // `<Callout>x <strong>y</strong></Callout>` should pair with `</strong>`.
120912
+ if (code !== null && isAlpha(code) && onOpenerLine) {
120913
+ openerLineOpens += 1;
120914
+ }
120887
120915
  atLineStart = false;
120888
120916
  return body(code);
120889
120917
  }
@@ -123359,14 +123387,24 @@ const transformImage = (jsx) => {
123359
123387
  */
123360
123388
  const transformCallout = (jsx) => {
123361
123389
  const attrs = getAttrs(jsx);
123362
- const { empty = false, icon = '', theme = '' } = attrs;
123390
+ const { empty: explicitEmpty = false, icon = '', theme = '' } = attrs;
123391
+ // children[0] is the title slot. Prepend an empty-paragraph placeholder
123392
+ // when JSX has no leading heading, otherwise the body round-trips into it.
123393
+ const jsxChildren = jsx.children;
123394
+ const hasHeadingFirst = jsxChildren[0]?.type === 'heading';
123395
+ const children = hasHeadingFirst
123396
+ ? jsxChildren
123397
+ : [
123398
+ { type: 'paragraph', children: [{ type: 'text', value: '' }] },
123399
+ ...jsxChildren,
123400
+ ];
123363
123401
  return {
123364
123402
  type: NodeTypes.callout,
123365
- children: jsx.children,
123403
+ children,
123366
123404
  data: {
123367
123405
  hName: 'Callout',
123368
123406
  hProperties: {
123369
- empty,
123407
+ empty: explicitEmpty || !hasHeadingFirst,
123370
123408
  icon,
123371
123409
  theme,
123372
123410
  },
@@ -123643,6 +123681,10 @@ const mdxishJsxToMdast = () => tree => {
123643
123681
  return SKIP;
123644
123682
  if (parent.type === 'paragraph')
123645
123683
  return SKIP;
123684
+ // `![](url)` in any tableCell stays inline. Authors who want a captioned figure use
123685
+ // `<Image caption="…" />` JSX, which becomes `image-block` via `COMPONENT_MAP` above.
123686
+ if (parent.type === 'tableCell')
123687
+ return SKIP;
123646
123688
  const newNode = transformMagicBlockImage(node);
123647
123689
  parent.children[index] = newNode;
123648
123690
  return SKIP;
@@ -124245,6 +124287,8 @@ const variablesCodeResolver = ({ variables } = {}) => tree => {
124245
124287
  visit(tree, 'code', (node) => {
124246
124288
  if (!node.value)
124247
124289
  return;
124290
+ if (node.lang === 'mermaid')
124291
+ return;
124248
124292
  const nextValue = resolveCodeVariables(node.value, resolvedVariables);
124249
124293
  node.value = nextValue;
124250
124294
  // Keep code-tabs/readme-components hProperties in sync with node.value