@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.node.js
CHANGED
|
@@ -19523,8 +19523,8 @@ const Callout = (props) => {
|
|
|
19523
19523
|
|
|
19524
19524
|
|
|
19525
19525
|
|
|
19526
|
-
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, target, title }) => {
|
|
19527
|
-
const Tag = href ?
|
|
19526
|
+
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, LinkComponent = 'a', target, title, }) => {
|
|
19527
|
+
const Tag = href ? LinkComponent : 'div';
|
|
19528
19528
|
return (external_react_default().createElement(Tag, { className: `Card Card_${kind}`, href: href, target: target },
|
|
19529
19529
|
icon && external_react_default().createElement(components_Icon, { className: "Card-icon", icon: icon, iconColor: iconColor }),
|
|
19530
19530
|
external_react_default().createElement("div", { className: "Card-content" },
|
|
@@ -96525,6 +96525,21 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
96525
96525
|
'caption',
|
|
96526
96526
|
'colgroup',
|
|
96527
96527
|
]);
|
|
96528
|
+
/**
|
|
96529
|
+
* Tags whose bodies a later mdxish transform keeps raw and never re-parses as
|
|
96530
|
+
* markdown. Both layers depend on this property, not on the tags being figures:
|
|
96531
|
+
* the transformer treats them as non-promotable, and the tokenizer must not claim
|
|
96532
|
+
* markdown islands inside them (a claimed island would never be re-parsed and would
|
|
96533
|
+
* leak as literal text). Currently just the figure tags, whose bodies are owned by
|
|
96534
|
+
* the figure reassembly transform (`mdxishJsxToMdast`).
|
|
96535
|
+
*/
|
|
96536
|
+
const NON_REPARSED_BODY_TAGS = new Set(['figure', 'figcaption']);
|
|
96537
|
+
/**
|
|
96538
|
+
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
96539
|
+
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
96540
|
+
* set per the HTML spec, so transforms can treat these roots as opaque islands.
|
|
96541
|
+
*/
|
|
96542
|
+
const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
|
|
96528
96543
|
/**
|
|
96529
96544
|
* HTML void elements — elements that have no closing tag and no children.
|
|
96530
96545
|
*
|
|
@@ -119154,6 +119169,9 @@ function getComponentName(componentName, components) {
|
|
|
119154
119169
|
|
|
119155
119170
|
|
|
119156
119171
|
|
|
119172
|
+
// Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
|
|
119173
|
+
// untouched (their children are namespaced XML, not HTML tags/components).
|
|
119174
|
+
const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
|
|
119157
119175
|
function isElementContentNode(node) {
|
|
119158
119176
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
119159
119177
|
}
|
|
@@ -119329,6 +119347,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
119329
119347
|
visit(tree, 'element', (node, index, parent) => {
|
|
119330
119348
|
if (index === undefined || !parent)
|
|
119331
119349
|
return;
|
|
119350
|
+
// Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
|
|
119351
|
+
// aren't HTML tags or components, so the "unknown component" removal below would
|
|
119352
|
+
// otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
|
|
119353
|
+
// eslint-disable-next-line consistent-return
|
|
119354
|
+
if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
|
|
119355
|
+
return SKIP;
|
|
119332
119356
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
119333
119357
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
119334
119358
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -119640,6 +119664,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
119640
119664
|
return restoreCodeBlocks(result, protectedCode);
|
|
119641
119665
|
}
|
|
119642
119666
|
|
|
119667
|
+
;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
|
|
119668
|
+
|
|
119669
|
+
|
|
119670
|
+
// `svg|math`, from the canonical list so this stays in sync with the component transform.
|
|
119671
|
+
const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
|
|
119672
|
+
// A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
|
|
119673
|
+
// root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
|
|
119674
|
+
const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
|
|
119675
|
+
// Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
|
|
119676
|
+
// `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
|
|
119677
|
+
// chars (including newlines) are consumed one at a time.
|
|
119678
|
+
const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
|
|
119679
|
+
// One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
|
|
119680
|
+
// and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
|
|
119681
|
+
// `<svg-icon>` out. Group 1 is `/` only for a self-closer.
|
|
119682
|
+
const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
|
|
119683
|
+
// An HTML comment. Foreign markup inside one is inert and must not open an island.
|
|
119684
|
+
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
119685
|
+
const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
|
|
119686
|
+
/**
|
|
119687
|
+
* `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
|
|
119688
|
+
* lines are known-insignificant XML. Matching whole tags (not per-line open/close
|
|
119689
|
+
* counts) keeps multi-line openers and self-closers balanced, so a wrapped
|
|
119690
|
+
* `<svg … />` can't latch and swallow the doc (#1545).
|
|
119691
|
+
*
|
|
119692
|
+
* Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
|
|
119693
|
+
* closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
|
|
119694
|
+
* swallowing every blank line after it, without hiding the real islands that follow.
|
|
119695
|
+
*/
|
|
119696
|
+
function findForeignContentSpans(text) {
|
|
119697
|
+
const spans = [];
|
|
119698
|
+
// Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
|
|
119699
|
+
// must not open an island and latch onto the rest of the doc.
|
|
119700
|
+
const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
|
|
119701
|
+
// Offsets of openers still waiting for their closer, innermost last.
|
|
119702
|
+
const openOffsets = [];
|
|
119703
|
+
[...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
|
|
119704
|
+
const offset = match.index ?? 0;
|
|
119705
|
+
if (withinAny(comments, offset))
|
|
119706
|
+
return; // markup inside an HTML comment is inert
|
|
119707
|
+
if (match[1] === '/')
|
|
119708
|
+
return; // self-closing tag opens no island
|
|
119709
|
+
if (match[0].startsWith('</')) {
|
|
119710
|
+
const start = openOffsets.pop();
|
|
119711
|
+
if (start !== undefined)
|
|
119712
|
+
spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
|
|
119713
|
+
}
|
|
119714
|
+
else {
|
|
119715
|
+
openOffsets.push(offset);
|
|
119716
|
+
}
|
|
119717
|
+
});
|
|
119718
|
+
return spans;
|
|
119719
|
+
}
|
|
119720
|
+
/**
|
|
119721
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
119722
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
119723
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
119724
|
+
*/
|
|
119725
|
+
function collapseForeignContentBlankLines(content) {
|
|
119726
|
+
// Fast path: nothing to do when the doc has no foreign-content island.
|
|
119727
|
+
if (!ANY_ROOT_RE.test(content))
|
|
119728
|
+
return content;
|
|
119729
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
119730
|
+
const islands = findForeignContentSpans(protectedContent);
|
|
119731
|
+
// Drop blank lines inside an island; keep everything else verbatim.
|
|
119732
|
+
const lines = [];
|
|
119733
|
+
let lineStart = 0;
|
|
119734
|
+
protectedContent.split('\n').forEach(line => {
|
|
119735
|
+
if (line.trim().length > 0 || !withinAny(islands, lineStart))
|
|
119736
|
+
lines.push(line);
|
|
119737
|
+
lineStart += line.length + 1; // +1 for the '\n' that split() removed
|
|
119738
|
+
});
|
|
119739
|
+
return restoreCodeBlocks(lines.join('\n'), protectedCode);
|
|
119740
|
+
}
|
|
119741
|
+
|
|
119643
119742
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
119644
119743
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
119645
119744
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -121632,12 +121731,95 @@ function tokenizeMagicBlockText(effects, ok, nok) {
|
|
|
121632
121731
|
*/
|
|
121633
121732
|
|
|
121634
121733
|
|
|
121734
|
+
;// ./lib/micromark/mdx-component/continuation-checks.ts
|
|
121735
|
+
|
|
121736
|
+
|
|
121737
|
+
/**
|
|
121738
|
+
* Partial constructs the `mdxComponent` tokenizer runs via `effects.check` to
|
|
121739
|
+
* decide whether the next line continues the block. They live here (not in
|
|
121740
|
+
* `syntax.ts`) because they hold none of `createTokenize`'s closure state — each
|
|
121741
|
+
* is a self-contained, single-line lookahead.
|
|
121742
|
+
*/
|
|
121743
|
+
function continuation_checks_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
121744
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
121745
|
+
const self = this;
|
|
121746
|
+
return start;
|
|
121747
|
+
function start(code) {
|
|
121748
|
+
if (markdownLineEnding(code)) {
|
|
121749
|
+
effects.enter(types_types.lineEnding);
|
|
121750
|
+
effects.consume(code);
|
|
121751
|
+
effects.exit(types_types.lineEnding);
|
|
121752
|
+
return after;
|
|
121753
|
+
}
|
|
121754
|
+
return nok(code);
|
|
121755
|
+
}
|
|
121756
|
+
function after(code) {
|
|
121757
|
+
if (self.parser.lazy[self.now().line]) {
|
|
121758
|
+
return nok(code);
|
|
121759
|
+
}
|
|
121760
|
+
return ok(code);
|
|
121761
|
+
}
|
|
121762
|
+
}
|
|
121763
|
+
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
121764
|
+
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
121765
|
+
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
121766
|
+
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
121767
|
+
let lastNonSpace = null;
|
|
121768
|
+
return start;
|
|
121769
|
+
function start(code) {
|
|
121770
|
+
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
121771
|
+
effects.enter(types_types.data);
|
|
121772
|
+
effects.consume(code);
|
|
121773
|
+
return afterLessThan;
|
|
121774
|
+
}
|
|
121775
|
+
function afterLessThan(code) {
|
|
121776
|
+
if (code === codes.slash) {
|
|
121777
|
+
effects.consume(code);
|
|
121778
|
+
return afterSlash;
|
|
121779
|
+
}
|
|
121780
|
+
return afterSlash(code);
|
|
121781
|
+
}
|
|
121782
|
+
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
121783
|
+
function afterSlash(code) {
|
|
121784
|
+
if (asciiAlpha(code)) {
|
|
121785
|
+
lastNonSpace = code;
|
|
121786
|
+
effects.consume(code);
|
|
121787
|
+
return scanToLineEnd;
|
|
121788
|
+
}
|
|
121789
|
+
effects.exit(types_types.data);
|
|
121790
|
+
return nok(code);
|
|
121791
|
+
}
|
|
121792
|
+
function scanToLineEnd(code) {
|
|
121793
|
+
if (code === null || markdownLineEnding(code)) {
|
|
121794
|
+
effects.exit(types_types.data);
|
|
121795
|
+
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
121796
|
+
}
|
|
121797
|
+
if (!markdownSpace(code))
|
|
121798
|
+
lastNonSpace = code;
|
|
121799
|
+
effects.consume(code);
|
|
121800
|
+
return scanToLineEnd;
|
|
121801
|
+
}
|
|
121802
|
+
}
|
|
121803
|
+
// A line ending whose next line isn't a lazy paragraph continuation. Checked so a
|
|
121804
|
+
// component body's blank/continuation lines aren't stolen by an interrupted paragraph.
|
|
121805
|
+
const continuation_checks_nonLazyContinuationStart = {
|
|
121806
|
+
tokenize: continuation_checks_tokenizeNonLazyContinuationStart,
|
|
121807
|
+
partial: true,
|
|
121808
|
+
};
|
|
121809
|
+
// Lookahead for `plainClaimLineStart`: is this line markup-only, or a paragraph
|
|
121810
|
+
// that merely starts with a tag? Run via `effects.check` so it never consumes.
|
|
121811
|
+
const markupOnlyContinuation = {
|
|
121812
|
+
tokenize: tokenizeMarkupOnlyContinuation,
|
|
121813
|
+
partial: true,
|
|
121814
|
+
};
|
|
121815
|
+
|
|
121635
121816
|
;// ./lib/micromark/mdx-component/syntax.ts
|
|
121636
121817
|
|
|
121637
121818
|
|
|
121638
121819
|
|
|
121639
121820
|
|
|
121640
121821
|
|
|
121822
|
+
|
|
121641
121823
|
// Raw tags (type-1: pre/script/style/textarea) and block tags (type-6: div,
|
|
121642
121824
|
// section, …) always start a block, so they stay flow even with trailing
|
|
121643
121825
|
// content. Other lowercase tags (i, span, …) follow the type-7 rule and only
|
|
@@ -121647,16 +121829,12 @@ const htmlFlowTagNames = new Set([...htmlRawNames, ...htmlBlockNames]);
|
|
|
121647
121829
|
// blank lines between nested JSX siblings don't fragment the block. Excludes table
|
|
121648
121830
|
// tags (mdxishTables owns their blank lines) and voids (never close).
|
|
121649
121831
|
const plainBlockClaimTagNames = new Set([...htmlBlockNames].filter(tag => !HTML_TABLE_STRUCTURE_TAGS.has(tag) && !HTML_VOID_ELEMENTS.has(tag)));
|
|
121650
|
-
|
|
121651
|
-
|
|
121652
|
-
|
|
121653
|
-
|
|
121654
|
-
|
|
121655
|
-
|
|
121656
|
-
const markupOnlyContinuation = {
|
|
121657
|
-
tokenize: tokenizeMarkupOnlyContinuation,
|
|
121658
|
-
partial: true,
|
|
121659
|
-
};
|
|
121832
|
+
// Both are 4 columns per CommonMark, but they mean different things: a tab advances
|
|
121833
|
+
// to the next multiple of TAB_STOP_WIDTH, and INDENTED_CODE_MIN_COLUMNS is the depth
|
|
121834
|
+
// at which a line would fragment into indented code. Named separately so the two
|
|
121835
|
+
// concepts don't read as one incidental literal.
|
|
121836
|
+
const TAB_STOP_WIDTH = 4;
|
|
121837
|
+
const INDENTED_CODE_MIN_COLUMNS = 4;
|
|
121660
121838
|
function resolveToMdxComponent(events) {
|
|
121661
121839
|
let index = events.length;
|
|
121662
121840
|
while (index > 0) {
|
|
@@ -121715,6 +121893,18 @@ function createTokenize(mode) {
|
|
|
121715
121893
|
// `plainClaimLineStart`: after a blank line it may only continue on a tag line.
|
|
121716
121894
|
let isPlainBlockClaim = false;
|
|
121717
121895
|
let pendingBlankLine = false;
|
|
121896
|
+
// Leading indent columns of the current plain-claim line, reset per line; ≥4 is
|
|
121897
|
+
// where CommonMark would fragment the island as indented code. Tabs advance to the
|
|
121898
|
+
// next 4-column stop — the same rule `expandIndentToColumns`
|
|
121899
|
+
// (processor/transform/mdxish/indentation.ts) applies, kept in sync by hand since
|
|
121900
|
+
// this side works on a `Code` stream, not a string. NB: do NOT swap this for
|
|
121901
|
+
// `self.now().column`; micromark bumps the point column by 1 per `horizontalTab`
|
|
121902
|
+
// code (the trailing `virtualSpace` codes don't move it), so it measures a tab as
|
|
121903
|
+
// 1 column, reviving the tab-under-measurement bug this math exists to avoid.
|
|
121904
|
+
let plainClaimIndentColumns = 0;
|
|
121905
|
+
// True once a non-blank line follows the opener: a deep island below it is nested
|
|
121906
|
+
// (cosmetic indent), not top-of-body indented code.
|
|
121907
|
+
let sawPlainBlockBodyContent = false;
|
|
121718
121908
|
// Code span tracking
|
|
121719
121909
|
let codeSpanOpenSize = 0;
|
|
121720
121910
|
let codeSpanCloseSize = 0;
|
|
@@ -122014,7 +122204,7 @@ function createTokenize(mode) {
|
|
|
122014
122204
|
}
|
|
122015
122205
|
// Continuation for multi-line opening tags
|
|
122016
122206
|
function openTagContinuationStart(code) {
|
|
122017
|
-
return effects.check(
|
|
122207
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, openTagContinuationNonLazy, continuationAfter)(code);
|
|
122018
122208
|
}
|
|
122019
122209
|
function openTagContinuationNonLazy(code) {
|
|
122020
122210
|
sawLineEnding = true;
|
|
@@ -122059,6 +122249,9 @@ function createTokenize(mode) {
|
|
|
122059
122249
|
}
|
|
122060
122250
|
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
122061
122251
|
openerLineHasContent = true;
|
|
122252
|
+
// Continuation content marks a later deep island as nested, not indented code.
|
|
122253
|
+
if (!onOpenerLine)
|
|
122254
|
+
sawPlainBlockBodyContent = true;
|
|
122062
122255
|
}
|
|
122063
122256
|
if (code === codes.backslash) {
|
|
122064
122257
|
effects.consume(code);
|
|
@@ -122139,7 +122332,7 @@ function createTokenize(mode) {
|
|
|
122139
122332
|
return inFencedCode;
|
|
122140
122333
|
}
|
|
122141
122334
|
function fencedCodeContinuationStart(code) {
|
|
122142
|
-
return effects.check(
|
|
122335
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, fencedCodeContinuationNonLazy, continuationAfter)(code);
|
|
122143
122336
|
}
|
|
122144
122337
|
function fencedCodeContinuationNonLazy(code) {
|
|
122145
122338
|
sawLineEnding = true;
|
|
@@ -122347,7 +122540,7 @@ function createTokenize(mode) {
|
|
|
122347
122540
|
}
|
|
122348
122541
|
// ── Body continuation (line endings) ───────────────────────────────────
|
|
122349
122542
|
function bodyContinuationStart(code) {
|
|
122350
|
-
return effects.check(
|
|
122543
|
+
return effects.check(continuation_checks_nonLazyContinuationStart, bodyContinuationNonLazy, continuationAfter)(code);
|
|
122351
122544
|
}
|
|
122352
122545
|
function bodyContinuationNonLazy(code) {
|
|
122353
122546
|
sawLineEnding = true;
|
|
@@ -122373,8 +122566,10 @@ function createTokenize(mode) {
|
|
|
122373
122566
|
return inBodyBraceString(code);
|
|
122374
122567
|
return inBodyBraceExpr(code);
|
|
122375
122568
|
}
|
|
122376
|
-
if (isPlainBlockClaim)
|
|
122569
|
+
if (isPlainBlockClaim) {
|
|
122570
|
+
plainClaimIndentColumns = 0;
|
|
122377
122571
|
return plainClaimLineStart(code);
|
|
122572
|
+
}
|
|
122378
122573
|
return bodyLineStart(code);
|
|
122379
122574
|
}
|
|
122380
122575
|
// Dispatch a non-blank continuation line: fenced code at line start, else body.
|
|
@@ -122404,6 +122599,8 @@ function createTokenize(mode) {
|
|
|
122404
122599
|
function plainClaimLineStart(code) {
|
|
122405
122600
|
// Leading whitespace only → treat as a blank line, matching CommonMark.
|
|
122406
122601
|
if (code === codes.space || code === codes.horizontalTab) {
|
|
122602
|
+
plainClaimIndentColumns +=
|
|
122603
|
+
code === codes.horizontalTab ? TAB_STOP_WIDTH - (plainClaimIndentColumns % TAB_STOP_WIDTH) : 1;
|
|
122407
122604
|
effects.consume(code);
|
|
122408
122605
|
return plainClaimLineStart;
|
|
122409
122606
|
}
|
|
@@ -122412,10 +122609,18 @@ function createTokenize(mode) {
|
|
|
122412
122609
|
effects.exit('mdxComponentData');
|
|
122413
122610
|
return bodyContinuationStart(code);
|
|
122414
122611
|
}
|
|
122415
|
-
// Across a blank line the block only continues onto a markup-only line; a
|
|
122416
|
-
// paragraph that merely starts with a tag must fall back so its markdown
|
|
122417
|
-
// parses and rehype-raw re-nests it into the wrapper.
|
|
122418
122612
|
if (pendingBlankLine) {
|
|
122613
|
+
// A 4+ col island nested under other tags is cosmetic nesting indent, not code:
|
|
122614
|
+
// keep claiming so promotion dedents + re-parses it as markdown (RM-17560).
|
|
122615
|
+
// Tags whose bodies stay raw are excluded — a claimed island there would never
|
|
122616
|
+
// be re-parsed and would leak as literal text.
|
|
122617
|
+
if (plainClaimIndentColumns >= INDENTED_CODE_MIN_COLUMNS &&
|
|
122618
|
+
sawPlainBlockBodyContent &&
|
|
122619
|
+
!NON_REPARSED_BODY_TAGS.has(tagName)) {
|
|
122620
|
+
return plainClaimContinue(code);
|
|
122621
|
+
}
|
|
122622
|
+
// Otherwise only a markup-only tag line continues; markdown/prose falls back to
|
|
122623
|
+
// CommonMark so it parses and rehype-raw re-nests it into the wrapper.
|
|
122419
122624
|
if (code !== codes.lessThan)
|
|
122420
122625
|
return nok(code);
|
|
122421
122626
|
return effects.check(markupOnlyContinuation, plainClaimContinue, nok)(code);
|
|
@@ -122436,66 +122641,6 @@ function createTokenize(mode) {
|
|
|
122436
122641
|
}
|
|
122437
122642
|
};
|
|
122438
122643
|
}
|
|
122439
|
-
function mdx_component_syntax_tokenizeNonLazyContinuationStart(effects, ok, nok) {
|
|
122440
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
122441
|
-
const self = this;
|
|
122442
|
-
return start;
|
|
122443
|
-
function start(code) {
|
|
122444
|
-
if (markdownLineEnding(code)) {
|
|
122445
|
-
effects.enter(types_types.lineEnding);
|
|
122446
|
-
effects.consume(code);
|
|
122447
|
-
effects.exit(types_types.lineEnding);
|
|
122448
|
-
return after;
|
|
122449
|
-
}
|
|
122450
|
-
return nok(code);
|
|
122451
|
-
}
|
|
122452
|
-
function after(code) {
|
|
122453
|
-
if (self.parser.lazy[self.now().line]) {
|
|
122454
|
-
return nok(code);
|
|
122455
|
-
}
|
|
122456
|
-
return ok(code);
|
|
122457
|
-
}
|
|
122458
|
-
}
|
|
122459
|
-
// A markup-only line opens with a tag (`<x`/`</x`) and ends (ignoring trailing
|
|
122460
|
-
// spaces) at a `>`. That distinguishes a structural continuation like
|
|
122461
|
-
// `<span>b</span></div>` from a paragraph like `<b>Note:</b> read *this*`.
|
|
122462
|
-
function tokenizeMarkupOnlyContinuation(effects, ok, nok) {
|
|
122463
|
-
let lastNonSpace = null;
|
|
122464
|
-
return start;
|
|
122465
|
-
function start(code) {
|
|
122466
|
-
// Caller guarantees we are at `<` at the (already de-indented) line start.
|
|
122467
|
-
effects.enter(types_types.data);
|
|
122468
|
-
effects.consume(code);
|
|
122469
|
-
return afterLessThan;
|
|
122470
|
-
}
|
|
122471
|
-
function afterLessThan(code) {
|
|
122472
|
-
if (code === codes.slash) {
|
|
122473
|
-
effects.consume(code);
|
|
122474
|
-
return afterSlash;
|
|
122475
|
-
}
|
|
122476
|
-
return afterSlash(code);
|
|
122477
|
-
}
|
|
122478
|
-
// The `<` (or `</`) must introduce a real tag, not a stray `<` in prose.
|
|
122479
|
-
function afterSlash(code) {
|
|
122480
|
-
if (asciiAlpha(code)) {
|
|
122481
|
-
lastNonSpace = code;
|
|
122482
|
-
effects.consume(code);
|
|
122483
|
-
return scanToLineEnd;
|
|
122484
|
-
}
|
|
122485
|
-
effects.exit(types_types.data);
|
|
122486
|
-
return nok(code);
|
|
122487
|
-
}
|
|
122488
|
-
function scanToLineEnd(code) {
|
|
122489
|
-
if (code === null || markdownLineEnding(code)) {
|
|
122490
|
-
effects.exit(types_types.data);
|
|
122491
|
-
return lastNonSpace === codes.greaterThan ? ok(code) : nok(code);
|
|
122492
|
-
}
|
|
122493
|
-
if (!markdownSpace(code))
|
|
122494
|
-
lastNonSpace = code;
|
|
122495
|
-
effects.consume(code);
|
|
122496
|
-
return scanToLineEnd;
|
|
122497
|
-
}
|
|
122498
|
-
}
|
|
122499
122644
|
/**
|
|
122500
122645
|
* Micromark extension that tokenizes MDX-like components.
|
|
122501
122646
|
*
|
|
@@ -122549,6 +122694,7 @@ function mdxComponent() {
|
|
|
122549
122694
|
|
|
122550
122695
|
|
|
122551
122696
|
|
|
122697
|
+
|
|
122552
122698
|
|
|
122553
122699
|
const buildInlineMdProcessor = (safeMode) => {
|
|
122554
122700
|
// `jsxTable` must be present so a `<Table>`/`<table>` nested in a component
|
|
@@ -122620,7 +122766,7 @@ const toMdxJsxTextElement = (name, attributes, children, position) => ({
|
|
|
122620
122766
|
// Raw-body tags (pre/script/style/textarea) must stay byte-exact; table
|
|
122621
122767
|
// structure (`table` + `tableTags`) is owned by `mdxishTables` and figures by
|
|
122622
122768
|
// `mdxishJsxToMdast`, both of which run later on raw html nodes.
|
|
122623
|
-
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table',
|
|
122769
|
+
const NON_PROMOTABLE_PLAIN_TAGS = new Set([...htmlRawNames, ...tableTags, 'table', ...NON_REPARSED_BODY_TAGS]);
|
|
122624
122770
|
const NESTED_TABLE_RE = /<table[\s>]/i;
|
|
122625
122771
|
const isMarkdownPromotableHtmlTag = (tag) => !NON_PROMOTABLE_PLAIN_TAGS.has(tag);
|
|
122626
122772
|
// Expression nodes count as plain so `<div>{1+1}</div>` keeps its current
|
|
@@ -122979,15 +123125,22 @@ function safeDeindent(text) {
|
|
|
122979
123125
|
*/
|
|
122980
123126
|
const parseMdChildren = (value, safeMode) => {
|
|
122981
123127
|
const parsed = getInlineMdProcessor({ safeMode }).parse(terminateHtmlFlowBlocks(safeDeindent(value).trim()));
|
|
123128
|
+
// Promote nested wrappers bottom-up so an outer wrapper sees markdown buried in a
|
|
123129
|
+
// child claimed whole (e.g. `<li>` in `<ol>`) before its containsMarkdownConstruct check (RM-17560).
|
|
123130
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define -- mutually recursive; hoisted decl, safe at runtime
|
|
123131
|
+
promoteComponentBlocks(parsed, safeMode, null);
|
|
122982
123132
|
return parsed.children || [];
|
|
122983
123133
|
};
|
|
122984
|
-
//
|
|
122985
|
-
// components among them
|
|
122986
|
-
|
|
123134
|
+
// Splices trailing content in as sibling nodes. parseMdChildren has already
|
|
123135
|
+
// promoted any components nested among them (bottom-up); the main loop's
|
|
123136
|
+
// index-based walk then reaches these spliced siblings and the original children
|
|
123137
|
+
// they shift down, so no parent re-queue is needed. Each spliced subtree is marked
|
|
123138
|
+
// `promoted` so the walk doesn't redundantly re-descend into it (its html is gone).
|
|
123139
|
+
const parseSibling = (parent, index, sibling, safeMode, promoted) => {
|
|
122987
123140
|
const siblingNodes = parseMdChildren(sibling, safeMode);
|
|
122988
123141
|
if (siblingNodes.length > 0) {
|
|
122989
123142
|
parent.children.splice(index + 1, 0, ...siblingNodes);
|
|
122990
|
-
|
|
123143
|
+
siblingNodes.forEach(siblingNode => promoted.add(siblingNode));
|
|
122991
123144
|
}
|
|
122992
123145
|
};
|
|
122993
123146
|
// Ends the position at `consumedLength` so the component doesn't claim trailing
|
|
@@ -123053,16 +123206,19 @@ const substituteNodeWithMdxNode = (parent, index, mdxNode) => {
|
|
|
123053
123206
|
* The opening tag, content, and closing tag are all captured in one HTML node
|
|
123054
123207
|
* (guaranteed by the mdx-component tokenizer).
|
|
123055
123208
|
*/
|
|
123056
|
-
|
|
123209
|
+
function promoteComponentBlocks(tree, safeMode, source) {
|
|
123057
123210
|
const stack = [tree];
|
|
123058
|
-
const safeMode = !!opts.safeMode;
|
|
123059
|
-
const source = file?.value ? String(file.value) : null;
|
|
123060
123211
|
const parseOpts = { preserveExpressionsAsText: safeMode };
|
|
123212
|
+
// Subtrees a nested parseMdChildren already promoted wholesale (spliced siblings):
|
|
123213
|
+
// re-descending them finds no html to promote, so skip them.
|
|
123214
|
+
const promoted = new WeakSet();
|
|
123061
123215
|
const processChildNode = (parent, index) => {
|
|
123062
123216
|
const node = parent.children[index];
|
|
123063
123217
|
if (!node)
|
|
123064
123218
|
return;
|
|
123065
|
-
|
|
123219
|
+
// Descend into container nodes (lists, blockquotes, …) so their html children
|
|
123220
|
+
// are reached — unless the subtree was already promoted upstream.
|
|
123221
|
+
if ('children' in node && Array.isArray(node.children) && !promoted.has(node)) {
|
|
123066
123222
|
stack.push(node);
|
|
123067
123223
|
}
|
|
123068
123224
|
// Only html nodes can be an unparsed MDX component.
|
|
@@ -123117,7 +123273,7 @@ const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
123117
123273
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
123118
123274
|
const remainingContent = contentAfterTag.trim();
|
|
123119
123275
|
if (remainingContent) {
|
|
123120
|
-
parseSibling(
|
|
123276
|
+
parseSibling(parent, index, remainingContent, safeMode, promoted);
|
|
123121
123277
|
}
|
|
123122
123278
|
return;
|
|
123123
123279
|
}
|
|
@@ -123144,43 +123300,57 @@ const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
|
123144
123300
|
return;
|
|
123145
123301
|
// Lowercase tags are usually inline; unwrap a sole paragraph so their
|
|
123146
123302
|
// phrasing content isn't spuriously block-wrapped.
|
|
123303
|
+
let unwrappedSoleParagraph = false;
|
|
123147
123304
|
if (!isPascal && parsedChildren.length === 1 && parsedChildren[0].type === 'paragraph') {
|
|
123148
123305
|
parsedChildren = parsedChildren[0].children;
|
|
123306
|
+
unwrappedSoleParagraph = true;
|
|
123307
|
+
}
|
|
123308
|
+
// Without trailing content the whole node position is correct. With it, end
|
|
123309
|
+
// precisely at the closing tag — preferring source offsets when available (the
|
|
123310
|
+
// node's value strips blockquote/list prefixes), else the consumed span.
|
|
123311
|
+
let endPosition = node.position;
|
|
123312
|
+
if (contentAfterClose) {
|
|
123313
|
+
endPosition = source
|
|
123314
|
+
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
123315
|
+
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length);
|
|
123149
123316
|
}
|
|
123150
123317
|
const componentNode = createComponentNode({
|
|
123151
123318
|
tag,
|
|
123152
123319
|
attributes,
|
|
123153
123320
|
children: parsedChildren,
|
|
123154
123321
|
startPosition: node.position,
|
|
123155
|
-
|
|
123156
|
-
// offsets when available (the node's value strips blockquote/list
|
|
123157
|
-
// prefixes); otherwise fall back to the whole node position.
|
|
123158
|
-
endPosition: contentAfterClose
|
|
123159
|
-
? source
|
|
123160
|
-
? positionEndingAtClosingTagInSource(node.position, closingTagStr, source)
|
|
123161
|
-
: positionEndingAtConsumed(node.position, value, leadingWhitespace + openingTagEnd + closingTagIndex + closingTagStr.length)
|
|
123162
|
-
: node.position,
|
|
123322
|
+
endPosition,
|
|
123163
123323
|
});
|
|
123164
123324
|
substituteNodeWithMdxNode(parent, index, componentNode);
|
|
123165
|
-
//
|
|
123166
|
-
|
|
123167
|
-
|
|
123168
|
-
}
|
|
123169
|
-
else if (componentNode.children.length > 0) {
|
|
123325
|
+
// The unwrap reparented the children out of their paragraph, so re-walk them
|
|
123326
|
+
// since the children HTML may contain promotable syntax (e.g. `{…}`-attr tags)
|
|
123327
|
+
if (unwrappedSoleParagraph) {
|
|
123170
123328
|
stack.push(componentNode);
|
|
123171
123329
|
}
|
|
123330
|
+
// Trailing content after the close becomes siblings; parseMdChildren has
|
|
123331
|
+
// already promoted any components nested inside both sides, so the promoted
|
|
123332
|
+
// subtree itself needs no re-queue.
|
|
123333
|
+
if (contentAfterClose) {
|
|
123334
|
+
parseSibling(parent, index, contentAfterClose, safeMode, promoted);
|
|
123335
|
+
}
|
|
123172
123336
|
}
|
|
123173
123337
|
};
|
|
123174
|
-
// Depth-first so nodes keep their source order.
|
|
123338
|
+
// Depth-first so nodes keep their source order. Index-based (not forEach) and
|
|
123339
|
+
// re-reading length each step: parseSibling splices siblings in mid-iteration, and
|
|
123340
|
+
// those — plus the original children they shift down — must all stay eligible.
|
|
123175
123341
|
while (stack.length) {
|
|
123176
123342
|
const parent = stack.pop();
|
|
123177
123343
|
if (parent?.children) {
|
|
123178
|
-
parent.children.
|
|
123344
|
+
for (let index = 0; index < parent.children.length; index += 1) {
|
|
123179
123345
|
processChildNode(parent, index);
|
|
123180
|
-
}
|
|
123346
|
+
}
|
|
123181
123347
|
}
|
|
123182
123348
|
}
|
|
123183
123349
|
return tree;
|
|
123350
|
+
}
|
|
123351
|
+
const mdxishMdxComponentBlocks = (opts = {}) => (tree, file) => {
|
|
123352
|
+
const source = file?.value ? String(file.value) : null;
|
|
123353
|
+
return promoteComponentBlocks(tree, !!opts.safeMode, source);
|
|
123184
123354
|
};
|
|
123185
123355
|
/* harmony default export */ const mdx_blocks = (mdxishMdxComponentBlocks);
|
|
123186
123356
|
|
|
@@ -126779,6 +126949,7 @@ function loadComponents() {
|
|
|
126779
126949
|
|
|
126780
126950
|
|
|
126781
126951
|
|
|
126952
|
+
|
|
126782
126953
|
|
|
126783
126954
|
|
|
126784
126955
|
const defaultTransformers = [
|
|
@@ -126793,10 +126964,11 @@ const defaultTransformers = [
|
|
|
126793
126964
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
126794
126965
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
126795
126966
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
126796
|
-
* 3.
|
|
126797
|
-
* 4.
|
|
126798
|
-
* 5.
|
|
126799
|
-
* 6.
|
|
126967
|
+
* 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
|
|
126968
|
+
* 4. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
126969
|
+
* 5. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
126970
|
+
* 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
126971
|
+
* 7. Replace snake_case component names with parser-safe placeholders
|
|
126800
126972
|
*/
|
|
126801
126973
|
function preprocessContent(content, opts) {
|
|
126802
126974
|
const { knownComponents } = opts;
|
|
@@ -126804,6 +126976,10 @@ function preprocessContent(content, opts) {
|
|
|
126804
126976
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
126805
126977
|
let result = normalizeClosingTagWhitespace(content);
|
|
126806
126978
|
result = normalizeTableSeparator(result);
|
|
126979
|
+
// Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
|
|
126980
|
+
// would otherwise fragment it (children spill out as an indented code block once
|
|
126981
|
+
// a wrapper re-parses its deindented body — #1545).
|
|
126982
|
+
result = collapseForeignContentBlankLines(result);
|
|
126807
126983
|
result = terminateHtmlFlowBlocks(result);
|
|
126808
126984
|
result = closeSelfClosingHtmlTags(result);
|
|
126809
126985
|
result = normalizeCompactHeadings(result);
|
|
@@ -127527,6 +127703,8 @@ function restoreMagicBlocks(replaced, blocks) {
|
|
|
127527
127703
|
|
|
127528
127704
|
|
|
127529
127705
|
|
|
127706
|
+
|
|
127707
|
+
|
|
127530
127708
|
/**
|
|
127531
127709
|
* Removes Markdown and MDX comments.
|
|
127532
127710
|
*/
|
|
@@ -127537,10 +127715,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
127537
127715
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
127538
127716
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
127539
127717
|
// 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
|
|
127718
|
+
// 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
|
|
127540
127719
|
if (mdxish) {
|
|
127541
127720
|
processor
|
|
127542
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
127543
|
-
.data('fromMarkdownExtensions', [
|
|
127721
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
127722
|
+
.data('fromMarkdownExtensions', [
|
|
127723
|
+
htmlBlockComponentFromMarkdown(),
|
|
127724
|
+
jsxTableFromMarkdown(),
|
|
127725
|
+
mdxComponentFromMarkdown(),
|
|
127726
|
+
mdxExpressionFromMarkdown(),
|
|
127727
|
+
])
|
|
127544
127728
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
127545
127729
|
}
|
|
127546
127730
|
processor
|