@readme/markdown 15.7.0 → 15.7.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.
@@ -96172,31 +96172,11 @@ const HTML_VOID_ELEMENTS = new Set([
96172
96172
 
96173
96173
 
96174
96174
  /**
96175
- * Partial constructs the `mdxComponent` tokenizer runs via `effects.check` to
96176
- * decide whether the next line continues the block. They live here (not in
96177
- * `syntax.ts`) because they hold none of `createTokenize`'s closure state — each
96175
+ * Partial construct the `mdxComponent` tokenizer runs via `effects.check` to
96176
+ * decide whether the next line continues the block. It lives here (not in
96177
+ * `syntax.ts`) because it holds none of `createTokenize`'s closure state — it
96178
96178
  * is a self-contained, single-line lookahead.
96179
96179
  */
96180
- function continuation_checks_tokenizeNonLazyContinuationStart(effects, ok, nok) {
96181
- // eslint-disable-next-line @typescript-eslint/no-this-alias
96182
- const self = this;
96183
- return start;
96184
- function start(code) {
96185
- if (markdownLineEnding(code)) {
96186
- effects.enter(types_types.lineEnding);
96187
- effects.consume(code);
96188
- effects.exit(types_types.lineEnding);
96189
- return after;
96190
- }
96191
- return nok(code);
96192
- }
96193
- function after(code) {
96194
- if (self.parser.lazy[self.now().line]) {
96195
- return nok(code);
96196
- }
96197
- return ok(code);
96198
- }
96199
- }
96200
96180
  // A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
96201
96181
  // spaces) at a `>`. That distinguishes a structural continuation like
96202
96182
  // `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
@@ -96237,12 +96217,6 @@ function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
96237
96217
  return scanToLineEnd;
96238
96218
  }
96239
96219
  }
96240
- // A line ending whose next line isn't a lazy paragraph continuation. Checked so a
96241
- // component body's blank/continuation lines aren't stolen by an interrupted paragraph.
96242
- const continuation_checks_nonLazyContinuationStart = {
96243
- tokenize: continuation_checks_tokenizeNonLazyContinuationStart,
96244
- partial: true,
96245
- };
96246
96220
  // Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
96247
96221
  // that merely starts with a tag? Run via `effects.check` so it never consumes.
