@readme/markdown 14.12.1 → 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/components/Cards/index.tsx +14 -2
- package/dist/components/Cards/index.d.ts +2 -1
- 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 +297 -113
- package/dist/main.node.js +295 -111
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/collapse-foreign-content-blank-lines.d.ts +6 -0
- 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 +295 -111
- package/dist/render-fixture.node.js.map +1 -1
- package/dist/utils/common-html-words.d.ts +15 -0
- package/package.json +1 -1
|
@@ -86449,8 +86449,8 @@ function Anchor(props) {
|
|
|
86449
86449
|
|
|
86450
86450
|
|
|
86451
86451
|
|
|
86452
|
-
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, target, title }) => {
|
|
86453
|
-
const Tag = href ?
|
|
86452
|
+
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, LinkComponent = 'a', target, title, }) => {
|
|
86453
|
+
const Tag = href ? LinkComponent : 'div';
|
|
86454
86454
|
return (external_react_default().createElement(Tag, { className: `Card Card_${kind}`, href: href, target: target },
|
|
86455
86455
|
icon && external_react_default().createElement(components_Icon, { className: "Card-icon", icon: icon, iconColor: iconColor }),
|
|
86456
86456
|
external_react_default().createElement("div", { className: "Card-content" },
|
|
@@ -96476,6 +96476,21 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
96476
96476
|
'caption',
|
|
96477
96477
|
'colgroup',
|
|
96478
96478
|
]);
|
|
96479
|
+
/**
|
|
96480
|
+
* Tags whose bodies a later mdxish transform keeps raw and never re-parses as
|
|
96481
|
+
* markdown. Both layers depend on this property, not on the tags being figures:
|
|
96482
|
+
* the transformer treats them as non-promotable, and the tokenizer must not claim
|
|
96483
|
+
* markdown islands inside them (a claimed island would never be re-parsed and would
|
|
96484
|
+
* leak as literal text). Currently just the figure tags, whose bodies are owned by
|
|
96485
|
+
* the figure reassembly transform (`mdxishJsxToMdast`).
|
|
96486
|
+
*/
|
|
96487
|
+
const NON_REPARSED_BODY_TAGS = new Set(['figure', 'figcaption']);
|
|
96488
|
+
/**
|
|
96489
|
+
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
96490
|
+
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
96491
|
+
* set per the HTML spec, so transforms can treat these roots as opaque islands.
|
|
96492
|
+
*/
|
|
96493
|
+
const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
|
|
96479
96494
|
/**
|
|
96480
96495
|
* HTML void elements — elements that have no closing tag and no children.
|
|
96481
96496
|
*
|
|
@@ -117685,6 +117700,9 @@ function getComponentName(componentName, components) {
|
|
|
117685
117700
|
|
|
117686
117701
|
|
|
117687
117702
|
|
|
117703
|
+
// Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
|
|
117704
|
+
// untouched (their children are namespaced XML, not HTML tags/components).
|
|
117705
|
+
const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
|
|
117688
117706
|
function isElementContentNode(node) {
|
|
117689
117707
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
117690
117708
|
}
|
|
@@ -117860,6 +117878,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
117860
117878
|
lib_visit(tree, 'element', (node, index, parent) => {
|
|
117861
117879
|
if (index === undefined || !parent)
|
|
117862
117880
|
return;
|
|
117881
|
+
// Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
|
|
117882
|
+
// aren't HTML tags or components, so the "unknown component" removal below would
|
|
117883
|
+
// otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
|
|
117884
|
+
// eslint-disable-next-line consistent-return
|
|
117885
|
+
if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
|
|
117886
|
+
return lib_SKIP;
|
|
117863
117887
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
117864
117888
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
117865
117889
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -118171,6 +118195,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
118171
118195
|
return restoreCodeBlocks(result, protectedCode);
|
|
118172
118196
|
}
|
|
118173
118197
|
|
|
118198
|
+
;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
|
|
118199
|
+
|
|
118200
|
+
|
|
118201
|
+
// `svg|math`, from the canonical list so this stays in sync with the component transform.
|
|
118202
|
+
const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
|
|
118203
|
+
// A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
|
|
118204
|
+
// root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
|
|
118205
|
+
const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
|
|
118206
|
+
// Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
|
|
118207
|
+
// `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
|
|
118208
|
+
// chars (including newlines) are consumed one at a time.
|
|
118209
|
+
const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
|
|
118210
|
+
// One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
|
|
118211
|
+
// and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
|
|
118212
|
+
// `<svg-icon>` out. Group 1 is `/` only for a self-closer.
|
|
118213
|
+
const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
|
|
118214
|
+
// An HTML comment. Foreign markup inside one is inert and must not open an island.
|
|
118215
|
+
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
118216
|
+
const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
|
|
118217
|
+
/**
|
|
118218
|
+
* `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
|
|
118219
|
+
* lines are known-insignificant XML. Matching whole tags (not per-line open/close
|
|
118220
|
+
* counts) keeps multi-line openers and self-closers balanced, so a wrapped
|
|
118221
|
+
* `<svg … />` can't latch and swallow the doc (#1545).
|
|
118222
|
+
*
|
|
118223
|
+
* Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
|
|
118224
|
+
* closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
|
|
118225
|
+
* swallowing every blank line after it, without hiding the real islands that follow.
|
|
118226
|
+
*/
|
|
118227
|
+
function findForeignContentSpans(text) {
|
|
118228
|
+
const spans = [];
|
|
118229
|
+
// Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
|
|
118230
|
+
// must not open an island and latch onto the rest of the doc.
|
|
118231
|
+
const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
|
|
118232
|
+
// Offsets of openers still waiting for their closer, innermost last.
|
|
118233
|
+
const openOffsets = [];
|
|
118234
|
+
[...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
|
|
118235
|
+
const offset = match.index ?? 0;
|
|
118236
|
+
if (withinAny(comments, offset))
|
|
118237
|
+
return; // markup inside an HTML comment is inert
|
|
118238
|
+
if (match[1] === '/')
|
|
118239
|
+
return; // self-closing tag opens no island
|
|
118240
|
+
if (match[0].startsWith('</')) {
|
|
118241
|
+
const start = openOffsets.pop();
|
|
118242
|
+
if (start !== undefined)
|
|
118243
|
+
spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
|
|
118244
|
+
}
|
|
118245
|
+
else {
|
|
118246
|
+
openOffsets.push(offset);
|
|
118247
|
+
}
|
|
118248
|
+
});
|
|
118249
|
+
return spans;
|
|
118250
|
+
}
|
|
118251
|
+
/**
|
|
118252
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
118253
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
118254
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
118255
|
+
*/
|
|
118256
|
+
function collapseForeignContentBlankLines(content) {
|
|
118257
|
+
// Fast path: nothing to do when the doc has no foreign-content island.
|
|
118258
|
+
if (!ANY_ROOT_RE.test(content))
|
|
118259
|
+
return content;
|
|
118260
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
118261
|
+
const islands = findForeignContentSpans(protectedContent);
|
|
118262
|
+
// Drop blank lines inside an island; keep everything else verbatim.
|
|
118263
|
+
const lines = [];
|
|
118264
|
+
let lineStart = 0;
|
|
118265
|
+
protectedContent.split('\n').forEach(line => {
|
|
118266
|
+
if (line.trim().length > 0 || !withinAny(islands, lineStart))
|
|
118267
|
+
lines.push(line);
|
|
118268
|
+
lineStart += line.length + 1; // +1 for the '\n' that split() removed
|
|
118269
|
+
});
|
|
118270
|
+
return restoreCodeBlocks(lines.join('\n'), protectedCode);
|
|
118271
|
+
}
|
|
118272
|
+
|
|
118174
118273
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
118175
118274
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
118176
118275
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -120163,12 +120262,95 @@ function tokenizeMagicBlockText(effects, ok, nok) {
|
|
|
120163
120262
|
*/
|
|
120164
120263
|
|
|
120165
120264
|
|
|
120265
|
+
;// ./lib/micromark/mdx-component/continuation-checks.ts
|
|
120266
|
+
|
|
120267
|
+
|
|
120268
|
+
/**
|
|
120269
|
+
* Partial constructs the `mdxComponent` tokenizer runs via `effects.check` to
|
|
120270
|
+
* decide whether the next line continues the block. They live here (not in
|
|
120271
|
+
* `syntax.ts`) because they hold none of `createTokenize`'s closure state — each
|
|
120272
|
+
* is a self-contained, single-line lookahead.
|
|
120273
|
+
*/
|
|
120274
|
+
function continuation_checks_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
120275
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
120276
|
+
const self = this;
|
|
120277
|
+
return start;
|
|
120278
|
+
function start(code) {
|
|
120279
|
+
if (markdownLineEnding(code)) {
|
|
120280
|
+
effects.enter(types_types.lineEnding);
|
|
120281
|
+
effects.consume(code);
|
|
120282
|
+
effects.exit(types_types.lineEnding);
|
|
120283
|
+
return after;
|
|
120284
|
+
}
|
|
120285
|
+
return nok(code);
|
|
120286
|
+
}
|
|
120287
|
+
function after(code) {
|
|
120288
|
+
if (self.parser.lazy[self.now().line]) {
|
|
120289
|
+
return nok(code);
|
|
120290
|
+
}
|
|
120291
|
+
return ok(code);
|
|
120292
|
+
}
|
|
120293
|
+
}
|
|
120294
|
+
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
120295
|
+
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
120296
|
+
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
120297
|
+
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
120298
|
+
let lastNonSpace = null;
|
|
120299
|
+
return start;
|
|
120300
|
+
function start(code) {
|
|
120301
|
+
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
120302
|
+
effects.enter(types_types.data);
|
|
120303
|
+
effects.consume(code);
|
|
120304
|
+
return afterLessThan;
|
|
120305
|
+
}
|
|
120306
|
+
function afterLessThan(code) {
|
|
120307
|
+
if (code === codes.slash) {
|
|
120308
|
+
effects.consume(code);
|
|
120309
|
+
return afterSlash;
|
|
120310
|
+
}
|
|
120311
|
+
return afterSlash(code);
|
|
120312
|
+
}
|
|
120313
|
+
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
120314
|
+
function afterSlash(code) {
|
|
120315
|
+
if (asciiAlpha(code)) {
|
|
120316
|
+
lastNonSpace = code;
|
|
120317
|
+
effects.consume(code);
|
|
120318
|
+
return scanToLineEnd;
|
|
120319
|
+
}
|
|
120320
|
+
effects.exit(types_types.data);
|
|
120321
|
+
return nok(code);
|
|
120322
|
+
}
|
|
120323
|
+
function scanToLineEnd(code) {
|
|
120324
|
+
if (code === null || markdownLineEnding(code)) {
|
|
120325
|
+
effects.exit(types_types.data);
|
|
120326
|
+
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
120327
|
+
}
|
|
120328
|
+
if (!markdownSpace(code))
|
|
120329
|
+
lastNonSpace = code;
|
|
120330
|
+
effects.consume(code);
|
|
120331
|
+
return scanToLineEnd;
|
|
120332
|
+
}
|
|
120333
|
+
}
|
|
120334
|
+
// A line ending whose next line isn't a lazy paragraph continuation. Checked so a
|
|
120335
|
+
// component body's blank/continuation lines aren't stolen by an interrupted paragraph.
|
|
120336
|
+
const continuation_checks_nonLazyContinuationStart = {
|
|
120337
|
+
tokenize: continuation_checks_tokenizeNonLazyContinuationStart,
|
|
120338
|
+
partial: true,
|
|
120339
|
+
};
|
|
120340
|
+
// Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
|
|
120341
|
+
// that merely starts with a tag? Run via `effects.check` so it never consumes.
|
|
120342
|
+
const markupOnlyContinuation = {
|
|
120343
|
+
tokenize: tokenizeMarkupOnlyContinuation,
|
|
120344
|
+
partial: true,
|
|
120345
|
+
};
|
|
120346
|
+
|
|
120166
120347
|
;// ./lib/micromark/mdx-component/syntax.ts
|
|
120167
120348
|
|
|
120168
120349
|
|
|
120169
120350
|
|
|
120170
120351
|
|
|
120171
120352
|
|
|
120353
|
+
|
|
120172
120354
|
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
120173
120355
|
// section, …) always start a block, so they stay flow even with trailing
|
|
120174
120356
|
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
@@ -120178,16 +120360,12 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
|
120178
120360
|
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
120179
120361
|
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
120180
120362
|
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
120181
|
-
|
|
120182
|
-
|
|
120183
|
-
|
|
120184
|
-
|
|
120185
|
-
|
|
120186
|
-
|
|
120187
|
-
const markupOnlyContinuation = {
|
|
120188
|
-
tokenize: tokenizeMarkupOnlyContinuation,
|
|
120189
|
-
partial: true,
|
|
120190
|
-
};
|
|
120363
|
+
// Both are 4 columns per CommonMark, but they mean different things: a tab advances
|
|
120364
|
+
// to the next multiple of TAB_STOP_WIDTH, and INDENTED_CODE_MIN_COLUMNS is the depth
|
|
120365
|
+
// at which a line would fragment into indented code. Named separately so the two
|
|
120366
|
+
// concepts don't read as one incidental literal.
|
|
120367
|
+
const TAB_STOP_WIDTH = 4;
|
|
120368
|
+
const INDENTED_CODE_MIN_COLUMNS = 4;
|
|
120191
120369
|
function resolveToMdxComponent(events) {
|
|
120192
120370
|
let index = events.length;
|
|
120193
120371
|
while (index > 0) {
|
|
@@ -120246,6 +120424,18 @@ function createTokenize(mode) {
|
|
|
120246
120424
|
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
120247
120425
|
let isPlainBlockClaim = false;
|
|
120248
120426
|
let pendingBlankLine = false;
|
|
120427
|
+
// Leading indent columns of the current plain-claim line, reset per line; ≥4 is
|
|
120428
|
+
// where CommonMark would fragment the island as indented code. Tabs advance to the
|
|
120429
|
+
// next 4-column stop — the same rule `expandIndentToColumns`
|
|
120430
|
+
// (processor/transform/mdxish/indentation.ts) applies, kept in sync by hand since
|
|
120431
|
+
// this side works on a `Code` stream, not a string. NB: do NOT swap this for
|
|
120432
|
+
// `self.now().column`; micromark bumps the point column by 1 per `horizontalTab`
|
|
120433
|
+
// code (the trailing `virtualSpace` codes don't move it), so it measures a tab as
|
|
120434
|
+
// 1 column, reviving the tab-under-measurement bug this math exists to avoid.
|
|
120435
|
+
let plainClaimIndentColumns = 0;
|
|
120436
|
+
// True once a non-blank line follows the opener: a deep island below it is nested
|
|
120437
|
+
// (cosmetic indent), not top-of-body indented code.
|
|
120438
|
+
let sawPlainBlockBodyContent = false;
|
|
120249
120439
|
// Code span tracking
|
|
120250
120440
|
let codeSpanOpenSize = 0;
|
|
120251
120441
|
let codeSpanCloseSize = 0;
|
|
@@ -120545,7 +120735,7 @@ function createTokenize(mode) {
|
|
|
120545
120735
|
}
|
|
120546
120736
|
// Continuation for multi-line opening tags
|
|
120547
120737
|
function openTagContinuationStart(code) {
|
|
120548
|
-
return effects.check(
|
|
120738
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
|
|
120549
120739
|
}
|
|
120550
120740
|
function openTagContinuationNonLazy(code) {
|
|
120551
120741
|
sawLineEnding = true;
|
|
@@ -120590,6 +120780,9 @@ function createTokenize(mode) {
|
|
|
120590
120780
|
}
|
|
120591
120781
|
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
120592
120782
|
openerLineHasContent = true;
|
|
120783
|
+
// Continuation content marks a later deep island as nested, not indented code.
|
|
120784
|
+
if (!onOpenerLine)
|
|
120785
|
+
sawPlainBlockBodyContent = true;
|
|
120593
120786
|
}
|
|
120594
120787
|
if (code === codes.backslash) {
|
|
120595
120788
|
effects.consume(code);
|
|
@@ -120670,7 +120863,7 @@ function createTokenize(mode) {
|
|
|
120670
120863
|
return inFencedCode;
|
|
120671
120864
|
}
|
|
120672
120865
|
function fencedCodeContinuationStart(code) {
|
|
120673
|
-
return effects.check(
|
|
120866
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
|
|
120674
120867
|
}
|
|
120675
120868
|
function fencedCodeContinuationNonLazy(code) {
|
|
120676
120869
|
sawLineEnding = true;
|
|
@@ -120878,7 +121071,7 @@ function createTokenize(mode) {
|
|
|
120878
121071
|
}
|
|
120879
121072
|
// ── Body continuation (line endings) ───────────────────────────────────
|
|
120880
121073
|
function bodyContinuationStart(code) {
|
|
120881
|
-
return effects.check(
|
|
121074
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
|
|
120882
121075
|
}
|
|
120883
121076
|
function bodyContinuationNonLazy(code) {
|
|
120884
121077
|
sawLineEnding = true;
|
|
@@ -120904,8 +121097,10 @@ function createTokenize(mode) {
|
|
|
120904
121097
|
return inBodyBraceString(code);
|
|
120905
121098
|
return inBodyBraceExpr(code);
|
|
120906
121099
|
}
|
|
120907
|
-
if (isPlainBlockClaim)
|
|
121100
|
+
if (isPlainBlockClaim) {
|
|
121101
|
+
plainClaimIndentColumns = 0;
|
|
120908
121102
|
return plainClaimLineStart(code);
|
|
121103
|
+
}
|
|
120909
121104
|
return bodyLineStart(code);
|
|
120910
121105
|
}
|
|
120911
121106
|
// Dispatch a non-blank continuation line: fenced code at line start, else body.
|
|
@@ -120935,6 +121130,8 @@ function createTokenize(mode) {
|
|
|
120935
121130
|
function plainClaimLineStart(code) {
|
|
120936
121131
|
// Leading whitespace only → treat as a blank line, matching CommonMark.
|
|
120937
121132
|
if (code === codes.space || code === codes.horizontalTab) {
|
|
121133
|
+
plainClaimIndentColumns +=
|
|
121134
|
+
code === codes.horizontalTab ? TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH) : 1;
|
|
120938
121135
|
effects.consume(code);
|
|
120939
121136
|
return plainClaimLineStart;
|
|
120940
121137
|
}
|
|
@@ -120943,10 +121140,18 @@ function createTokenize(mode) {
|
|
|
120943
121140
|
effects.exit('mdxComponentData');
|
|
120944
121141
|
return bodyContinuationStart(code);
|
|
120945
121142
|
}
|
|
120946
|
-
// Across a blank line the block only continues onto a markup-only line; a
|
|
120947
|
-
// paragraph that merely starts with a tag must fall back so its markdown
|
|
120948
|
-
// parses and rehype-raw re-nests it into the wrapper.
|
|
120949
121143
|
if (pendingBlankLine) {
|
|
121144
|
+
// A 4+ col island nested under other tags is cosmetic nesting indent, not code:
|
|
121145
|
+
// keep claiming so promotion dedents + re-parses it as markdown (RM-17560).
|
|
121146
|
+
// Tags whose bodies stay raw are excluded — a claimed island there would never
|
|
121147
|
+
// be re-parsed and would leak as literal text.
|
|
121148
|
+
if (plainClaimIndentColumns >= INDENTED_CODE_MIN_COLUMNS &&
|
|
121149
|
+
sawPlainBlockBodyContent &&
|
|
121150
|
+
!NON_REPARSED_BODY_TAGS.has(tagName)) {
|
|
121151
|
+
return plainClaimContinue(code);
|
|
121152
|
+
}
|
|
121153
|
+
// Otherwise only a markup-only tag line continues; markdown/prose falls back to
|
|
121154
|
+
// CommonMark so it parses and rehype-raw re-nests it into the wrapper.
|
|
120950
121155
|
if (code !== codes.lessThan)
|
|
120951
121156
|
return nok(code);
|
|
120952
121157
|
return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
|
|
@@ -120967,66 +121172,6 @@ function createTokenize(mode) {
|
|
|
120967
121172
|
}
|
|
120968
121173
|
};
|
|
120969
121174
|
}
|
|
120970
|
-
function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
120971
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
120972
|
-
const self = this;
|
|
120973
|
-
return start;
|
|
120974
|
-
function start(code) {
|
|
120975
|
-
if (markdownLineEnding(code)) {
|
|
120976
|
-
effects.enter(types_types.lineEnding);
|
|
120977
|
-
effects.consume(code);
|
|
120978
|
-
effects.exit(types_types.lineEnding);
|
|
120979
|
-
return after;
|
|
120980
|
-
}
|
|
120981
|
-
return nok(code);
|
|
120982
|
-
}
|
|
120983
|
-
function after(code) {
|
|
120984
|
-
if (self.parser.lazy[self.now().line]) {
|
|
120985
|
-
return nok(code);
|
|
120986
|
-
}
|
|
120987
|
-
return ok(code);
|
|
120988
|
-
}
|
|
120989
|
-
}
|
|
120990
|
-
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
120991
|
-
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
120992
|
-
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
120993
|
-
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
120994
|
-
let lastNonSpace = null;
|
|
120995
|
-
return start;
|
|
120996
|
-
function start(code) {
|
|
120997
|
-
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
120998
|
-
effects.enter(types_types.data);
|
|
120999
|
-
effects.consume(code);
|
|
121000
|
-
return afterLessThan;
|
|
121001
|
-
}
|
|
121002
|
-
function afterLessThan(code) {
|
|
121003
|
-
if (code === codes.slash) {
|
|
121004
|
-
effects.consume(code);
|
|
121005
|
-
return afterSlash;
|
|
121006
|
-
}
|
|
121007
|
-
return afterSlash(code);
|
|
121008
|
-
}
|
|
121009
|
-
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
121010
|
-
function afterSlash(code) {
|
|
121011
|
-
if (asciiAlpha(code)) {
|
|
121012
|
-
lastNonSpace = code;
|
|
121013
|
-
effects.consume(code);
|
|
121014
|
-
return scanToLineEnd;
|
|
121015
|
-
}
|
|
121016
|
-
effects.exit(types_types.data);
|
|
121017
|
-
return nok(code);
|
|
121018
|
-
}
|
|
121019
|
-
function scanToLineEnd(code) {
|
|
121020
|
-
if (code === null || markdownLineEnding(code)) {
|
|
121021
|
-
effects.exit(types_types.data);
|
|
121022
|
-
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
121023
|
-
}
|
|
121024
|
-
if (!markdownSpace(code))
|
|
121025
|
-
lastNonSpace = code;
|
|
121026
|
-
effects.consume(code);
|
|
121027
|
-
return scanToLineEnd;
|
|
121028
|
-
}
|
|
121029
|
-
}
|
|
121030
121175
|
/**
|
|
121031
121176
|
* Micromark extension that tokenizes MDX-like components.
|
|
121032
121177
|
*
|
|
@@ -121080,6 +121225,7 @@ function syntax_mdxComponent() {
|
|
|
121080
121225
|
|
|
121081
121226
|
|
|
121082
121227
|
|
|
121228
|
+
|
|
121083
121229
|
|
|
121084
121230
|
const buildInlineMdProcessor = (safeMode) => {
|
|
121085
121231
|
// `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
|
|
@@ -121151,7 +121297,7 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
|
|
|
121151
121297
|
// Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
|
|
121152
121298
|
// structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
|
|
121153
121299
|
// `mdxishJsxToMdast`, both of which run later on raw html nodes.
|
|
121154
|
-
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table',
|
|
121300
|
+
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table', ...NON_REPARSED_BODY_TAGS]);
|
|
121155
121301
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
121156
121302
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
121157
121303
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
@@ -121510,15 +121656,22 @@ function safeDeindent(text) {
|
|
|
121510
121656
|
*/
|
|
121511
121657
|
const parseMdChildren = (value, safeMode) => {
|
|
121512
121658
|
const parsed = getInlineMdProcessor({ safeMode }).parse(terminateHtmlFlowBlocks(safeDeindent(value).trim()));
|
|
121659
|
+
// Promote nested wrappers bottom-up so an outer wrapper sees markdown buried in a
|
|
121660
|
+
// child claimed whole (e.g. `<li>` in `<ol>`) before its containsMarkdownConstruct check (RM-17560).
|
|
121661
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define -- mutually recursive; hoisted decl, safe at runtime
|
|
121662
|
+
promoteComponentBlocks(parsed, safeMode, null);
|
|
121513
121663
|
return parsed.children || [];
|
|
121514
121664
|
};
|
|
121515
|
-
//
|
|
121516
|
-
// components among them
|
|
121517
|
-
|
|
121665
|
+
// Splices trailing content in as sibling nodes. parseMdChildren has already
|
|
121666
|
+
// promoted any components nested among them (bottom-up); the main loop's
|
|
121667
|
+
// index-based walk then reaches these spliced siblings and the original children
|
|
121668
|
+
// they shift down, so no parent re-queue is needed. Each spliced subtree is marked
|
|
121669
|
+
// `promoted` so the walk doesn't redundantly re-descend into it (its html is gone).
|
|
121670
|
+
const parseSibling = (parent, index, sibling, safeMode, promoted) => {
|
|
121518
121671
|
const siblingNodes = parseMdChildren(sibling, safeMode);
|
|
121519
121672
|
if (siblingNodes.length > 0) {
|
|
121520
121673
|
parent.children.splice(index + 1, 0, ...siblingNodes);
|
|
121521
|
-
|
|
121674
|
+
siblingNodes.forEach(siblingNode => promoted.add(siblingNode));
|
|
121522
121675
|
}
|
|
121523
121676
|
};
|
|
121524
121677
|
// Ends the position at `consumedLength` so the component doesn't claim trailing
|
|
@@ -121584,16 +121737,19 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
|
121584
121737
|
* The opening tag, content, and closing tag are all captured in one HTML node
|
|
121585
121738
|
* (guaranteed by the mdx-component tokenizer).
|
|
121586
121739
|
*/
|
|
121587
|
-
|
|
121740
|
+
function promoteComponentBlocks(tree, safeMode, source) {
|
|
121588
121741
|
const stack = [tree];
|
|
121589
|
-
const safeMode = !!opts.safeMode;
|
|
121590
|
-
const source = file?.value ? String(file.value) : null;
|
|
121591
121742
|
const parseOpts = { preserveExpressionsAsText: safeMode };
|
|
121743
|
+
// Subtrees a nested parseMdChildren already promoted wholesale (spliced siblings):
|
|
121744
|
+
// re-descending them finds no html to promote, so skip them.
|
|
121745
|
+
const promoted = new WeakSet();
|
|
121592
121746
|
const processChildNode = (parent, index) => {
|
|
121593
121747
|
const node = parent.children[index];
|
|
121594
121748
|
if (!node)
|
|
121595
121749
|
return;
|
|
121596
|
-
|
|
121750
|
+
// Descend into container nodes (lists, blockquotes, …) so their html children
|
|
121751
|
+
// are reached — unless the subtree was already promoted upstream.
|
|
121752
|
+
if ('children' in node && Array.isArray(node.children) && !promoted.has(node)) {
|
|
121597
121753
|
stack.push(node);
|
|
121598
121754
|
}
|
|
121599
121755
|
// Only html nodes can be an unparsed MDX component.
|
|
@@ -121648,7 +121804,7 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121648
121804
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
121649
121805
|
const remainingContent = contentAfterTag.trim();
|
|
121650
121806
|
if (remainingContent) {
|
|
121651
|
-
parseSibling(
|
|
121807
|
+
parseSibling(parent, index, remainingContent, safeMode, promoted);
|
|
121652
121808
|
}
|
|
121653
121809
|
return;
|
|
121654
121810
|
}
|
|
@@ -121675,43 +121831,57 @@ const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
121675
121831
|
return;
|
|
121676
121832
|
// Lowercase tags are usually inline; unwrap a sole paragraph so their
|
|
121677
121833
|
// phrasing content isn't spuriously block-wrapped.
|
|
121834
|
+
let unwrappedSoleParagraph = false;
|
|
121678
121835
|
if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
|
|
121679
121836
|
parsedChildren = parsedChildren[0].children;
|
|
121837
|
+
unwrappedSoleParagraph = true;
|
|
121838
|
+
}
|
|
121839
|
+
// Without trailing content the whole node position is correct. With it, end
|
|
121840
|
+
// precisely at the closing tag — preferring source offsets when available (the
|
|
121841
|
+
// node's value strips blockquote/list prefixes), else the consumed span.
|
|
121842
|
+
let endPosition = node.position;
|
|
121843
|
+
if (contentAfterClose) {
|
|
121844
|
+
endPosition = source
|
|
121845
|
+
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
121846
|
+
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length);
|
|
121680
121847
|
}
|
|
121681
121848
|
const componentNode = createComponentNode({
|
|
121682
121849
|
tag,
|
|
121683
121850
|
attributes,
|
|
121684
121851
|
children: parsedChildren,
|
|
121685
121852
|
startPosition: node.position,
|
|
121686
|
-
|
|
121687
|
-
// offsets when available (the node's value strips blockquote/list
|
|
121688
|
-
// prefixes); otherwise fall back to the whole node position.
|
|
121689
|
-
endPosition: contentAfterClose
|
|
121690
|
-
? source
|
|
121691
|
-
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
121692
|
-
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length)
|
|
121693
|
-
: node.position,
|
|
121853
|
+
endPosition,
|
|
121694
121854
|
});
|
|
121695
121855
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
121696
|
-
//
|
|
121697
|
-
|
|
121698
|
-
|
|
121699
|
-
}
|
|
121700
|
-
else if (componentNode.children.length > 0) {
|
|
121856
|
+
// The unwrap reparented the children out of their paragraph, so re-walk them
|
|
121857
|
+
// since the children HTML may contain promotable syntax (e.g. `{…}`-attr tags)
|
|
121858
|
+
if (unwrappedSoleParagraph) {
|
|
121701
121859
|
stack.push(componentNode);
|
|
121702
121860
|
}
|
|
121861
|
+
// Trailing content after the close becomes siblings; parseMdChildren has
|
|
121862
|
+
// already promoted any components nested inside both sides, so the promoted
|
|
121863
|
+
// subtree itself needs no re-queue.
|
|
121864
|
+
if (contentAfterClose) {
|
|
121865
|
+
parseSibling(parent, index, contentAfterClose, safeMode, promoted);
|
|
121866
|
+
}
|
|
121703
121867
|
}
|
|
121704
121868
|
};
|
|
121705
|
-
// Depth-first so nodes keep their source order.
|
|
121869
|
+
// Depth-first so nodes keep their source order. Index-based (not forEach) and
|
|
121870
|
+
// re-reading length each step: parseSibling splices siblings in mid-iteration, and
|
|
121871
|
+
// those — plus the original children they shift down — must all stay eligible.
|
|
121706
121872
|
while (stack.length) {
|
|
121707
121873
|
const parent = stack.pop();
|
|
121708
121874
|
if (parent?.children) {
|
|
121709
|
-
parent.children.
|
|
121875
|
+
for (let index = 0; index < parent.children.length; index += 1) {
|
|
121710
121876
|
processChildNode(parent, index);
|
|
121711
|
-
}
|
|
121877
|
+
}
|
|
121712
121878
|
}
|
|
121713
121879
|
}
|
|
121714
121880
|
return tree;
|
|
121881
|
+
}
|
|
121882
|
+
const mdx_blocks_mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
121883
|
+
const source = file?.value ? String(file.value) : null;
|
|
121884
|
+
return promoteComponentBlocks(tree, !!opts.safeMode, source);
|
|
121715
121885
|
};
|
|
121716
121886
|
/* harmony default export */ const mdx_blocks = (mdx_blocks_mdxishMdxComponentBlocks);
|
|
121717
121887
|
|
|
@@ -126728,6 +126898,7 @@ function loadComponents() {
|
|
|
126728
126898
|
|
|
126729
126899
|
|
|
126730
126900
|
|
|
126901
|
+
|
|
126731
126902
|
|
|
126732
126903
|
|
|
126733
126904
|
const defaultTransformers = [
|
|
@@ -126742,10 +126913,11 @@ const defaultTransformers = [
|
|
|
126742
126913
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
126743
126914
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
126744
126915
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
126745
|
-
* 3.
|
|
126746
|
-
* 4.
|
|
126747
|
-
* 5.
|
|
126748
|
-
* 6.
|
|
126916
|
+
* 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
|
|
126917
|
+
* 4. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
126918
|
+
* 5. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
126919
|
+
* 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
126920
|
+
* 7. Replace snake_case component names with parser-safe placeholders
|
|
126749
126921
|
*/
|
|
126750
126922
|
function preprocessContent(content, opts) {
|
|
126751
126923
|
const { knownComponents } = opts;
|
|
@@ -126753,6 +126925,10 @@ function preprocessContent(content, opts) {
|
|
|
126753
126925
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
126754
126926
|
let result = normalizeClosingTagWhitespace(content);
|
|
126755
126927
|
result = normalizeTableSeparator(result);
|
|
126928
|
+
// Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
|
|
126929
|
+
// would otherwise fragment it (children spill out as an indented code block once
|
|
126930
|
+
// a wrapper re-parses its deindented body — #1545).
|
|
126931
|
+
result = collapseForeignContentBlankLines(result);
|
|
126756
126932
|
result = terminateHtmlFlowBlocks(result);
|
|
126757
126933
|
result = closeSelfClosingHtmlTags(result);
|
|
126758
126934
|
result = normalizeCompactHeadings(result);
|
|
@@ -127368,6 +127544,8 @@ const mdxishTags_tags = (doc) => {
|
|
|
127368
127544
|
|
|
127369
127545
|
|
|
127370
127546
|
|
|
127547
|
+
|
|
127548
|
+
|
|
127371
127549
|
/**
|
|
127372
127550
|
* Removes Markdown and MDX comments.
|
|
127373
127551
|
*/
|
|
@@ -127378,10 +127556,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
127378
127556
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
127379
127557
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
127380
127558
|
// 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
|
|
127559
|
+
// 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
|
|
127381
127560
|
if (mdxish) {
|
|
127382
127561
|
processor
|
|
127383
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
127384
|
-
.data('fromMarkdownExtensions', [
|
|
127562
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
127563
|
+
.data('fromMarkdownExtensions', [
|
|
127564
|
+
htmlBlockComponentFromMarkdown(),
|
|
127565
|
+
jsxTableFromMarkdown(),
|
|
127566
|
+
mdxComponentFromMarkdown(),
|
|
127567
|
+
mdxExpressionFromMarkdown(),
|
|
127568
|
+
])
|
|
127385
127569
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
127386
127570
|
}
|
|
127387
127571
|
processor
|