@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
package/dist/main.js
CHANGED
|
@@ -1893,7 +1893,7 @@ module.exports = function (exec) {
|
|
|
1893
1893
|
|
|
1894
1894
|
/***/ }),
|
|
1895
1895
|
|
|
1896
|
-
/***/
|
|
1896
|
+
/***/ 9461:
|
|
1897
1897
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
1898
1898
|
|
|
1899
1899
|
module.exports = __webpack_require__(4556)('native-function-to-string', Function.toString);
|
|
@@ -2493,7 +2493,7 @@ var global = __webpack_require__(7526);
|
|
|
2493
2493
|
var hide = __webpack_require__(3341);
|
|
2494
2494
|
var has = __webpack_require__(7917);
|
|
2495
2495
|
var SRC = __webpack_require__(4415)('src');
|
|
2496
|
-
var $toString = __webpack_require__(
|
|
2496
|
+
var $toString = __webpack_require__(9461);
|
|
2497
2497
|
var TO_STRING = 'toString';
|
|
2498
2498
|
var TPL = ('' + $toString).split(TO_STRING);
|
|
2499
2499
|
|
|
@@ -11839,8 +11839,8 @@ const Callout = (props) => {
|
|
|
11839
11839
|
|
|
11840
11840
|
|
|
11841
11841
|
|
|
11842
|
-
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, target, title }) => {
|
|
11843
|
-
const Tag = href ?
|
|
11842
|
+
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, LinkComponent = 'a', target, title, }) => {
|
|
11843
|
+
const Tag = href ? LinkComponent : 'div';
|
|
11844
11844
|
return (external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement(Tag, { className: `Card Card_${kind}`, href: href, target: target },
|
|
11845
11845
|
icon && external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement(components_Icon, { className: "Card-icon", icon: icon, iconColor: iconColor }),
|
|
11846
11846
|
external_amd_react_commonjs_react_commonjs2_react_root_React_umd_react_default().createElement("div", { className: "Card-content" },
|
|
@@ -76301,6 +76301,21 @@ 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']);
|
|
76313
|
+
/**
|
|
76314
|
+
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
76315
|
+
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
76316
|
+
* set per the HTML spec, so transforms can treat these roots as opaque islands.
|
|
76317
|
+
*/
|
|
76318
|
+
const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
|
|
76304
76319
|
/**
|
|
76305
76320
|
* HTML void elements — elements that have no closing tag and no children.
|
|
76306
76321
|
*
|
|
@@ -98930,6 +98945,9 @@ function getComponentName(componentName, components) {
|
|
|
98930
98945
|
|
|
98931
98946
|
|
|
98932
98947
|
|
|
98948
|
+
// Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
|
|
98949
|
+
// untouched (their children are namespaced XML, not HTML tags/components).
|
|
98950
|
+
const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
|
|
98933
98951
|
function isElementContentNode(node) {
|
|
98934
98952
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
98935
98953
|
}
|
|
@@ -99105,6 +99123,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
99105
99123
|
visit(tree, 'element', (node, index, parent) => {
|
|
99106
99124
|
if (index === undefined || !parent)
|
|
99107
99125
|
return;
|
|
99126
|
+
// Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
|
|
99127
|
+
// aren't HTML tags or components, so the "unknown component" removal below would
|
|
99128
|
+
// otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
|
|
99129
|
+
// eslint-disable-next-line consistent-return
|
|
99130
|
+
if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
|
|
99131
|
+
return SKIP;
|
|
99108
99132
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
99109
99133
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
99110
99134
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -99416,6 +99440,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
99416
99440
|
return restoreCodeBlocks(result, protectedCode);
|
|
99417
99441
|
}
|
|
99418
99442
|
|
|
99443
|
+
;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
|
|
99444
|
+
|
|
99445
|
+
|
|
99446
|
+
// `svg|math`, from the canonical list so this stays in sync with the component transform.
|
|
99447
|
+
const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
|
|
99448
|
+
// A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
|
|
99449
|
+
// root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
|
|
99450
|
+
const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
|
|
99451
|
+
// Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
|
|
99452
|
+
// `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
|
|
99453
|
+
// chars (including newlines) are consumed one at a time.
|
|
99454
|
+
const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
|
|
99455
|
+
// One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
|
|
99456
|
+
// and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
|
|
99457
|
+
// `<svg-icon>` out. Group 1 is `/` only for a self-closer.
|
|
99458
|
+
const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
|
|
99459
|
+
// An HTML comment. Foreign markup inside one is inert and must not open an island.
|
|
99460
|
+
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
99461
|
+
const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
|
|
99462
|
+
/**
|
|
99463
|
+
* `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
|
|
99464
|
+
* lines are known-insignificant XML. Matching whole tags (not per-line open/close
|
|
99465
|
+
* counts) keeps multi-line openers and self-closers balanced, so a wrapped
|
|
99466
|
+
* `<svg … />` can't latch and swallow the doc (#1545).
|
|
99467
|
+
*
|
|
99468
|
+
* Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
|
|
99469
|
+
* closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
|
|
99470
|
+
* swallowing every blank line after it, without hiding the real islands that follow.
|
|
99471
|
+
*/
|
|
99472
|
+
function findForeignContentSpans(text) {
|
|
99473
|
+
const spans = [];
|
|
99474
|
+
// Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
|
|
99475
|
+
// must not open an island and latch onto the rest of the doc.
|
|
99476
|
+
const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
|
|
99477
|
+
// Offsets of openers still waiting for their closer, innermost last.
|
|
99478
|
+
const openOffsets = [];
|
|
99479
|
+
[...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
|
|
99480
|
+
const offset = match.index ?? 0;
|
|
99481
|
+
if (withinAny(comments, offset))
|
|
99482
|
+
return; // markup inside an HTML comment is inert
|
|
99483
|
+
if (match[1] === '/')
|
|
99484
|
+
return; // self-closing tag opens no island
|
|
99485
|
+
if (match[0].startsWith('</')) {
|
|
99486
|
+
const start = openOffsets.pop();
|
|
99487
|
+
if (start !== undefined)
|
|
99488
|
+
spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
|
|
99489
|
+
}
|
|
99490
|
+
else {
|
|
99491
|
+
openOffsets.push(offset);
|
|
99492
|
+
}
|
|
99493
|
+
});
|
|
99494
|
+
return spans;
|
|
99495
|
+
}
|
|
99496
|
+
/**
|
|
99497
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
99498
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
99499
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
99500
|
+
*/
|
|
99501
|
+
function collapseForeignContentBlankLines(content) {
|
|
99502
|
+
// Fast path: nothing to do when the doc has no foreign-content island.
|
|
99503
|
+
if (!ANY_ROOT_RE.test(content))
|
|
99504
|
+
return content;
|
|
99505
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
99506
|
+
const islands = findForeignContentSpans(protectedContent);
|
|
99507
|
+
// Drop blank lines inside an island; keep everything else verbatim.
|
|
99508
|
+
const lines = [];
|
|
99509
|
+
let lineStart = 0;
|
|
99510
|
+
protectedContent.split('\n').forEach(line => {
|
|
99511
|
+
if (line.trim().length > 0 || !withinAny(islands, lineStart))
|
|
99512
|
+
lines.push(line);
|
|
99513
|
+
lineStart += line.length + 1; // +1 for the '\n' that split() removed
|
|
99514
|
+
});
|
|
99515
|
+
return restoreCodeBlocks(lines.join('\n'), protectedCode);
|
|
99516
|
+
}
|
|
99517
|
+
|
|
99419
99518
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
99420
99519
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
99421
99520
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -101408,12 +101507,95 @@ function tokenizeMagicBlockText(effects, ok, nok) {
|
|
|
101408
101507
|
*/
|
|
101409
101508
|
|
|
101410
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
|
+
|
|
101411
101592
|
;// ./lib/micromark/mdx-component/syntax.ts
|
|
101412
101593
|
|
|
101413
101594
|
|
|
101414
101595
|
|
|
101415
101596
|
|
|
101416
101597
|
|
|
101598
|
+
|
|
101417
101599
|
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
101418
101600
|
// section, …) always start a block, so they stay flow even with trailing
|
|
101419
101601
|
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
@@ -101423,16 +101605,12 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
|
101423
101605
|
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
101424
101606
|
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
101425
101607
|
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
101426
|
-
|
|
101427
|
-
|
|
101428
|
-
|
|
101429
|
-
|
|
101430
|
-
|
|
101431
|
-
|
|
101432
|
-
const markupOnlyContinuation = {
|
|
101433
|
-
tokenize: tokenizeMarkupOnlyContinuation,
|
|
101434
|
-
partial: true,
|
|
101435
|
-
};
|
|
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;
|
|
101436
101614
|
function resolveToMdxComponent(events) {
|
|
101437
101615
|
let index = events.length;
|
|
101438
101616
|
while (index > 0) {
|
|
@@ -101491,6 +101669,18 @@ function createTokenize(mode) {
|
|
|
101491
101669
|
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
101492
101670
|
let isPlainBlockClaim = false;
|
|
101493
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;
|
|
101494
101684
|
// Code span tracking
|
|
101495
101685
|
let codeSpanOpenSize = 0;
|
|
101496
101686
|
let codeSpanCloseSize = 0;
|
|
@@ -101790,7 +101980,7 @@ function createTokenize(mode) {
|
|
|
101790
101980
|
}
|
|
101791
101981
|
// Continuation for multi-line opening tags
|
|
101792
101982
|
function openTagContinuationStart(code) {
|
|
101793
|
-
return effects.check(
|
|
101983
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
|
|
101794
101984
|
}
|
|
101795
101985
|
function openTagContinuationNonLazy(code) {
|
|
101796
101986
|
sawLineEnding = true;
|
|
@@ -101835,6 +102025,9 @@ function createTokenize(mode) {
|
|
|
101835
102025
|
}
|
|
101836
102026
|
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
101837
102027
|
openerLineHasContent = true;
|
|
102028
|
+
// Continuation content marks a later deep island as nested, not indented code.
|
|
102029
|
+
if (!onOpenerLine)
|
|
102030
|
+
sawPlainBlockBodyContent = true;
|
|
101838
102031
|
}
|
|
101839
102032
|
if (code === codes.backslash) {
|
|
101840
102033
|
effects.consume(code);
|
|
@@ -101915,7 +102108,7 @@ function createTokenize(mode) {
|
|
|
101915
102108
|
return inFencedCode;
|
|
101916
102109
|
}
|
|
101917
102110
|
function fencedCodeContinuationStart(code) {
|
|
101918
|
-
return effects.check(
|
|
102111
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
|
|
101919
102112
|
}
|
|
101920
102113
|
function fencedCodeContinuationNonLazy(code) {
|
|
101921
102114
|
sawLineEnding = true;
|
|
@@ -102123,7 +102316,7 @@ function createTokenize(mode) {
|
|
|
102123
102316
|
}
|
|
102124
102317
|
// ── Body continuation (line endings) ───────────────────────────────────
|
|
102125
102318
|
function bodyContinuationStart(code) {
|
|
102126
|
-
return effects.check(
|
|
102319
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
|
|
102127
102320
|
}
|
|
102128
102321
|
function bodyContinuationNonLazy(code) {
|
|
102129
102322
|
sawLineEnding = true;
|
|
@@ -102149,8 +102342,10 @@ function createTokenize(mode) {
|
|
|
102149
102342
|
return inBodyBraceString(code);
|
|
102150
102343
|
return inBodyBraceExpr(code);
|
|
102151
102344
|
}
|
|
102152
|
-
if (isPlainBlockClaim)
|
|
102345
|
+
if (isPlainBlockClaim) {
|
|
102346
|
+
plainClaimIndentColumns = 0;
|
|
102153
102347
|
return plainClaimLineStart(code);
|
|
102348
|
+
}
|
|
102154
102349
|
return bodyLineStart(code);
|
|
102155
102350
|
}
|
|
102156
102351
|
// Dispatch a non-blank continuation line: fenced code at line start, else body.
|
|
@@ -102180,6 +102375,8 @@ function createTokenize(mode) {
|
|
|
102180
102375
|
function plainClaimLineStart(code) {
|
|
102181
102376
|
// Leading whitespace only → treat as a blank line, matching CommonMark.
|
|
102182
102377
|
if (code === codes.space || code === codes.horizontalTab) {
|
|
102378
|
+
plainClaimIndentColumns +=
|
|
102379
|
+
code === codes.horizontalTab ? TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH) : 1;
|
|
102183
102380
|
effects.consume(code);
|
|
102184
102381
|
return plainClaimLineStart;
|
|
102185
102382
|
}
|
|
@@ -102188,10 +102385,18 @@ function createTokenize(mode) {
|
|
|
102188
102385
|
effects.exit('mdxComponentData');
|
|
102189
102386
|
return bodyContinuationStart(code);
|
|
102190
102387
|
}
|
|
102191
|
-
// Across a blank line the block only continues onto a markup-only line; a
|
|
102192
|
-
// paragraph that merely starts with a tag must fall back so its markdown
|
|
102193
|
-
// parses and rehype-raw re-nests it into the wrapper.
|
|
102194
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.
|
|
102195
102400
|
if (code !== codes.lessThan)
|
|
102196
102401
|
return nok(code);
|
|
102197
102402
|
return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
|
|
@@ -102212,66 +102417,6 @@ function createTokenize(mode) {
|
|
|
102212
102417
|
}
|
|
102213
102418
|
};
|
|
102214
102419
|
}
|
|
102215
|
-
function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
102216
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
102217
|
-
const self = this;
|
|
102218
|
-
return start;
|
|
102219
|
-
function start(code) {
|
|
102220
|
-
if (markdownLineEnding(code)) {
|
|
102221
|
-
effects.enter(types_types.lineEnding);
|
|
102222
|
-
effects.consume(code);
|
|
102223
|
-
effects.exit(types_types.lineEnding);
|
|
102224
|
-
return after;
|
|
102225
|
-
}
|
|
102226
|
-
return nok(code);
|
|
102227
|
-
}
|
|
102228
|
-
function after(code) {
|
|
102229
|
-
if (self.parser.lazy[self.now().line]) {
|
|
102230
|
-
return nok(code);
|
|
102231
|
-
}
|
|
102232
|
-
return ok(code);
|
|
102233
|
-
}
|
|
102234
|
-
}
|
|
102235
|
-
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
102236
|
-
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
102237
|
-
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
102238
|
-
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
102239
|
-
let lastNonSpace = null;
|
|
102240
|
-
return start;
|
|
102241
|
-
function start(code) {
|
|
102242
|
-
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
102243
|
-
effects.enter(types_types.data);
|
|
102244
|
-
effects.consume(code);
|
|
102245
|
-
return afterLessThan;
|
|
102246
|
-
}
|
|
102247
|
-
function afterLessThan(code) {
|
|
102248
|
-
if (code === codes.slash) {
|
|
102249
|
-
effects.consume(code);
|
|
102250
|
-
return afterSlash;
|
|
102251
|
-
}
|
|
102252
|
-
return afterSlash(code);
|
|
102253
|
-
}
|
|
102254
|
-
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
102255
|
-
function afterSlash(code) {
|
|
102256
|
-
if (asciiAlpha(code)) {
|
|
102257
|
-
lastNonSpace = code;
|
|
102258
|
-
effects.consume(code);
|
|
102259
|
-
return scanToLineEnd;
|
|
102260
|
-
}
|
|
102261
|
-
effects.exit(types_types.data);
|
|
102262
|
-
return nok(code);
|
|
102263
|
-
}
|
|
102264
|
-
function scanToLineEnd(code) {
|
|
102265
|
-
if (code === null || markdownLineEnding(code)) {
|
|
102266
|
-
effects.exit(types_types.data);
|
|
102267
|
-
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
102268
|
-
}
|
|
102269
|
-
if (!markdownSpace(code))
|
|
102270
|
-
lastNonSpace = code;
|
|
102271
|
-
effects.consume(code);
|
|
102272
|
-
return scanToLineEnd;
|
|
102273
|
-
}
|
|
102274
|
-
}
|
|
102275
102420
|
/**
|
|
102276
102421
|
* Micromark extension that tokenizes MDX-like components.
|
|
102277
102422
|
*
|
|
@@ -102325,6 +102470,7 @@ function mdxComponent() {
|
|
|
102325
102470
|
|
|
102326
102471
|
|
|
102327
102472
|
|
|
102473
|
+
|
|
102328
102474
|
|
|
102329
102475
|
const buildInlineMdProcessor = (safeMode) => {
|
|
102330
102476
|
// `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
|
|
@@ -102396,7 +102542,7 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
|
|
|
102396
102542
|
// Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
|
|
102397
102543
|
// structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
|
|
102398
102544
|
// `mdxishJsxToMdast`, both of which run later on raw html nodes.
|
|
102399
|
-
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]);
|
|
102400
102546
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
102401
102547
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
102402
102548
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
@@ -102755,15 +102901,22 @@ function safeDeindent(text) {
|
|
|
102755
102901
|
*/
|
|
102756
102902
|
const parseMdChildren = (value, safeMode) => {
|
|
102757
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);
|
|
102758
102908
|
return parsed.children || [];
|
|
102759
102909
|
};
|
|
102760
|
-
//
|
|
102761
|
-
// components among them
|
|
102762
|
-
|
|
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) => {
|
|
102763
102916
|
const siblingNodes = parseMdChildren(sibling, safeMode);
|
|
102764
102917
|
if (siblingNodes.length > 0) {
|
|
102765
102918
|
parent.children.splice(index + 1, 0, ...siblingNodes);
|
|
102766
|
-
|
|
102919
|
+
siblingNodes.forEach(siblingNode => promoted.add(siblingNode));
|
|
102767
102920
|
}
|
|
102768
102921
|
};
|
|
102769
102922
|
// Ends the position at `consumedLength` so the component doesn't claim trailing
|
|
@@ -102829,16 +102982,19 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
|
102829
102982
|
* The opening tag, content, and closing tag are all captured in one HTML node
|
|
102830
102983
|
* (guaranteed by the mdx-component tokenizer).
|
|
102831
102984
|
*/
|
|
102832
|
-
|
|
102985
|
+
function promoteComponentBlocks(tree, safeMode, source) {
|
|
102833
102986
|
const stack = [tree];
|
|
102834
|
-
const safeMode = !!opts.safeMode;
|
|
102835
|
-
const source = file?.value ? String(file.value) : null;
|
|
102836
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();
|
|
102837
102991
|
const processChildNode = (parent, index) => {
|
|
102838
102992
|
const node = parent.children[index];
|
|
102839
102993
|
if (!node)
|
|
102840
102994
|
return;
|
|
102841
|
-
|
|
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)) {
|
|
102842
102998
|
stack.push(node);
|
|
102843
102999
|
}
|
|
102844
103000
|
// Only html nodes can be an unparsed MDX component.
|
|
@@ -102893,7 +103049,7 @@ const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
102893
103049
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
102894
103050
|
const remainingContent = contentAfterTag.trim();
|
|
102895
103051
|
if (remainingContent) {
|
|
102896
|
-
parseSibling(
|
|
103052
|
+
parseSibling(parent, index, remainingContent, safeMode, promoted);
|
|
102897
103053
|
}
|
|
102898
103054
|
return;
|
|
102899
103055
|
}
|
|
@@ -102920,43 +103076,57 @@ const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
102920
103076
|
return;
|
|
102921
103077
|
// Lowercase tags are usually inline; unwrap a sole paragraph so their
|
|
102922
103078
|
// phrasing content isn't spuriously block-wrapped.
|
|
103079
|
+
let unwrappedSoleParagraph = false;
|
|
102923
103080
|
if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
|
|
102924
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);
|
|
102925
103092
|
}
|
|
102926
103093
|
const componentNode = createComponentNode({
|
|
102927
103094
|
tag,
|
|
102928
103095
|
attributes,
|
|
102929
103096
|
children: parsedChildren,
|
|
102930
103097
|
startPosition: node.position,
|
|
102931
|
-
|
|
102932
|
-
// offsets when available (the node's value strips blockquote/list
|
|
102933
|
-
// prefixes); otherwise fall back to the whole node position.
|
|
102934
|
-
endPosition: contentAfterClose
|
|
102935
|
-
? source
|
|
102936
|
-
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
102937
|
-
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length)
|
|
102938
|
-
: node.position,
|
|
103098
|
+
endPosition,
|
|
102939
103099
|
});
|
|
102940
103100
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
102941
|
-
//
|
|
102942
|
-
|
|
102943
|
-
|
|
102944
|
-
}
|
|
102945
|
-
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) {
|
|
102946
103104
|
stack.push(componentNode);
|
|
102947
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
|
+
}
|
|
102948
103112
|
}
|
|
102949
103113
|
};
|
|
102950
|
-
// 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.
|
|
102951
103117
|
while (stack.length) {
|
|
102952
103118
|
const parent = stack.pop();
|
|
102953
103119
|
if (parent?.children) {
|
|
102954
|
-
parent.children.
|
|
103120
|
+
for (let index = 0; index < parent.children.length; index += 1) {
|
|
102955
103121
|
processChildNode(parent, index);
|
|
102956
|
-
}
|
|
103122
|
+
}
|
|
102957
103123
|
}
|
|
102958
103124
|
}
|
|
102959
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);
|
|
102960
103130
|
};
|
|
102961
103131
|
/* harmony default export */ const mdx_blocks = (mdxishMdxComponentBlocks);
|
|
102962
103132
|
|
|
@@ -106555,6 +106725,7 @@ function loadComponents() {
|
|
|
106555
106725
|
|
|
106556
106726
|
|
|
106557
106727
|
|
|
106728
|
+
|
|
106558
106729
|
|
|
106559
106730
|
|
|
106560
106731
|
const defaultTransformers = [
|
|
@@ -106569,10 +106740,11 @@ const defaultTransformers = [
|
|
|
106569
106740
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
106570
106741
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
106571
106742
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
106572
|
-
* 3.
|
|
106573
|
-
* 4.
|
|
106574
|
-
* 5.
|
|
106575
|
-
* 6.
|
|
106743
|
+
* 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
|
|
106744
|
+
* 4. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
106745
|
+
* 5. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
106746
|
+
* 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
106747
|
+
* 7. Replace snake_case component names with parser-safe placeholders
|
|
106576
106748
|
*/
|
|
106577
106749
|
function preprocessContent(content, opts) {
|
|
106578
106750
|
const { knownComponents } = opts;
|
|
@@ -106580,6 +106752,10 @@ function preprocessContent(content, opts) {
|
|
|
106580
106752
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
106581
106753
|
let result = normalizeClosingTagWhitespace(content);
|
|
106582
106754
|
result = normalizeTableSeparator(result);
|
|
106755
|
+
// Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
|
|
106756
|
+
// would otherwise fragment it (children spill out as an indented code block once
|
|
106757
|
+
// a wrapper re-parses its deindented body — #1545).
|
|
106758
|
+
result = collapseForeignContentBlankLines(result);
|
|
106583
106759
|
result = terminateHtmlFlowBlocks(result);
|
|
106584
106760
|
result = closeSelfClosingHtmlTags(result);
|
|
106585
106761
|
result = normalizeCompactHeadings(result);
|
|
@@ -107303,6 +107479,8 @@ function restoreMagicBlocks(replaced, blocks) {
|
|
|
107303
107479
|
|
|
107304
107480
|
|
|
107305
107481
|
|
|
107482
|
+
|
|
107483
|
+
|
|
107306
107484
|
/**
|
|
107307
107485
|
* Removes Markdown and MDX comments.
|
|
107308
107486
|
*/
|
|
@@ -107313,10 +107491,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
107313
107491
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
107314
107492
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
107315
107493
|
// 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
|
|
107494
|
+
// 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
|
|
107316
107495
|
if (mdxish) {
|
|
107317
107496
|
processor
|
|
107318
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
107319
|
-
.data('fromMarkdownExtensions', [
|
|
107497
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
107498
|
+
.data('fromMarkdownExtensions', [
|
|
107499
|
+
htmlBlockComponentFromMarkdown(),
|
|
107500
|
+
jsxTableFromMarkdown(),
|
|
107501
|
+
mdxComponentFromMarkdown(),
|
|
107502
|
+
mdxExpressionFromMarkdown(),
|
|
107503
|
+
])
|
|
107320
107504
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
107321
107505
|
}
|
|
107322
107506
|
processor
|