@readme/markdown 14.12.1 → 14.13.0
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/Cards/index.tsx +14 -2
- package/dist/components/Cards/index.d.ts +2 -1
- package/dist/main.js +114 -10
- package/dist/main.node.js +112 -8
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/collapse-foreign-content-blank-lines.d.ts +6 -0
- package/dist/render-fixture.node.js +112 -8
- package/dist/render-fixture.node.js.map +1 -1
- package/dist/utils/common-html-words.d.ts +6 -0
- package/package.json +1 -1
|
@@ -6,6 +6,8 @@ import './style.scss';
|
|
|
6
6
|
|
|
7
7
|
interface CardProps
|
|
8
8
|
extends React.PropsWithChildren<{
|
|
9
|
+
// Optional link component wrapper so that the link can be formatted & processed by the parent
|
|
10
|
+
LinkComponent?: React.ElementType;
|
|
9
11
|
badge?: string;
|
|
10
12
|
href?: string;
|
|
11
13
|
icon?: string;
|
|
@@ -15,8 +17,18 @@ interface CardProps
|
|
|
15
17
|
title?: string;
|
|
16
18
|
}> {}
|
|
17
19
|
|
|
18
|
-
export const Card = ({
|
|
19
|
-
|
|
20
|
+
export const Card = ({
|
|
21
|
+
badge,
|
|
22
|
+
children,
|
|
23
|
+
href,
|
|
24
|
+
kind = 'card',
|
|
25
|
+
icon,
|
|
26
|
+
iconColor,
|
|
27
|
+
LinkComponent = 'a',
|
|
28
|
+
target,
|
|
29
|
+
title,
|
|
30
|
+
}: CardProps) => {
|
|
31
|
+
const Tag = href ? LinkComponent : 'div';
|
|
20
32
|
|
|
21
33
|
return (
|
|
22
34
|
<Tag className={`Card Card_${kind}`} href={href} target={target}>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import './style.scss';
|
|
3
3
|
interface CardProps extends React.PropsWithChildren<{
|
|
4
|
+
LinkComponent?: React.ElementType;
|
|
4
5
|
badge?: string;
|
|
5
6
|
href?: string;
|
|
6
7
|
icon?: string;
|
|
@@ -10,7 +11,7 @@ interface CardProps extends React.PropsWithChildren<{
|
|
|
10
11
|
title?: string;
|
|
11
12
|
}> {
|
|
12
13
|
}
|
|
13
|
-
export declare const Card: ({ badge, children, href, kind, icon, iconColor, target, title }: CardProps) => React.JSX.Element;
|
|
14
|
+
export declare const Card: ({ badge, children, href, kind, icon, iconColor, LinkComponent, target, title, }: CardProps) => React.JSX.Element;
|
|
14
15
|
interface CardsGridProps extends React.PropsWithChildren<{
|
|
15
16
|
cardWidth?: string;
|
|
16
17
|
columns?: number | string;
|
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,12 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
76301
76301
|
'caption',
|
|
76302
76302
|
'colgroup',
|
|
76303
76303
|
]);
|
|
76304
|
+
/**
|
|
76305
|
+
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
76306
|
+
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
76307
|
+
* set per the HTML spec, so transforms can treat these roots as opaque islands.
|
|
76308
|
+
*/
|
|
76309
|
+
const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
|
|
76304
76310
|
/**
|
|
76305
76311
|
* HTML void elements — elements that have no closing tag and no children.
|
|
76306
76312
|
*
|
|
@@ -98930,6 +98936,9 @@ function getComponentName(componentName, components) {
|
|
|
98930
98936
|
|
|
98931
98937
|
|
|
98932
98938
|
|
|
98939
|
+
// Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
|
|
98940
|
+
// untouched (their children are namespaced XML, not HTML tags/components).
|
|
98941
|
+
const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
|
|
98933
98942
|
function isElementContentNode(node) {
|
|
98934
98943
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
98935
98944
|
}
|
|
@@ -99105,6 +99114,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
99105
99114
|
visit(tree, 'element', (node, index, parent) => {
|
|
99106
99115
|
if (index === undefined || !parent)
|
|
99107
99116
|
return;
|
|
99117
|
+
// Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
|
|
99118
|
+
// aren't HTML tags or components, so the "unknown component" removal below would
|
|
99119
|
+
// otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
|
|
99120
|
+
// eslint-disable-next-line consistent-return
|
|
99121
|
+
if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
|
|
99122
|
+
return SKIP;
|
|
99108
99123
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
99109
99124
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
99110
99125
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -99416,6 +99431,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
99416
99431
|
return restoreCodeBlocks(result, protectedCode);
|
|
99417
99432
|
}
|
|
99418
99433
|
|
|
99434
|
+
;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
|
|
99435
|
+
|
|
99436
|
+
|
|
99437
|
+
// `svg|math`, from the canonical list so this stays in sync with the component transform.
|
|
99438
|
+
const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
|
|
99439
|
+
// A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
|
|
99440
|
+
// root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
|
|
99441
|
+
const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
|
|
99442
|
+
// Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
|
|
99443
|
+
// `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
|
|
99444
|
+
// chars (including newlines) are consumed one at a time.
|
|
99445
|
+
const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
|
|
99446
|
+
// One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
|
|
99447
|
+
// and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
|
|
99448
|
+
// `<svg-icon>` out. Group 1 is `/` only for a self-closer.
|
|
99449
|
+
const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
|
|
99450
|
+
// An HTML comment. Foreign markup inside one is inert and must not open an island.
|
|
99451
|
+
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
99452
|
+
const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
|
|
99453
|
+
/**
|
|
99454
|
+
* `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
|
|
99455
|
+
* lines are known-insignificant XML. Matching whole tags (not per-line open/close
|
|
99456
|
+
* counts) keeps multi-line openers and self-closers balanced, so a wrapped
|
|
99457
|
+
* `<svg … />` can't latch and swallow the doc (#1545).
|
|
99458
|
+
*
|
|
99459
|
+
* Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
|
|
99460
|
+
* closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
|
|
99461
|
+
* swallowing every blank line after it, without hiding the real islands that follow.
|
|
99462
|
+
*/
|
|
99463
|
+
function findForeignContentSpans(text) {
|
|
99464
|
+
const spans = [];
|
|
99465
|
+
// Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
|
|
99466
|
+
// must not open an island and latch onto the rest of the doc.
|
|
99467
|
+
const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
|
|
99468
|
+
// Offsets of openers still waiting for their closer, innermost last.
|
|
99469
|
+
const openOffsets = [];
|
|
99470
|
+
[...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
|
|
99471
|
+
const offset = match.index ?? 0;
|
|
99472
|
+
if (withinAny(comments, offset))
|
|
99473
|
+
return; // markup inside an HTML comment is inert
|
|
99474
|
+
if (match[1] === '/')
|
|
99475
|
+
return; // self-closing tag opens no island
|
|
99476
|
+
if (match[0].startsWith('</')) {
|
|
99477
|
+
const start = openOffsets.pop();
|
|
99478
|
+
if (start !== undefined)
|
|
99479
|
+
spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
|
|
99480
|
+
}
|
|
99481
|
+
else {
|
|
99482
|
+
openOffsets.push(offset);
|
|
99483
|
+
}
|
|
99484
|
+
});
|
|
99485
|
+
return spans;
|
|
99486
|
+
}
|
|
99487
|
+
/**
|
|
99488
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
99489
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
99490
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
99491
|
+
*/
|
|
99492
|
+
function collapseForeignContentBlankLines(content) {
|
|
99493
|
+
// Fast path: nothing to do when the doc has no foreign-content island.
|
|
99494
|
+
if (!ANY_ROOT_RE.test(content))
|
|
99495
|
+
return content;
|
|
99496
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
99497
|
+
const islands = findForeignContentSpans(protectedContent);
|
|
99498
|
+
// Drop blank lines inside an island; keep everything else verbatim.
|
|
99499
|
+
const lines = [];
|
|
99500
|
+
let lineStart = 0;
|
|
99501
|
+
protectedContent.split('\n').forEach(line => {
|
|
99502
|
+
if (line.trim().length > 0 || !withinAny(islands, lineStart))
|
|
99503
|
+
lines.push(line);
|
|
99504
|
+
lineStart += line.length + 1; // +1 for the '\n' that split() removed
|
|
99505
|
+
});
|
|
99506
|
+
return restoreCodeBlocks(lines.join('\n'), protectedCode);
|
|
99507
|
+
}
|
|
99508
|
+
|
|
99419
99509
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
99420
99510
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
99421
99511
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -106555,6 +106645,7 @@ function loadComponents() {
|
|
|
106555
106645
|
|
|
106556
106646
|
|
|
106557
106647
|
|
|
106648
|
+
|
|
106558
106649
|
|
|
106559
106650
|
|
|
106560
106651
|
const defaultTransformers = [
|
|
@@ -106569,10 +106660,11 @@ const defaultTransformers = [
|
|
|
106569
106660
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
106570
106661
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
106571
106662
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
106572
|
-
* 3.
|
|
106573
|
-
* 4.
|
|
106574
|
-
* 5.
|
|
106575
|
-
* 6.
|
|
106663
|
+
* 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
|
|
106664
|
+
* 4. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
106665
|
+
* 5. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
106666
|
+
* 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
106667
|
+
* 7. Replace snake_case component names with parser-safe placeholders
|
|
106576
106668
|
*/
|
|
106577
106669
|
function preprocessContent(content, opts) {
|
|
106578
106670
|
const { knownComponents } = opts;
|
|
@@ -106580,6 +106672,10 @@ function preprocessContent(content, opts) {
|
|
|
106580
106672
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
106581
106673
|
let result = normalizeClosingTagWhitespace(content);
|
|
106582
106674
|
result = normalizeTableSeparator(result);
|
|
106675
|
+
// Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
|
|
106676
|
+
// would otherwise fragment it (children spill out as an indented code block once
|
|
106677
|
+
// a wrapper re-parses its deindented body — #1545).
|
|
106678
|
+
result = collapseForeignContentBlankLines(result);
|
|
106583
106679
|
result = terminateHtmlFlowBlocks(result);
|
|
106584
106680
|
result = closeSelfClosingHtmlTags(result);
|
|
106585
106681
|
result = normalizeCompactHeadings(result);
|
|
@@ -107303,6 +107399,8 @@ function restoreMagicBlocks(replaced, blocks) {
|
|
|
107303
107399
|
|
|
107304
107400
|
|
|
107305
107401
|
|
|
107402
|
+
|
|
107403
|
+
|
|
107306
107404
|
/**
|
|
107307
107405
|
* Removes Markdown and MDX comments.
|
|
107308
107406
|
*/
|
|
@@ -107313,10 +107411,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
107313
107411
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
107314
107412
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
107315
107413
|
// 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
|
|
107414
|
+
// 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
|
|
107316
107415
|
if (mdxish) {
|
|
107317
107416
|
processor
|
|
107318
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
107319
|
-
.data('fromMarkdownExtensions', [
|
|
107417
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
107418
|
+
.data('fromMarkdownExtensions', [
|
|
107419
|
+
htmlBlockComponentFromMarkdown(),
|
|
107420
|
+
jsxTableFromMarkdown(),
|
|
107421
|
+
mdxComponentFromMarkdown(),
|
|
107422
|
+
mdxExpressionFromMarkdown(),
|
|
107423
|
+
])
|
|
107320
107424
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
107321
107425
|
}
|
|
107322
107426
|
processor
|
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,12 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
96525
96525
|
'caption',
|
|
96526
96526
|
'colgroup',
|
|
96527
96527
|
]);
|
|
96528
|
+
/**
|
|
96529
|
+
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
96530
|
+
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
96531
|
+
* set per the HTML spec, so transforms can treat these roots as opaque islands.
|
|
96532
|
+
*/
|
|
96533
|
+
const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
|
|
96528
96534
|
/**
|
|
96529
96535
|
* HTML void elements — elements that have no closing tag and no children.
|
|
96530
96536
|
*
|
|
@@ -119154,6 +119160,9 @@ function getComponentName(componentName, components) {
|
|
|
119154
119160
|
|
|
119155
119161
|
|
|
119156
119162
|
|
|
119163
|
+
// Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
|
|
119164
|
+
// untouched (their children are namespaced XML, not HTML tags/components).
|
|
119165
|
+
const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
|
|
119157
119166
|
function isElementContentNode(node) {
|
|
119158
119167
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
119159
119168
|
}
|
|
@@ -119329,6 +119338,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
119329
119338
|
visit(tree, 'element', (node, index, parent) => {
|
|
119330
119339
|
if (index === undefined || !parent)
|
|
119331
119340
|
return;
|
|
119341
|
+
// Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
|
|
119342
|
+
// aren't HTML tags or components, so the "unknown component" removal below would
|
|
119343
|
+
// otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
|
|
119344
|
+
// eslint-disable-next-line consistent-return
|
|
119345
|
+
if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
|
|
119346
|
+
return SKIP;
|
|
119332
119347
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
119333
119348
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
119334
119349
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -119640,6 +119655,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
119640
119655
|
return restoreCodeBlocks(result, protectedCode);
|
|
119641
119656
|
}
|
|
119642
119657
|
|
|
119658
|
+
;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
|
|
119659
|
+
|
|
119660
|
+
|
|
119661
|
+
// `svg|math`, from the canonical list so this stays in sync with the component transform.
|
|
119662
|
+
const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
|
|
119663
|
+
// A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
|
|
119664
|
+
// root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
|
|
119665
|
+
const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
|
|
119666
|
+
// Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
|
|
119667
|
+
// `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
|
|
119668
|
+
// chars (including newlines) are consumed one at a time.
|
|
119669
|
+
const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
|
|
119670
|
+
// One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
|
|
119671
|
+
// and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
|
|
119672
|
+
// `<svg-icon>` out. Group 1 is `/` only for a self-closer.
|
|
119673
|
+
const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
|
|
119674
|
+
// An HTML comment. Foreign markup inside one is inert and must not open an island.
|
|
119675
|
+
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
119676
|
+
const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
|
|
119677
|
+
/**
|
|
119678
|
+
* `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
|
|
119679
|
+
* lines are known-insignificant XML. Matching whole tags (not per-line open/close
|
|
119680
|
+
* counts) keeps multi-line openers and self-closers balanced, so a wrapped
|
|
119681
|
+
* `<svg … />` can't latch and swallow the doc (#1545).
|
|
119682
|
+
*
|
|
119683
|
+
* Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
|
|
119684
|
+
* closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
|
|
119685
|
+
* swallowing every blank line after it, without hiding the real islands that follow.
|
|
119686
|
+
*/
|
|
119687
|
+
function findForeignContentSpans(text) {
|
|
119688
|
+
const spans = [];
|
|
119689
|
+
// Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
|
|
119690
|
+
// must not open an island and latch onto the rest of the doc.
|
|
119691
|
+
const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
|
|
119692
|
+
// Offsets of openers still waiting for their closer, innermost last.
|
|
119693
|
+
const openOffsets = [];
|
|
119694
|
+
[...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
|
|
119695
|
+
const offset = match.index ?? 0;
|
|
119696
|
+
if (withinAny(comments, offset))
|
|
119697
|
+
return; // markup inside an HTML comment is inert
|
|
119698
|
+
if (match[1] === '/')
|
|
119699
|
+
return; // self-closing tag opens no island
|
|
119700
|
+
if (match[0].startsWith('</')) {
|
|
119701
|
+
const start = openOffsets.pop();
|
|
119702
|
+
if (start !== undefined)
|
|
119703
|
+
spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
|
|
119704
|
+
}
|
|
119705
|
+
else {
|
|
119706
|
+
openOffsets.push(offset);
|
|
119707
|
+
}
|
|
119708
|
+
});
|
|
119709
|
+
return spans;
|
|
119710
|
+
}
|
|
119711
|
+
/**
|
|
119712
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
119713
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
119714
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
119715
|
+
*/
|
|
119716
|
+
function collapseForeignContentBlankLines(content) {
|
|
119717
|
+
// Fast path: nothing to do when the doc has no foreign-content island.
|
|
119718
|
+
if (!ANY_ROOT_RE.test(content))
|
|
119719
|
+
return content;
|
|
119720
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
119721
|
+
const islands = findForeignContentSpans(protectedContent);
|
|
119722
|
+
// Drop blank lines inside an island; keep everything else verbatim.
|
|
119723
|
+
const lines = [];
|
|
119724
|
+
let lineStart = 0;
|
|
119725
|
+
protectedContent.split('\n').forEach(line => {
|
|
119726
|
+
if (line.trim().length > 0 || !withinAny(islands, lineStart))
|
|
119727
|
+
lines.push(line);
|
|
119728
|
+
lineStart += line.length + 1; // +1 for the '\n' that split() removed
|
|
119729
|
+
});
|
|
119730
|
+
return restoreCodeBlocks(lines.join('\n'), protectedCode);
|
|
119731
|
+
}
|
|
119732
|
+
|
|
119643
119733
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
119644
119734
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
119645
119735
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -126779,6 +126869,7 @@ function loadComponents() {
|
|
|
126779
126869
|
|
|
126780
126870
|
|
|
126781
126871
|
|
|
126872
|
+
|
|
126782
126873
|
|
|
126783
126874
|
|
|
126784
126875
|
const defaultTransformers = [
|
|
@@ -126793,10 +126884,11 @@ const defaultTransformers = [
|
|
|
126793
126884
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
126794
126885
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
126795
126886
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
126796
|
-
* 3.
|
|
126797
|
-
* 4.
|
|
126798
|
-
* 5.
|
|
126799
|
-
* 6.
|
|
126887
|
+
* 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
|
|
126888
|
+
* 4. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
126889
|
+
* 5. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
126890
|
+
* 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
126891
|
+
* 7. Replace snake_case component names with parser-safe placeholders
|
|
126800
126892
|
*/
|
|
126801
126893
|
function preprocessContent(content, opts) {
|
|
126802
126894
|
const { knownComponents } = opts;
|
|
@@ -126804,6 +126896,10 @@ function preprocessContent(content, opts) {
|
|
|
126804
126896
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
126805
126897
|
let result = normalizeClosingTagWhitespace(content);
|
|
126806
126898
|
result = normalizeTableSeparator(result);
|
|
126899
|
+
// Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
|
|
126900
|
+
// would otherwise fragment it (children spill out as an indented code block once
|
|
126901
|
+
// a wrapper re-parses its deindented body — #1545).
|
|
126902
|
+
result = collapseForeignContentBlankLines(result);
|
|
126807
126903
|
result = terminateHtmlFlowBlocks(result);
|
|
126808
126904
|
result = closeSelfClosingHtmlTags(result);
|
|
126809
126905
|
result = normalizeCompactHeadings(result);
|
|
@@ -127527,6 +127623,8 @@ function restoreMagicBlocks(replaced, blocks) {
|
|
|
127527
127623
|
|
|
127528
127624
|
|
|
127529
127625
|
|
|
127626
|
+
|
|
127627
|
+
|
|
127530
127628
|
/**
|
|
127531
127629
|
* Removes Markdown and MDX comments.
|
|
127532
127630
|
*/
|
|
@@ -127537,10 +127635,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
127537
127635
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
127538
127636
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
127539
127637
|
// 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
|
|
127638
|
+
// 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
|
|
127540
127639
|
if (mdxish) {
|
|
127541
127640
|
processor
|
|
127542
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
127543
|
-
.data('fromMarkdownExtensions', [
|
|
127641
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
127642
|
+
.data('fromMarkdownExtensions', [
|
|
127643
|
+
htmlBlockComponentFromMarkdown(),
|
|
127644
|
+
jsxTableFromMarkdown(),
|
|
127645
|
+
mdxComponentFromMarkdown(),
|
|
127646
|
+
mdxExpressionFromMarkdown(),
|
|
127647
|
+
])
|
|
127544
127648
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
127545
127649
|
}
|
|
127546
127650
|
processor
|