96248
96222
  const markupOnlyContinuation = {
@@ -96658,14 +96632,7 @@ function syntax_createTokenize(mode) {
96658
96632
  }
96659
96633
  // Continuation for multi-line opening tags
96660
96634
  function openTagContinuationStart(code) {
96661
- return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
96662
- }
96663
- function openTagContinuationNonLazy(code) {
96664
- sawLineEnding = true;
96665
- effects.enter(types_types.lineEnding);
96666
- effects.consume(code);
96667
- effects.exit(types_types.lineEnding);
96668
- return openTagContinuationBefore;
96635
+ return continueOnNextLine(code, openTagContinuationBefore);
96669
96636
  }
96670
96637
  function openTagContinuationBefore(code) {
96671
96638
  if (code === null || markdownLineEnding(code)) {
@@ -96783,14 +96750,7 @@ function syntax_createTokenize(mode) {
96783
96750
  return inFencedCode;
96784
96751
  }
96785
96752
  function fencedCodeContinuationStart(code) {
96786
- return effects.check(continuation_checks_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
96787
- }
96788
- function fencedCodeContinuationNonLazy(code) {
96789
- sawLineEnding = true;
96790
- effects.enter(types_types.lineEnding);
96791
- effects.consume(code);
96792
- effects.exit(types_types.lineEnding);
96793
- return fencedCodeContinuationBefore;
96753
+ return continueOnNextLine(code, fencedCodeContinuationBefore);
96794
96754
  }
96795
96755
  function fencedCodeContinuationBefore(code) {
96796
96756
  if (code === null || markdownLineEnding(code)) {
@@ -97007,14 +96967,7 @@ function syntax_createTokenize(mode) {
97007
96967
  }
97008
96968
  // ── Body continuation (line endings) ───────────────────────────────────
97009
96969
  function bodyContinuationStart(code) {
97010
- return effects.check(continuation_checks_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
97011
- }
97012
- function bodyContinuationNonLazy(code) {
97013
- sawLineEnding = true;
97014
- effects.enter(types_types.lineEnding);
97015
- effects.consume(code);
97016
- effects.exit(types_types.lineEnding);
97017
- return bodyContinuationBefore;
96970
+ return continueOnNextLine(code, bodyContinuationBefore);
97018
96971
  }
97019
96972
  function bodyContinuationBefore(code) {
97020
96973
  if (code === null || markdownLineEnding(code)) {
@@ -97083,13 +97036,18 @@ function syntax_createTokenize(mode) {
97083
97036
  pendingBlankLine = false;
97084
97037
  return bodyLineStart(code);
97085
97038
  }
97086
- // ── Shared lazy continuation failure ───────────────────────────────────
97087
- function continuationAfter(code) {
97088
- if (code === null) {
97039
+ // ── Shared line-ending continuation ────────────────────────────────────
97040
+ // Consumes one line ending and resumes at `nextLine`. Lazy lines (under-indented
97041
+ // under a list item or blockquote) continue too: a claim only ends at its closing
97042
+ // tag, and an unclosed one fails whole at EOF instead of leaving a truncated opener (CX-3940).
97043
+ function continueOnNextLine(code, nextLine) {
97044
+ if (!markdownLineEnding(code))
97089
97045
  return nok(code);
97090
- }
97091
- effects.exit('mdxComponent');
97092
- return ok(code);
97046
+ sawLineEnding = true;
97047
+ effects.enter(types_types.lineEnding);
97048
+ effects.consume(code);
97049
+ effects.exit(types_types.lineEnding);
97050
+ return nextLine;
97093
97051
  }
97094
97052
  };
97095
97053
  }
@@ -123346,7 +123304,7 @@ const parseMdChildren = (value, safeMode) => {
123346
123304
  // Promote nested wrappers bottom-up so an outer wrapper sees markdown buried in a
123347
123305
  // child claimed whole (e.g. `<li>` in `<ol>`) before its containsMarkdownConstruct check (RM-17560).
123348
123306
  // eslint-disable-next-line @typescript-eslint/no-use-before-define -- mutually recursive; hoisted decl, safe at runtime
123349
- promoteComponentBlocks(parsed, safeMode, null);
123307
+ promoteComponentBlocks(parsed, safeMode, reparseSource);
123350
123308
  const children = parsed.children || [];
123351
123309
  // These children root a new coordinate space: their offsets index into `reparseSource`.
123352
123310
  stampReparseSource(children, reparseSource);
@@ -123365,23 +123323,26 @@ const parseSibling = (parent, index, sibling, safeMode, promoted) => {
123365
123323
  }
123366
123324
  };
123367
123325
  // Ends the position at `consumedLength` so the component doesn't claim trailing
123368
- // content the tokenizer swallowed into the same html node.
123369
- const positionEndingAtConsumed = (nodePosition, value, consumedLength) => {
123326
+ // content the tokenizer swallowed into the same html node. Measured against the source
123327
+ // when available: each value line is its source line minus the container prefix
123328
+ // (list indent, `> `) micromark stripped, so those prefixes are counted back in.
123329
+ const positionEndingAtConsumed = (nodePosition, value, consumedLength, source) => {
123370
123330
  if (!nodePosition?.start)
123371
123331
  return nodePosition;
123372
- return { start: nodePosition.start, end: pointAfter(nodePosition.start, value.slice(0, consumedLength)) };
123373
- };
123374
- // Like `positionEndingAtConsumed`, but measures against the original source so
123375
- // blockquote/list prefixes stripped from the html node's value are counted.
123376
- const positionEndingAtClosingTagInSource = (nodePosition, closingTag, source) => {
123377
- if (!nodePosition?.start || !nodePosition.end)
123378
- return nodePosition;
123379
- const nodeSource = source.slice(nodePosition.start.offset, nodePosition.end.offset);
123380
- const closingTagOffset = nodeSource.lastIndexOf(closingTag);
123381
- if (closingTagOffset === -1)
123382
- return nodePosition;
123383
- const consumed = nodeSource.slice(0, closingTagOffset + closingTag.length);
123384
- return { start: nodePosition.start, end: pointAfter(nodePosition.start, consumed) };
123332
+ const consumedValue = value.slice(0, consumedLength);
123333
+ const sourceLines = source?.slice(nodePosition.start.offset, nodePosition.end?.offset).split('\n');
123334
+ const valueLines = value.split('\n');
123335
+ if (!sourceLines || sourceLines.length !== valueLines.length) {
123336
+ return { start: nodePosition.start, end: pointAfter(nodePosition.start, consumedValue) };
123337
+ }
123338
+ const consumedLines = consumedValue.split('\n');
123339
+ const lastLineIndex = consumedLines.length - 1;
123340
+ const prefixWidth = sourceLines[lastLineIndex].length - valueLines[lastLineIndex].length;
123341
+ const consumedSource = [
123342
+ ...sourceLines.slice(0, lastLineIndex),
123343
+ sourceLines[lastLineIndex].slice(0, prefixWidth + consumedLines[lastLineIndex].length),
123344
+ ].join('\n');
123345
+ return { start: nodePosition.start, end: pointAfter(nodePosition.start, consumedSource) };
123385
123346
  };
123386
123347
  const createComponentNode = ({ tag, attributes, children, startPosition, endPosition, }) => ({
123387
123348
  type: 'mdxJsxFlowElement',
@@ -123488,16 +123449,18 @@ function promoteComponentBlocks(tree, safeMode, source) {
123488
123449
  const closingTagStr = `</${tag}>`;
123489
123450
  // Case 1: Self-closing tag
123490
123451
  if (selfClosing) {
123452
+ const remainingContent = contentAfterTag.trim();
123491
123453
  const componentNode = createComponentNode({
123492
123454
  tag,
123493
123455
  attributes,
123494
123456
  children: [],
123495
123457
  startPosition: node.position,
123496
- // End at the self-closing tag, not at any trailing content.
123497
- endPosition: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd),
123458
+ // Without trailing content the whole node position is correct; with it, end at the tag.
123459
+ endPosition: remainingContent
123460
+ ? positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd, source)
123461
+ : node.position,
123498
123462
  });
123499
123463
  substituteNodeWithMdxNode(parent, index, componentNode);
123500
- const remainingContent = contentAfterTag.trim();
123501
123464
  if (remainingContent) {
123502
123465
  parseSibling(parent, index, remainingContent, safeMode, promoted);
123503
123466
  }
@@ -123536,14 +123499,10 @@ function promoteComponentBlocks(tree, safeMode, source) {
123536
123499
  stampReparseSource(parsedChildren, soleParagraph.data.reparseSource);
123537
123500
  unwrappedSoleParagraph = true;
123538
123501
  }
123539
- // Without trailing content the whole node position is correct. With it, end
123540
- // precisely at the closing tag — preferring source offsets when available (the
123541
- // node's value strips blockquote/list prefixes), else the consumed span.
123502
+ // Without trailing content the whole node position is correct; with it, end at the closing tag.
123542
123503
  let endPosition = node.position;
123543
123504
  if (contentAfterClose) {
123544
- endPosition = source
123545
- ? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
123546
- : positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length);
123505
+ endPosition = positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length, source);
123547
123506
  }
123548
123507
  const componentNode = createComponentNode({
123549
123508
  tag,