@readme/markdown 14.13.0 → 14.13.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/components/Accordion/style.scss +4 -0
- package/dist/lib/micromark/mdx-component/continuation-checks.d.ts +3 -0
- package/dist/main.css +1 -1
- package/dist/main.css.map +1 -1
- package/dist/main.js +183 -103
- package/dist/main.node.js +183 -103
- package/dist/main.node.js.map +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 +183 -103
- 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/dist/main.js
CHANGED
|
@@ -76301,6 +76301,15 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
76301
76301
|
'caption',
|
|
76302
76302
|
'colgroup',
|
|
76303
76303
|
]);
|
|
76304
|
+
/**
|
|
76305
|
+
* Tags whose bodies a later mdxish transform keeps raw and never re-parses as
|
|
76306
|
+
* markdown. Both layers depend on this property, not on the tags being figures:
|
|
76307
|
+
* the transformer treats them as non-promotable, and the tokenizer must not claim
|
|
76308
|
+
* markdown islands inside them (a claimed island would never be re-parsed and would
|
|
76309
|
+
* leak as literal text). Currently just the figure tags, whose bodies are owned by
|
|
76310
|
+
* the figure reassembly transform (`mdxishJsxToMdast`).
|
|
76311
|
+
*/
|
|
76312
|
+
const NON_REPARSED_BODY_TAGS = new Set(['figure', 'figcaption']);
|
|
76304
76313
|
/**
|
|
76305
76314
|
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
76306
76315
|
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
@@ -101498,12 +101507,95 @@ function tokenizeMagicBlockText(effects, ok, nok) {
|
|
|
101498
101507
|
*/
|
|
101499
101508
|
|
|
101500
101509
|
|
|
101510
|
+
;// ./lib/micromark/mdx-component/continuation-checks.ts
|
|
101511
|
+
|
|
101512
|
+
|
|
101513
|
+
/**
|
|
101514
|
+
* Partial constructs the `mdxComponent` tokenizer runs via `effects.check` to
|
|
101515
|
+
* decide whether the next line continues the block. They live here (not in
|
|
101516
|
+
* `syntax.ts`) because they hold none of `createTokenize`'s closure state — each
|
|
101517
|
+
* is a self-contained, single-line lookahead.
|
|
101518
|
+
*/
|
|
101519
|
+
function continuation_checks_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
101520
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
101521
|
+
const self = this;
|
|
101522
|
+
return start;
|
|
101523
|
+
function start(code) {
|
|
101524
|
+
if (markdownLineEnding(code)) {
|
|
101525
|
+
effects.enter(types_types.lineEnding);
|
|
101526
|
+
effects.consume(code);
|
|
101527
|
+
effects.exit(types_types.lineEnding);
|
|
101528
|
+
return after;
|
|
101529
|
+
}
|
|
101530
|
+
return nok(code);
|
|
101531
|
+
}
|
|
101532
|
+
function after(code) {
|
|
101533
|
+
if (self.parser.lazy[self.now().line]) {
|
|
101534
|
+
return nok(code);
|
|
101535
|
+
}
|
|
101536
|
+
return ok(code);
|
|
101537
|
+
}
|
|
101538
|
+
}
|
|
101539
|
+
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
101540
|
+
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
101541
|
+
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
101542
|
+
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
101543
|
+
let lastNonSpace = null;
|
|
101544
|
+
return start;
|
|
101545
|
+
function start(code) {
|
|
101546
|
+
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
101547
|
+
effects.enter(types_types.data);
|
|
101548
|
+
effects.consume(code);
|
|
101549
|
+
return afterLessThan;
|
|
101550
|
+
}
|
|
101551
|
+
function afterLessThan(code) {
|
|
101552
|
+
if (code === codes.slash) {
|
|
101553
|
+
effects.consume(code);
|
|
101554
|
+
return afterSlash;
|
|
101555
|
+
}
|
|
101556
|
+
return afterSlash(code);
|
|
101557
|
+
}
|
|
101558
|
+
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
101559
|
+
function afterSlash(code) {
|
|
101560
|
+
if (asciiAlpha(code)) {
|
|
101561
|
+
lastNonSpace = code;
|
|
101562
|
+
effects.consume(code);
|
|
101563
|
+
return scanToLineEnd;
|
|
101564
|
+
}
|
|
101565
|
+
effects.exit(types_types.data);
|
|
101566
|
+
return nok(code);
|
|
101567
|
+
}
|
|
101568
|
+
function scanToLineEnd(code) {
|
|
101569
|
+
if (code === null || markdownLineEnding(code)) {
|
|
101570
|
+
effects.exit(types_types.data);
|
|
101571
|
+
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
101572
|
+
}
|
|
101573
|
+
if (!markdownSpace(code))
|
|
101574
|
+
lastNonSpace = code;
|
|
101575
|
+
effects.consume(code);
|
|
101576
|
+
return scanToLineEnd;
|
|
101577
|
+
}
|
|
101578
|
+
}
|
|
101579
|
+
// A line ending whose next line isn't a lazy paragraph continuation. Checked so a
|
|
101580
|
+
// component body's blank/continuation lines aren't stolen by an interrupted paragraph.
|
|
101581
|
+
const continuation_checks_nonLazyContinuationStart = {
|
|
101582
|
+
tokenize: continuation_checks_tokenizeNonLazyContinuationStart,
|
|
101583
|
+
partial: true,
|
|
101584
|
+
};
|
|
101585
|
+
// Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
|
|
101586
|
+
// that merely starts with a tag? Run via `effects.check` so it never consumes.
|
|
101587
|
+
const markupOnlyContinuation = {
|
|
101588
|
+
tokenize: tokenizeMarkupOnlyContinuation,
|
|
101589
|
+
partial: true,
|
|
101590
|
+
};
|
|
101591
|
+
|
|
101501
101592
|
;// ./lib/micromark/mdx-component/syntax.ts
|
|
101502
101593
|
|
|
101503
101594
|
|
|
101504
101595
|
|
|
101505
101596
|
|
|
101506
101597
|
|
|
101598
|
+
|
|
101507
101599
|
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
101508
101600
|
// section, …) always start a block, so they stay flow even with trailing
|
|
101509
101601
|
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
@@ -101513,16 +101605,12 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
|
101513
101605
|
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
101514
101606
|
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
101515
101607
|
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
101516
|
-
|
|
101517
|
-
|
|
101518
|
-
|
|
101519
|
-
|
|
101520
|
-
|
|
101521
|
-
|
|
101522
|
-
const markupOnlyContinuation = {
|
|
101523
|
-
tokenize: tokenizeMarkupOnlyContinuation,
|
|
101524
|
-
partial: true,
|
|
101525
|
-
};
|
|
101608
|
+
// Both are 4 columns per CommonMark, but they mean different things: a tab advances
|
|
101609
|
+
// to the next multiple of TAB_STOP_WIDTH, and INDENTED_CODE_MIN_COLUMNS is the depth
|
|
101610
|
+
// at which a line would fragment into indented code. Named separately so the two
|
|
101611
|
+
// concepts don't read as one incidental literal.
|
|
101612
|
+
const TAB_STOP_WIDTH = 4;
|
|
101613
|
+
const INDENTED_CODE_MIN_COLUMNS = 4;
|
|
101526
101614
|
function resolveToMdxComponent(events) {
|
|
101527
101615
|
let index = events.length;
|
|
101528
101616
|
while (index > 0) {
|
|
@@ -101581,6 +101669,18 @@ function createTokenize(mode) {
|
|
|
101581
101669
|
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
101582
101670
|
let isPlainBlockClaim = false;
|
|
101583
101671
|
let pendingBlankLine = false;
|
|
101672
|
+
// Leading indent columns of the current plain-claim line, reset per line; ≥4 is
|
|
101673
|
+
// where CommonMark would fragment the island as indented code. Tabs advance to the
|
|
101674
|
+
// next 4-column stop — the same rule `expandIndentToColumns`
|
|
101675
|
+
// (processor/transform/mdxish/indentation.ts) applies, kept in sync by hand since
|
|
101676
|
+
// this side works on a `Code` stream, not a string. NB: do NOT swap this for
|
|
101677
|
+
// `self.now().column`; micromark bumps the point column by 1 per `horizontalTab`
|
|
101678
|
+
// code (the trailing `virtualSpace` codes don't move it), so it measures a tab as
|
|
101679
|
+
// 1 column, reviving the tab-under-measurement bug this math exists to avoid.
|
|
101680
|
+
let plainClaimIndentColumns = 0;
|
|
101681
|
+
// True once a non-blank line follows the opener: a deep island below it is nested
|
|
101682
|
+
// (cosmetic indent), not top-of-body indented code.
|
|
101683
|
+
let sawPlainBlockBodyContent = false;
|
|
101584
101684
|
// Code span tracking
|
|
101585
101685
|
let codeSpanOpenSize = 0;
|
|
101586
101686
|
let codeSpanCloseSize = 0;
|
|
@@ -101880,7 +101980,7 @@ function createTokenize(mode) {
|
|
|
101880
101980
|
}
|
|
101881
101981
|
// Continuation for multi-line opening tags
|
|
101882
101982
|
function openTagContinuationStart(code) {
|
|
101883
|
-
return effects.check(
|
|
101983
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
|
|
101884
101984
|
}
|
|
101885
101985
|
function openTagContinuationNonLazy(code) {
|
|
101886
101986
|
sawLineEnding = true;
|
|
@@ -101925,6 +102025,9 @@ function createTokenize(mode) {
|
|
|
101925
102025
|
}
|
|
101926
102026
|
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
101927
102027
|
openerLineHasContent = true;
|
|
102028
|
+
// Continuation content marks a later deep island as nested, not indented code.
|
|
102029
|
+
if (!onOpenerLine)
|
|
102030
|
+
sawPlainBlockBodyContent = true;
|
|
101928
102031
|
}
|
|
101929
102032
|
if (code === codes.backslash) {
|
|
101930
102033
|
effects.consume(code);
|
|
@@ -102005,7 +102108,7 @@ function createTokenize(mode) {
|
|
|
102005
102108
|
return inFencedCode;
|
|
102006
102109
|
}
|
|
102007
102110
|
function fencedCodeContinuationStart(code) {
|
|
102008
|
-
return effects.check(
|
|
102111
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
|
|
102009
102112
|
}
|
|
102010
102113
|
function fencedCodeContinuationNonLazy(code) {
|
|
102011
102114
|
sawLineEnding = true;
|
|
@@ -102213,7 +102316,7 @@ function createTokenize(mode) {
|
|
|
102213
102316
|
}
|
|
102214
102317
|
// ── Body continuation (line endings) ───────────────────────────────────
|
|
102215
102318
|
function bodyContinuationStart(code) {
|
|
102216
|
-
return effects.check(
|
|
102319
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
|
|
102217
102320
|
}
|
|
102218
102321
|
function bodyContinuationNonLazy(code) {
|
|
102219
102322
|
sawLineEnding = true;
|
|
@@ -102239,8 +102342,10 @@ function createTokenize(mode) {
|
|
|
102239
102342
|
return inBodyBraceString(code);
|
|
102240
102343
|
return inBodyBraceExpr(code);
|
|
102241
102344
|
}
|
|
102242
|
-
if (isPlainBlockClaim)
|
|
102345
|
+
if (isPlainBlockClaim) {
|
|
102346
|
+
plainClaimIndentColumns = 0;
|
|
102243
102347
|
return plainClaimLineStart(code);
|
|
102348
|
+
}
|
|
102244
102349
|
return bodyLineStart(code);
|
|
102245
102350
|
}
|
|
102246
102351
|
// Dispatch a non-blank continuation line: fenced code at line start, else body.
|
|
@@ -102270,6 +102375,8 @@ function createTokenize(mode) {
|
|
|
102270
102375
|
function plainClaimLineStart(code) {
|
|
102271
102376
|
// Leading whitespace only → treat as a blank line, matching CommonMark.
|
|
102272
102377
|
if (code === codes.space || code === codes.horizontalTab) {
|
|
102378
|
+
plainClaimIndentColumns +=
|
|
102379
|
+
code === codes.horizontalTab ? TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH) : 1;
|
|
102273
102380
|
effects.consume(code);
|
|
102274
102381
|
return plainClaimLineStart;
|
|
102275
102382
|
}
|
|
@@ -102278,10 +102385,18 @@ function createTokenize(mode) {
|
|
|
102278
102385
|
effects.exit('mdxComponentData');
|
|
102279
102386
|
return bodyContinuationStart(code);
|
|
102280
102387
|
}
|
|
102281
|
-
// Across a blank line the block only continues onto a markup-only line; a
|
|
102282
|
-
// paragraph that merely starts with a tag must fall back so its markdown
|
|
102283
|
-
// parses and rehype-raw re-nests it into the wrapper.
|
|
102284
102388
|
if (pendingBlankLine) {
|
|
102389
|
+
// A 4+ col island nested under other tags is cosmetic nesting indent, not code:
|
|
102390
|
+
// keep claiming so promotion dedents + re-parses it as markdown (RM-17560).
|
|
102391
|
+
// Tags whose bodies stay raw are excluded — a claimed island there would never
|
|
102392
|
+
// be re-parsed and would leak as literal text.
|
|
102393
|
+
if (plainClaimIndentColumns >= INDENTED_CODE_MIN_COLUMNS &&
|
|
102394
|
+
sawPlainBlockBodyContent &&
|
|
102395
|
+
!NON_REPARSED_BODY_TAGS.has(tagName)) {
|
|
102396
|
+
return plainClaimContinue(code);
|
|
102397
|
+
}
|
|
102398
|
+
// Otherwise only a markup-only tag line continues; markdown/prose falls back to
|
|
102399
|
+
// CommonMark so it parses and rehype-raw re-nests it into the wrapper.
|
|
102285
102400
|
if (code !== codes.lessThan)
|
|
102286
102401
|
return nok(code);
|
|
102287
102402
|
return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
|
|
@@ -102302,66 +102417,6 @@ function createTokenize(mode) {
|
|
|
102302
102417
|
}
|
|
102303
102418
|
};
|
|
102304
102419
|
}
|
|
102305
|
-
function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
102306
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
102307
|
-
const self = this;
|
|
102308
|
-
return start;
|
|
102309
|
-
function start(code) {
|
|
102310
|
-
if (markdownLineEnding(code)) {
|
|
102311
|
-
effects.enter(types_types.lineEnding);
|
|
102312
|
-
effects.consume(code);
|
|
102313
|
-
effects.exit(types_types.lineEnding);
|
|
102314
|
-
return after;
|
|
102315
|
-
}
|
|
102316
|
-
return nok(code);
|
|
102317
|
-
}
|
|
102318
|
-
function after(code) {
|
|
102319
|
-
if (self.parser.lazy[self.now().line]) {
|
|
102320
|
-
return nok(code);
|
|
102321
|
-
}
|
|
102322
|
-
return ok(code);
|
|
102323
|
-
}
|
|
102324
|
-
}
|
|
102325
|
-
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
102326
|
-
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
102327
|
-
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
102328
|
-
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
102329
|
-
let lastNonSpace = null;
|
|
102330
|
-
return start;
|
|
102331
|
-
function start(code) {
|
|
102332
|
-
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
102333
|
-
effects.enter(types_types.data);
|
|
102334
|
-
effects.consume(code);
|
|
102335
|
-
return afterLessThan;
|
|
102336
|
-
}
|
|
102337
|
-
function afterLessThan(code) {
|
|
102338
|
-
if (code === codes.slash) {
|
|
102339
|
-
effects.consume(code);
|
|
102340
|
-
return afterSlash;
|
|
102341
|
-
}
|
|
102342
|
-
return afterSlash(code);
|
|
102343
|
-
}
|
|
102344
|
-
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
102345
|
-
function afterSlash(code) {
|
|
102346
|
-
if (asciiAlpha(code)) {
|
|
102347
|
-
lastNonSpace = code;
|
|
102348
|
-
effects.consume(code);
|
|
102349
|
-
return scanToLineEnd;
|
|
102350
|
-
}
|
|
102351
|
-
effects.exit(types_types.data);
|
|
102352
|
-
return nok(code);
|
|
102353
|
-
}
|
|
102354
|
-
function scanToLineEnd(code) {
|
|
102355
|
-
if (code === null || markdownLineEnding(code)) {
|
|
102356
|
-
effects.exit(types_types.data);
|
|
102357
|
-
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
102358
|
-
}
|
|
102359
|
-
if (!markdownSpace(code))
|
|
102360
|
-
lastNonSpace = code;
|
|
102361
|
-
effects.consume(code);
|
|
102362
|
-
return scanToLineEnd;
|
|
102363
|
-
}
|
|
102364
|
-
}
|
|
102365
102420
|
/**
|
|
102366
102421
|
* Micromark extension that tokenizes MDX-like components.
|
|
102367
102422
|
*
|
|
@@ -102415,6 +102470,7 @@ function mdxComponent() {
|
|
|
102415
102470
|
|
|
102416
102471
|
|
|
102417
102472
|
|
|
102473
|
+
|
|
102418
102474
|
|
|
102419
102475
|
const buildInlineMdProcessor = (safeMode) => {
|
|
102420
102476
|
// `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
|
|
@@ -102486,7 +102542,7 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
|
|
|
102486
102542
|
// Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
|
|
102487
102543
|
// structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
|
|
102488
102544
|
// `mdxishJsxToMdast`, both of which run later on raw html nodes.
|
|
102489
|
-
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table',
|
|
102545
|
+
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table', ...NON_REPARSED_BODY_TAGS]);
|
|
102490
102546
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
102491
102547
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
102492
102548
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
@@ -102845,15 +102901,22 @@ function safeDeindent(text) {
|
|
|
102845
102901
|
*/
|
|
102846
102902
|
const parseMdChildren = (value, safeMode) => {
|
|
102847
102903
|
const parsed = getInlineMdProcessor({ safeMode }).parse(terminateHtmlFlowBlocks(safeDeindent(value).trim()));
|
|
102904
|
+
// Promote nested wrappers bottom-up so an outer wrapper sees markdown buried in a
|
|
102905
|
+
// child claimed whole (e.g. `<li>` in `<ol>`) before its containsMarkdownConstruct check (RM-17560).
|
|
102906
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define -- mutually recursive; hoisted decl, safe at runtime
|
|
102907
|
+
promoteComponentBlocks(parsed, safeMode, null);
|
|
102848
102908
|
return parsed.children || [];
|
|
102849
102909
|
};
|
|
102850
|
-
//
|
|
102851
|
-
// components among them
|
|
102852
|
-
|
|
102910
|
+
// Splices trailing content in as sibling nodes. parseMdChildren has already
|
|
102911
|
+
// promoted any components nested among them (bottom-up); the main loop's
|
|
102912
|
+
// index-based walk then reaches these spliced siblings and the original children
|
|
102913
|
+
// they shift down, so no parent re-queue is needed. Each spliced subtree is marked
|
|
102914
|
+
// `promoted` so the walk doesn't redundantly re-descend into it (its html is gone).
|
|
102915
|
+
const parseSibling = (parent, index, sibling, safeMode, promoted) => {
|
|
102853
102916
|
const siblingNodes = parseMdChildren(sibling, safeMode);
|
|
102854
102917
|
if (siblingNodes.length > 0) {
|
|
102855
102918
|
parent.children.splice(index + 1, 0, ...siblingNodes);
|
|
102856
|
-
|
|
102919
|
+
siblingNodes.forEach(siblingNode => promoted.add(siblingNode));
|
|
102857
102920
|
}
|
|
102858
102921
|
};
|
|
102859
102922
|
// Ends the position at `consumedLength` so the component doesn't claim trailing
|
|
@@ -102919,16 +102982,19 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
|
102919
102982
|
* The opening tag, content, and closing tag are all captured in one HTML node
|
|
102920
102983
|
* (guaranteed by the mdx-component tokenizer).
|
|
102921
102984
|
*/
|
|
102922
|
-
|
|
102985
|
+
function promoteComponentBlocks(tree, safeMode, source) {
|
|
102923
102986
|
const stack = [tree];
|
|
102924
|
-
const safeMode = !!opts.safeMode;
|
|
102925
|
-
const source = file?.value ? String(file.value) : null;
|
|
102926
102987
|
const parseOpts = { preserveExpressionsAsText: safeMode };
|
|
102988
|
+
// Subtrees a nested parseMdChildren already promoted wholesale (spliced siblings):
|
|
102989
|
+
// re-descending them finds no html to promote, so skip them.
|
|
102990
|
+
const promoted = new WeakSet();
|
|
102927
102991
|
const processChildNode = (parent, index) => {
|
|
102928
102992
|
const node = parent.children[index];
|
|
102929
102993
|
if (!node)
|
|
102930
102994
|
return;
|
|
102931
|
-
|
|
102995
|
+
// Descend into container nodes (lists, blockquotes, …) so their html children
|
|
102996
|
+
// are reached — unless the subtree was already promoted upstream.
|
|
102997
|
+
if ('children' in node && Array.isArray(node.children) && !promoted.has(node)) {
|
|
102932
102998
|
stack.push(node);
|
|
102933
102999
|
}
|
|
102934
103000
|
// Only html nodes can be an unparsed MDX component.
|
|
@@ -102983,7 +103049,7 @@ const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
102983
103049
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
102984
103050
|
const remainingContent = contentAfterTag.trim();
|
|
102985
103051
|
if (remainingContent) {
|
|
102986
|
-
parseSibling(
|
|
103052
|
+
parseSibling(parent, index, remainingContent, safeMode, promoted);
|
|
102987
103053
|
}
|
|
102988
103054
|
return;
|
|
102989
103055
|
}
|
|
@@ -103010,43 +103076,57 @@ const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
103010
103076
|
return;
|
|
103011
103077
|
// Lowercase tags are usually inline; unwrap a sole paragraph so their
|
|
103012
103078
|
// phrasing content isn't spuriously block-wrapped.
|
|
103079
|
+
let unwrappedSoleParagraph = false;
|
|
103013
103080
|
if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
|
|
103014
103081
|
parsedChildren = parsedChildren[0].children;
|
|
103082
|
+
unwrappedSoleParagraph = true;
|
|
103083
|
+
}
|
|
103084
|
+
// Without trailing content the whole node position is correct. With it, end
|
|
103085
|
+
// precisely at the closing tag — preferring source offsets when available (the
|
|
103086
|
+
// node's value strips blockquote/list prefixes), else the consumed span.
|
|
103087
|
+
let endPosition = node.position;
|
|
103088
|
+
if (contentAfterClose) {
|
|
103089
|
+
endPosition = source
|
|
103090
|
+
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
103091
|
+
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length);
|
|
103015
103092
|
}
|
|
103016
103093
|
const componentNode = createComponentNode({
|
|
103017
103094
|
tag,
|
|
103018
103095
|
attributes,
|
|
103019
103096
|
children: parsedChildren,
|
|
103020
103097
|
startPosition: node.position,
|
|
103021
|
-
|
|
103022
|
-
// offsets when available (the node's value strips blockquote/list
|
|
103023
|
-
// prefixes); otherwise fall back to the whole node position.
|
|
103024
|
-
endPosition: contentAfterClose
|
|
103025
|
-
? source
|
|
103026
|
-
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
103027
|
-
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length)
|
|
103028
|
-
: node.position,
|
|
103098
|
+
endPosition,
|
|
103029
103099
|
});
|
|
103030
103100
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
103031
|
-
//
|
|
103032
|
-
|
|
103033
|
-
|
|
103034
|
-
}
|
|
103035
|
-
else if (componentNode.children.length > 0) {
|
|
103101
|
+
// The unwrap reparented the children out of their paragraph, so re-walk them
|
|
103102
|
+
// since the children HTML may contain promotable syntax (e.g. `{…}`-attr tags)
|
|
103103
|
+
if (unwrappedSoleParagraph) {
|
|
103036
103104
|
stack.push(componentNode);
|
|
103037
103105
|
}
|
|
103106
|
+
// Trailing content after the close becomes siblings; parseMdChildren has
|
|
103107
|
+
// already promoted any components nested inside both sides, so the promoted
|
|
103108
|
+
// subtree itself needs no re-queue.
|
|
103109
|
+
if (contentAfterClose) {
|
|
103110
|
+
parseSibling(parent, index, contentAfterClose, safeMode, promoted);
|
|
103111
|
+
}
|
|
103038
103112
|
}
|
|
103039
103113
|
};
|
|
103040
|
-
// Depth-first so nodes keep their source order.
|
|
103114
|
+
// Depth-first so nodes keep their source order. Index-based (not forEach) and
|
|
103115
|
+
// re-reading length each step: parseSibling splices siblings in mid-iteration, and
|
|
103116
|
+
// those — plus the original children they shift down — must all stay eligible.
|
|
103041
103117
|
while (stack.length) {
|
|
103042
103118
|
const parent = stack.pop();
|
|
103043
103119
|
if (parent?.children) {
|
|
103044
|
-
parent.children.
|
|
103120
|
+
for (let index = 0; index < parent.children.length; index += 1) {
|
|
103045
103121
|
processChildNode(parent, index);
|
|
103046
|
-
}
|
|
103122
|
+
}
|
|
103047
103123
|
}
|
|
103048
103124
|
}
|
|
103049
103125
|
return tree;
|
|
103126
|
+
}
|
|
103127
|
+
const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
103128
|
+
const source = file?.value ? String(file.value) : null;
|
|
103129
|
+
return promoteComponentBlocks(tree, !!opts.safeMode, source);
|
|
103050
103130
|
};
|
|
103051
103131
|
/* harmony default export */ const mdx_blocks = (mdxishMdxComponentBlocks);
|
|
103052
103132
|
|