@readme/markdown 14.13.0 → 14.13.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/components/Accordion/style.scss +4 -0
- package/components/TailwindRoot/index.tsx +4 -0
- package/dist/example/components.d.ts +2 -0
- package/dist/lib/mdxish.d.ts +1 -1
- package/dist/lib/micromark/mdx-component/continuation-checks.d.ts +3 -0
- package/dist/lib/renderMdxish.d.ts +1 -1
- package/dist/main.css +2 -2
- package/dist/main.css.map +1 -1
- package/dist/main.js +243 -116
- package/dist/main.node.js +243 -116
- package/dist/main.node.js.map +1 -1
- package/dist/processor/plugin/mdxish-components.d.ts +1 -1
- package/dist/processor/transform/mdxish/components/mdx-blocks.d.ts +0 -31
- package/dist/render-fixture.css +1 -1
- package/dist/render-fixture.css.map +1 -1
- package/dist/render-fixture.node.js +243 -116
- package/dist/render-fixture.node.js.map +1 -1
- package/dist/utils/common-html-words.d.ts +9 -0
- package/package.json +1 -1
- package/styles/gfm.scss +15 -1
|
@@ -92197,6 +92197,10 @@ const tailwindPrefix = 'readme-tailwind';
|
|
|
92197
92197
|
|
|
92198
92198
|
|
|
92199
92199
|
const TailwindRoot = ({ children, flow }) => {
|
|
92200
|
+
// `styles/gfm.scss` spaces the wrapped block children through this element and
|
|
92201
|
+
// relies on their margins collapsing through it. Keep it a plain block — no
|
|
92202
|
+
// border, padding, or block formatting context (overflow, display: flow-root/
|
|
92203
|
+
// flex/grid) — or the spacing breaks.
|
|
92200
92204
|
const Tag = flow ? 'div' : 'span';
|
|
92201
92205
|
return external_react_default().createElement(Tag, { className: tailwindPrefix }, children);
|
|
92202
92206
|
};
|
|
@@ -96476,6 +96480,15 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
96476
96480
|
'caption',
|
|
96477
96481
|
'colgroup',
|
|
96478
96482
|
]);
|
|
96483
|
+
/**
|
|
96484
|
+
* Tags whose bodies a later mdxish transform keeps raw and never re-parses as
|
|
96485
|
+
* markdown. Both layers depend on this property, not on the tags being figures:
|
|
96486
|
+
* the transformer treats them as non-promotable, and the tokenizer must not claim
|
|
96487
|
+
* markdown islands inside them (a claimed island would never be re-parsed and would
|
|
96488
|
+
* leak as literal text). Currently just the figure tags, whose bodies are owned by
|
|
96489
|
+
* the figure reassembly transform (`mdxishJsxToMdast`).
|
|
96490
|
+
*/
|
|
96491
|
+
const NON_REPARSED_BODY_TAGS = new Set(['figure', 'figcaption']);
|
|
96479
96492
|
/**
|
|
96480
96493
|
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
96481
96494
|
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
@@ -117853,7 +117866,7 @@ function normalizeProperties(node) {
|
|
|
117853
117866
|
* Identifies custom MDX components and recursively parses markdown children.
|
|
117854
117867
|
* Replaces tagName with PascalCase component name for React component resolution.
|
|
117855
117868
|
*
|
|
117856
|
-
* @see
|
|
117869
|
+
* @see .claude/context/MDXish/Processor Overview.md
|
|
117857
117870
|
* @param {Options} options - Configuration options
|
|
117858
117871
|
* @param {CustomComponents} options.components - Available custom components
|
|
117859
117872
|
* @param {Function} options.processMarkdown - Function to process markdown content
|
|
@@ -120253,12 +120266,95 @@ function tokenizeMagicBlockText(effects, ok, nok) {
|
|
|
120253
120266
|
*/
|
|
120254
120267
|
|
|
120255
120268
|
|
|
120269
|
+
;// ./lib/micromark/mdx-component/continuation-checks.ts
|
|
120270
|
+
|
|
120271
|
+
|
|
120272
|
+
/**
|
|
120273
|
+
* Partial constructs the `mdxComponent` tokenizer runs via `effects.check` to
|
|
120274
|
+
* decide whether the next line continues the block. They live here (not in
|
|
120275
|
+
* `syntax.ts`) because they hold none of `createTokenize`'s closure state — each
|
|
120276
|
+
* is a self-contained, single-line lookahead.
|
|
120277
|
+
*/
|
|
120278
|
+
function continuation_checks_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
120279
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
120280
|
+
const self = this;
|
|
120281
|
+
return start;
|
|
120282
|
+
function start(code) {
|
|
120283
|
+
if (markdownLineEnding(code)) {
|
|
120284
|
+
effects.enter(types_types.lineEnding);
|
|
120285
|
+
effects.consume(code);
|
|
120286
|
+
effects.exit(types_types.lineEnding);
|
|
120287
|
+
return after;
|
|
120288
|
+
}
|
|
120289
|
+
return nok(code);
|
|
120290
|
+
}
|
|
120291
|
+
function after(code) {
|
|
120292
|
+
if (self.parser.lazy[self.now().line]) {
|
|
120293
|
+
return nok(code);
|
|
120294
|
+
}
|
|
120295
|
+
return ok(code);
|
|
120296
|
+
}
|
|
120297
|
+
}
|
|
120298
|
+
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
120299
|
+
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
120300
|
+
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
120301
|
+
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
120302
|
+
let lastNonSpace = null;
|
|
120303
|
+
return start;
|
|
120304
|
+
function start(code) {
|
|
120305
|
+
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
120306
|
+
effects.enter(types_types.data);
|
|
120307
|
+
effects.consume(code);
|
|
120308
|
+
return afterLessThan;
|
|
120309
|
+
}
|
|
120310
|
+
function afterLessThan(code) {
|
|
120311
|
+
if (code === codes.slash) {
|
|
120312
|
+
effects.consume(code);
|
|
120313
|
+
return afterSlash;
|
|
120314
|
+
}
|
|
120315
|
+
return afterSlash(code);
|
|
120316
|
+
}
|
|
120317
|
+
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
120318
|
+
function afterSlash(code) {
|
|
120319
|
+
if (asciiAlpha(code)) {
|
|
120320
|
+
lastNonSpace = code;
|
|
120321
|
+
effects.consume(code);
|
|
120322
|
+
return scanToLineEnd;
|
|
120323
|
+
}
|
|
120324
|
+
effects.exit(types_types.data);
|
|
120325
|
+
return nok(code);
|
|
120326
|
+
}
|
|
120327
|
+
function scanToLineEnd(code) {
|
|
120328
|
+
if (code === null || markdownLineEnding(code)) {
|
|
120329
|
+
effects.exit(types_types.data);
|
|
120330
|
+
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
120331
|
+
}
|
|
120332
|
+
if (!markdownSpace(code))
|
|
120333
|
+
lastNonSpace = code;
|
|
120334
|
+
effects.consume(code);
|
|
120335
|
+
return scanToLineEnd;
|
|
120336
|
+
}
|
|
120337
|
+
}
|
|
120338
|
+
// A line ending whose next line isn't a lazy paragraph continuation. Checked so a
|
|
120339
|
+
// component body's blank/continuation lines aren't stolen by an interrupted paragraph.
|
|
120340
|
+
const continuation_checks_nonLazyContinuationStart = {
|
|
120341
|
+
tokenize: continuation_checks_tokenizeNonLazyContinuationStart,
|
|
120342
|
+
partial: true,
|
|
120343
|
+
};
|
|
120344
|
+
// Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
|
|
120345
|
+
// that merely starts with a tag? Run via `effects.check` so it never consumes.
|
|
120346
|
+
const markupOnlyContinuation = {
|
|
120347
|
+
tokenize: tokenizeMarkupOnlyContinuation,
|
|
120348
|
+
partial: true,
|
|
120349
|
+
};
|
|
120350
|
+
|
|
120256
120351
|
;// ./lib/micromark/mdx-component/syntax.ts
|
|
120257
120352
|
|
|
120258
120353
|
|
|
120259
120354
|
|
|
120260
120355
|
|
|
120261
120356
|
|
|
120357
|
+
|
|
120262
120358
|
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
120263
120359
|
// section, …) always start a block, so they stay flow even with trailing
|
|
120264
120360
|
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
@@ -120268,16 +120364,19 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
|
120268
120364
|
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
120269
120365
|
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
120270
120366
|
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
120271
|
-
const
|
|
120272
|
-
|
|
120273
|
-
|
|
120274
|
-
|
|
120275
|
-
//
|
|
120276
|
-
//
|
|
120277
|
-
const
|
|
120278
|
-
|
|
120279
|
-
|
|
120280
|
-
|
|
120367
|
+
const foreignContentTags = new Set(FOREIGN_CONTENT_TAGS);
|
|
120368
|
+
// Type-7 lowercase tags (a, span, button, and unknown names): CommonMark ends their
|
|
120369
|
+
// block at a blank line, fragmenting 4+ column children into indented code. Claimable
|
|
120370
|
+
// only in block-wrapper shape (see `blockWrapperOpenerRest`); lookalike openers
|
|
120371
|
+
// (`<https://…>`) never find a closer, so their claim retreats cleanly to CommonMark.
|
|
120372
|
+
// Voids never close and raw/foreign-content bodies have dedicated owners.
|
|
120373
|
+
const isBlockWrapperClaimTagName = (tag) => !htmlFlowTagNames.has(tag) && !HTML_VOID_ELEMENTS.has(tag) && !foreignContentTags.has(tag);
|
|
120374
|
+
// Both are 4 columns per CommonMark, but they mean different things: a tab advances
|
|
120375
|
+
// to the next multiple of TAB_STOP_WIDTH, and INDENTED_CODE_MIN_COLUMNS is the depth
|
|
120376
|
+
// at which a line would fragment into indented code. Named separately so the two
|
|
120377
|
+
// concepts don't read as one incidental literal.
|
|
120378
|
+
const TAB_STOP_WIDTH = 4;
|
|
120379
|
+
const INDENTED_CODE_MIN_COLUMNS = 4;
|
|
120281
120380
|
function resolveToMdxComponent(events) {
|
|
120282
120381
|
let index = events.length;
|
|
120283
120382
|
while (index > 0) {
|
|
@@ -120336,6 +120435,23 @@ function createTokenize(mode) {
|
|
|
120336
120435
|
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
120337
120436
|
let isPlainBlockClaim = false;
|
|
120338
120437
|
let pendingBlankLine = false;
|
|
120438
|
+
// Type-7 tag claimed pending the block-wrapper (opener alone on its line) check.
|
|
120439
|
+
let pendingBlockWrapperClaim = false;
|
|
120440
|
+
// True once a block-wrapper claim is confirmed; relaxes the top-of-body island gate
|
|
120441
|
+
// below (type-7 fallback is the fragmentation bug, not intentional indented code).
|
|
120442
|
+
let isBlockWrapperClaim = false;
|
|
120443
|
+
// Leading indent columns of the current plain-claim line, reset per line; ≥4 is
|
|
120444
|
+
// where CommonMark would fragment the island as indented code. Tabs advance to the
|
|
120445
|
+
// next 4-column stop — the same rule `expandIndentToColumns`
|
|
120446
|
+
// (processor/transform/mdxish/indentation.ts) applies, kept in sync by hand since
|
|
120447
|
+
// this side works on a `Code` stream, not a string. NB: do NOT swap this for
|
|
120448
|
+
// `self.now().column`; micromark bumps the point column by 1 per `horizontalTab`
|
|
120449
|
+
// code (the trailing `virtualSpace` codes don't move it), so it measures a tab as
|
|
120450
|
+
// 1 column, reviving the tab-under-measurement bug this math exists to avoid.
|
|
120451
|
+
let plainClaimIndentColumns = 0;
|
|
120452
|
+
// True once a non-blank line follows the opener: a deep island below it is nested
|
|
120453
|
+
// (cosmetic indent), not top-of-body indented code.
|
|
120454
|
+
let sawPlainBlockBodyContent = false;
|
|
120339
120455
|
// Code span tracking
|
|
120340
120456
|
let codeSpanOpenSize = 0;
|
|
120341
120457
|
let codeSpanCloseSize = 0;
|
|
@@ -120569,16 +120685,11 @@ function createTokenize(mode) {
|
|
|
120569
120685
|
}
|
|
120570
120686
|
// End of opening tag
|
|
120571
120687
|
if (code === codes.greaterThan) {
|
|
120572
|
-
if (requiresBraceAttr && !sawBraceAttr)
|
|
120573
|
-
|
|
120574
|
-
// `plainClaimLineStart`; everything else falls through to CommonMark.
|
|
120575
|
-
if (!isFlow || !plainBlockClaimTagNames.has(tagName))
|
|
120576
|
-
return nok(code);
|
|
120577
|
-
isPlainBlockClaim = true;
|
|
120578
|
-
}
|
|
120688
|
+
if (requiresBraceAttr && !sawBraceAttr && !claimBraceLessTag())
|
|
120689
|
+
return nok(code);
|
|
120579
120690
|
effects.consume(code);
|
|
120580
120691
|
onOpenerLine = isFlow;
|
|
120581
|
-
return body;
|
|
120692
|
+
return pendingBlockWrapperClaim ? blockWrapperOpenerRest : body;
|
|
120582
120693
|
}
|
|
120583
120694
|
// Quoted attribute value
|
|
120584
120695
|
if (code === codes.quotationMark || code === codes.apostrophe) {
|
|
@@ -120633,9 +120744,38 @@ function createTokenize(mode) {
|
|
|
120633
120744
|
// `/ ` without `>` is just part of the attribute area
|
|
120634
120745
|
return afterOpenTagName(code);
|
|
120635
120746
|
}
|
|
120747
|
+
// Whether a brace-less lowercase flow tag is claimable: type-6 tags immediately,
|
|
120748
|
+
// type-7 tags pending the block-wrapper check; anything else is CommonMark's.
|
|
120749
|
+
function claimBraceLessTag() {
|
|
120750
|
+
if (!isFlow)
|
|
120751
|
+
return false;
|
|
120752
|
+
if (plainBlockClaimTagNames.has(tagName)) {
|
|
120753
|
+
isPlainBlockClaim = true;
|
|
120754
|
+
return true;
|
|
120755
|
+
}
|
|
120756
|
+
if (isBlockWrapperClaimTagName(tagName)) {
|
|
120757
|
+
pendingBlockWrapperClaim = true;
|
|
120758
|
+
return true;
|
|
120759
|
+
}
|
|
120760
|
+
return false;
|
|
120761
|
+
}
|
|
120762
|
+
// A type-7 tag is claimed only as a block wrapper: opener alone on its line
|
|
120763
|
+
// (trailing spaces ok). Inline content after the opener bails to CommonMark.
|
|
120764
|
+
function blockWrapperOpenerRest(code) {
|
|
120765
|
+
if (markdownSpace(code)) {
|
|
120766
|
+
effects.consume(code);
|
|
120767
|
+
return blockWrapperOpenerRest;
|
|
120768
|
+
}
|
|
120769
|
+
if (!markdownLineEnding(code))
|
|
120770
|
+
return nok(code);
|
|
120771
|
+
pendingBlockWrapperClaim = false;
|
|
120772
|
+
isPlainBlockClaim = true;
|
|
120773
|
+
isBlockWrapperClaim = true;
|
|
120774
|
+
return body(code);
|
|
120775
|
+
}
|
|
120636
120776
|
// Continuation for multi-line opening tags
|
|
120637
120777
|
function openTagContinuationStart(code) {
|
|
120638
|
-
return effects.check(
|
|
120778
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
|
|
120639
120779
|
}
|
|
120640
120780
|
function openTagContinuationNonLazy(code) {
|
|
120641
120781
|
sawLineEnding = true;
|
|
@@ -120680,6 +120820,9 @@ function createTokenize(mode) {
|
|
|
120680
120820
|
}
|
|
120681
120821
|
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
120682
120822
|
openerLineHasContent = true;
|
|
120823
|
+
// Continuation content marks a later deep island as nested, not indented code.
|
|
120824
|
+
if (!onOpenerLine)
|
|
120825
|
+
sawPlainBlockBodyContent = true;
|
|
120683
120826
|
}
|
|
120684
120827
|
if (code === codes.backslash) {
|
|
120685
120828
|
effects.consume(code);
|
|
@@ -120760,7 +120903,7 @@ function createTokenize(mode) {
|
|
|
120760
120903
|
return inFencedCode;
|
|
120761
120904
|
}
|
|
120762
120905
|
function fencedCodeContinuationStart(code) {
|
|
120763
|
-
return effects.check(
|
|
120906
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
|
|
120764
120907
|
}
|
|
120765
120908
|
function fencedCodeContinuationNonLazy(code) {
|
|
120766
120909
|
sawLineEnding = true;
|
|
@@ -120968,7 +121111,7 @@ function createTokenize(mode) {
|
|
|
120968
121111
|
}
|
|
120969
121112
|
// ── Body continuation (line endings) ───────────────────────────────────
|
|
120970
121113
|
function bodyContinuationStart(code) {
|
|
120971
|
-
return effects.check(
|
|
121114
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
|
|
120972
121115
|
}
|
|
120973
121116
|
function bodyContinuationNonLazy(code) {
|
|
120974
121117
|
sawLineEnding = true;
|
|
@@ -120994,8 +121137,10 @@ function createTokenize(mode) {
|
|
|
120994
121137
|
return inBodyBraceString(code);
|
|
120995
121138
|
return inBodyBraceExpr(code);
|
|
120996
121139
|
}
|
|
120997
|
-
if (isPlainBlockClaim)
|
|
121140
|
+
if (isPlainBlockClaim) {
|
|
121141
|
+
plainClaimIndentColumns = 0;
|
|
120998
121142
|
return plainClaimLineStart(code);
|
|
121143
|
+
}
|
|
120999
121144
|
return bodyLineStart(code);
|
|
121000
121145
|
}
|
|
121001
121146
|
// Dispatch a non-blank continuation line: fenced code at line start, else body.
|
|
@@ -121023,8 +121168,16 @@ function createTokenize(mode) {
|
|
|
121023
121168
|
// continue on a tag line (`<…`); any markdown island (`**bold**`, `[block:…]`, a
|
|
121024
121169
|
// fence) refuses so CommonMark html-flow reparses it exactly as it does today.
|
|
121025
121170
|
function plainClaimLineStart(code) {
|
|
121026
|
-
// Leading whitespace only → treat as a blank line, matching CommonMark.
|
|
121027
|
-
|
|
121171
|
+
// Leading whitespace only → treat as a blank line, matching CommonMark. A tab
|
|
121172
|
+
// advances to the next stop; its trailing `virtualSpace` fillers add nothing
|
|
121173
|
+
// but must still be consumed or they'd read as line content below.
|
|
121174
|
+
if (markdownSpace(code)) {
|
|
121175
|
+
if (code === codes.horizontalTab) {
|
|
121176
|
+
plainClaimIndentColumns += TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH);
|
|
121177
|
+
}
|
|
121178
|
+
else if (code === codes.space) {
|
|
121179
|
+
plainClaimIndentColumns += 1;
|
|
121180
|
+
}
|
|
121028
121181
|
effects.consume(code);
|
|
121029
121182
|
return plainClaimLineStart;
|
|
121030
121183
|
}
|
|
@@ -121033,10 +121186,19 @@ function createTokenize(mode) {
|
|
|
121033
121186
|
effects.exit('mdxComponentData');
|
|
121034
121187
|
return bodyContinuationStart(code);
|
|
121035
121188
|
}
|
|
121036
|
-
// Across a blank line the block only continues onto a markup-only line; a
|
|
121037
|
-
// paragraph that merely starts with a tag must fall back so its markdown
|
|
121038
|
-
// parses and rehype-raw re-nests it into the wrapper.
|
|
121039
121189
|
if (pendingBlankLine) {
|
|
121190
|
+
// A 4+ col island nested under other tags is cosmetic nesting indent, not code:
|
|
121191
|
+
// keep claiming so promotion dedents + re-parses it as markdown (RM-17560).
|
|
121192
|
+
// Block-wrapper claims extend this to top-of-body islands — their CommonMark
|
|
121193
|
+
// fallback is the fragmentation bug, not intentional indented code. Tags whose
|
|
121194
|
+
// bodies stay raw are excluded: a claimed island there would leak as literal text.
|
|
121195
|
+
if (plainClaimIndentColumns >= INDENTED_CODE_MIN_COLUMNS &&
|
|
121196
|
+
(sawPlainBlockBodyContent || isBlockWrapperClaim) &&
|
|
121197
|
+
!NON_REPARSED_BODY_TAGS.has(tagName)) {
|
|
121198
|
+
return plainClaimContinue(code);
|
|
121199
|
+
}
|
|
121200
|
+
// Otherwise only a markup-only tag line continues; markdown/prose falls back to
|
|
121201
|
+
// CommonMark so it parses and rehype-raw re-nests it into the wrapper.
|
|
121040
121202
|
if (code !== codes.lessThan)
|
|
121041
121203
|
return nok(code);
|
|
121042
121204
|
return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
|
|
@@ -121057,66 +121219,6 @@ function createTokenize(mode) {
|
|
|
121057
121219
|
}
|
|
121058
121220
|
};
|
|
121059
121221
|
}
|
|
121060
|
-
function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
121061
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
121062
|
-
const self = this;
|
|
121063
|
-
return start;
|
|
121064
|
-
function start(code) {
|
|
121065
|
-
if (markdownLineEnding(code)) {
|
|
121066
|
-
effects.enter(types_types.lineEnding);
|
|
121067
|
-
effects.consume(code);
|
|
121068
|
-
effects.exit(types_types.lineEnding);
|
|
121069
|
-
return after;
|
|
121070
|
-
}
|
|
121071
|
-
return nok(code);
|
|
121072
|
-
}
|
|
121073
|
-
function after(code) {
|
|
121074
|
-
if (self.parser.lazy[self.now().line]) {
|
|
121075
|
-
return nok(code);
|
|
121076
|
-
}
|
|
121077
|
-
return ok(code);
|
|
121078
|
-
}
|
|
121079
|
-
}
|
|
121080
|
-
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
121081
|
-
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
121082
|
-
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
121083
|
-
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
121084
|
-
let lastNonSpace = null;
|
|
121085
|
-
return start;
|
|
121086
|
-
function start(code) {
|
|
121087
|
-
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
121088
|
-
effects.enter(types_types.data);
|
|
121089
|
-
effects.consume(code);
|
|
121090
|
-
return afterLessThan;
|
|
121091
|
-
}
|
|
121092
|
-
function afterLessThan(code) {
|
|
121093
|
-
if (code === codes.slash) {
|
|
121094
|
-
effects.consume(code);
|
|
121095
|
-
return afterSlash;
|
|
121096
|
-
}
|
|
121097
|
-
return afterSlash(code);
|
|
121098
|
-
}
|
|
121099
|
-
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
121100
|
-
function afterSlash(code) {
|
|
121101
|
-
if (asciiAlpha(code)) {
|
|
121102
|
-
lastNonSpace = code;
|
|
121103
|
-
effects.consume(code);
|
|
121104
|
-
return scanToLineEnd;
|
|
121105
|
-
}
|
|
121106
|
-
effects.exit(types_types.data);
|
|
121107
|
-
return nok(code);
|
|
121108
|
-
}
|
|
121109
|
-
function scanToLineEnd(code) {
|
|
121110
|
-
if (code === null || markdownLineEnding(code)) {
|
|
121111
|
-
effects.exit(types_types.data);
|
|
121112
|
-
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
121113
|
-
}
|
|
121114
|
-
if (!markdownSpace(code))
|
|
121115
|
-
lastNonSpace = code;
|
|
121116
|
-
effects.consume(code);
|
|
121117
|
-
return scanToLineEnd;
|
|
121118
|
-
}
|
|
121119
|
-
}
|
|
121120
121222
|
/**
|
|
121121
121223
|
* Micromark extension that tokenizes MDX-like components.
|
|
121122
121224
|
*
|
|
@@ -121170,6 +121272,7 @@ function syntax_mdxComponent() {
|
|
|
121170
121272
|
|
|
121171
121273
|
|
|
121172
121274
|
|
|
121275
|
+
|
|
121173
121276
|
|
|
121174
121277
|
const buildInlineMdProcessor = (safeMode) => {
|
|
121175
121278
|
// `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
|
|
@@ -121241,7 +121344,7 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
|
|
|
121241
121344
|
// Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
|
|
121242
121345
|
// structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
|
|
121243
121346
|
// `mdxishJsxToMdast`, both of which run later on raw html nodes.
|
|
121244
|
-
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table',
|
|
121347
|
+
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table', ...NON_REPARSED_BODY_TAGS]);
|
|
121245
121348
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
121246
121349
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
121247
121350
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
@@ -121600,15 +121703,22 @@ function safeDeindent(text) {
|
|
|
121600
121703
|
*/
|
|
121601
121704
|
const parseMdChildren = (value, safeMode) => {
|
|
121602
121705
|
const parsed = getInlineMdProcessor({ safeMode }).parse(terminateHtmlFlowBlocks(safeDeindent(value).trim()));
|
|
121706
|
+
// Promote nested wrappers bottom-up so an outer wrapper sees markdown buried in a
|
|
121707
|
+
// child claimed whole (e.g. `<li>` in `<ol>`) before its containsMarkdownConstruct check (RM-17560).
|
|
121708
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define -- mutually recursive; hoisted decl, safe at runtime
|
|
121709
|
+
promoteComponentBlocks(parsed, safeMode, null);
|
|
121603
121710
|
return parsed.children || [];
|
|
121604
121711
|
};
|
|
121605
|
-
//
|
|
121606
|
-
// components among them
|
|
121607
|
-
|
|
121712
|
+
// Splices trailing content in as sibling nodes. parseMdChildren has already
|
|
121713
|
+
// promoted any components nested among them (bottom-up); the main loop's
|
|
121714
|
+
// index-based walk then reaches these spliced siblings and the original children
|
|
121715
|
+
// they shift down, so no parent re-queue is needed. Each spliced subtree is marked
|
|
121716
|
+
// `promoted` so the walk doesn't redundantly re-descend into it (its html is gone).
|
|
121717
|
+
const parseSibling = (parent, index, sibling, safeMode, promoted) => {
|
|
121608
121718
|
const siblingNodes = parseMdChildren(sibling, safeMode);
|
|
121609
121719
|
if (siblingNodes.length > 0) {
|
|
121610
121720
|
parent.children.splice(index + 1, 0, ...siblingNodes);
|
|
121611
|
-
|
|
121721
|
+
siblingNodes.forEach(siblingNode => promoted.add(siblingNode));
|
|
121612
121722
|
}
|
|
121613
121723
|
};
|
|
121614
121724
|
// Ends the position at `consumedLength` so the component doesn't claim trailing
|
|
@@ -121674,16 +121784,19 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
|
121674
121784
|
* The opening tag, content, and closing tag are all captured in one HTML node
|
|
121675
121785
|
* (guaranteed by the mdx-component tokenizer).
|
|
121676
121786
|
*/
|
|
121677
|
-
|
|
121787
|
+
function promoteComponentBlocks(tree, safeMode, source) {
|
|
121678
121788
|
const stack = [tree];
|
|
121679
|
-
const safeMode = !!opts.safeMode;
|
|
121680
|
-
const source = file?.value ? String(file.value) : null;
|
|
121681
121789
|
const parseOpts = { preserveExpressionsAsText: safeMode };
|
|
121790
|
+
// Subtrees a nested parseMdChildren already promoted wholesale (spliced siblings):
|
|
121791
|
+
// re-descending them finds no html to promote, so skip them.
|
|
121792
|
+
const promoted = new WeakSet();
|
|
121682
121793
|
const processChildNode = (parent, index) => {
|
|
121683
121794
|
const node = parent.children[index];
|
|
121684
121795
|
if (!node)
|
|
121685
121796
|
return;
|
|
121686
|
-
|
|
121797
|
+
// Descend into container nodes (lists, blockquotes, …) so their html children
|
|
121798
|
+
// are reached — unless the subtree was already promoted upstream.
|
|
121799
|
+
if ('children' in node && Array.isArray(node.children) && !promoted.has(node)) {
|
|
121687
121800
|
stack.push(node);
|
|
121688
121801
|
}
|
|
121689
121802
|
// Only html nodes can be an unparsed MDX component.
|
|
@@ -121738,7 +121851,7 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121738
121851
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
121739
121852
|
const remainingContent = contentAfterTag.trim();
|
|
121740
121853
|
if (remainingContent) {
|
|
121741
|
-
parseSibling(
|
|
121854
|
+
parseSibling(parent, index, remainingContent, safeMode, promoted);
|
|
121742
121855
|
}
|
|
121743
121856
|
return;
|
|
121744
121857
|
}
|
|
@@ -121765,43 +121878,57 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121765
121878
|
return;
|
|
121766
121879
|
// Lowercase tags are usually inline; unwrap a sole paragraph so their
|
|
121767
121880
|
// phrasing content isn't spuriously block-wrapped.
|
|
121881
|
+
let unwrappedSoleParagraph = false;
|
|
121768
121882
|
if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
|
|
121769
121883
|
parsedChildren = parsedChildren[0].children;
|
|
121884
|
+
unwrappedSoleParagraph = true;
|
|
121885
|
+
}
|
|
121886
|
+
// Without trailing content the whole node position is correct. With it, end
|
|
121887
|
+
// precisely at the closing tag — preferring source offsets when available (the
|
|
121888
|
+
// node's value strips blockquote/list prefixes), else the consumed span.
|
|
121889
|
+
let endPosition = node.position;
|
|
121890
|
+
if (contentAfterClose) {
|
|
121891
|
+
endPosition = source
|
|
121892
|
+
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
121893
|
+
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length);
|
|
121770
121894
|
}
|
|
121771
121895
|
const componentNode = createComponentNode({
|
|
121772
121896
|
tag,
|
|
121773
121897
|
attributes,
|
|
121774
121898
|
children: parsedChildren,
|
|
121775
121899
|
startPosition: node.position,
|
|
121776
|
-
|
|
121777
|
-
// offsets when available (the node's value strips blockquote/list
|
|
121778
|
-
// prefixes); otherwise fall back to the whole node position.
|
|
121779
|
-
endPosition: contentAfterClose
|
|
121780
|
-
? source
|
|
121781
|
-
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
121782
|
-
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length)
|
|
121783
|
-
: node.position,
|
|
121900
|
+
endPosition,
|
|
121784
121901
|
});
|
|
121785
121902
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
121786
|
-
//
|
|
121787
|
-
|
|
121788
|
-
|
|
121789
|
-
}
|
|
121790
|
-
else if (componentNode.children.length > 0) {
|
|
121903
|
+
// The unwrap reparented the children out of their paragraph, so re-walk them
|
|
121904
|
+
// since the children HTML may contain promotable syntax (e.g. `{…}`-attr tags)
|
|
121905
|
+
if (unwrappedSoleParagraph) {
|
|
121791
121906
|
stack.push(componentNode);
|
|
121792
121907
|
}
|
|
121908
|
+
// Trailing content after the close becomes siblings; parseMdChildren has
|
|
121909
|
+
// already promoted any components nested inside both sides, so the promoted
|
|
121910
|
+
// subtree itself needs no re-queue.
|
|
121911
|
+
if (contentAfterClose) {
|
|
121912
|
+
parseSibling(parent, index, contentAfterClose, safeMode, promoted);
|
|
121913
|
+
}
|
|
121793
121914
|
}
|
|
121794
121915
|
};
|
|
121795
|
-
// Depth-first so nodes keep their source order.
|
|
121916
|
+
// Depth-first so nodes keep their source order. Index-based (not forEach) and
|
|
121917
|
+
// re-reading length each step: parseSibling splices siblings in mid-iteration, and
|
|
121918
|
+
// those — plus the original children they shift down — must all stay eligible.
|
|
121796
121919
|
while (stack.length) {
|
|
121797
121920
|
const parent = stack.pop();
|
|
121798
121921
|
if (parent?.children) {
|
|
121799
|
-
parent.children.
|
|
121922
|
+
for (let index = 0; index < parent.children.length; index += 1) {
|
|
121800
121923
|
processChildNode(parent, index);
|
|
121801
|
-
}
|
|
121924
|
+
}
|
|
121802
121925
|
}
|
|
121803
121926
|
}
|
|
121804
121927
|
return tree;
|
|
121928
|
+
}
|
|
121929
|
+
const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
121930
|
+
const source = file?.value ? String(file.value) : null;
|
|
121931
|
+
return promoteComponentBlocks(tree, !!opts.safeMode, source);
|
|
121805
121932
|
};
|
|
121806
121933
|
/* harmony default export */ const mdx_blocks = (mdx_blocks_mdxishMdxComponentBlocks);
|
|
121807
121934
|
|
|
@@ -126973,7 +127100,7 @@ function mdxishMdastToMd(mdast) {
|
|
|
126973
127100
|
* Processes markdown content with MDX syntax support and returns a HAST.
|
|
126974
127101
|
* Detects and renders custom component tags from the components hash.
|
|
126975
127102
|
*
|
|
126976
|
-
* @see
|
|
127103
|
+
* @see .claude/context/MDXish/Processor Overview.md
|
|
126977
127104
|
*/
|
|
126978
127105
|
function mdxish_mdxish(mdContent, opts = {}) {
|
|
126979
127106
|
const { components: userComponents = {}, safeMode = false, variables } = opts;
|
|
@@ -127257,7 +127384,7 @@ function buildRMDXModule(content, headings, tocHast, opts) {
|
|
|
127257
127384
|
* @param opts - The options for the render
|
|
127258
127385
|
* @returns The React component
|
|
127259
127386
|
*
|
|
127260
|
-
* @see
|
|
127387
|
+
* @see .claude/context/MDXish/Processor Overview.md
|
|
127261
127388
|
*/
|
|
127262
127389
|
const renderMdxish = (tree, opts = {}) => {
|
|
127263
127390
|
const { components: userComponents = {}, variables, ...contextOpts } = opts;
|