@readme/markdown 14.12.0 → 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 +174 -81
- package/dist/main.node.js +174 -81
- package/dist/main.node.js.map +1 -1
- package/dist/processor/plugin/hard-breaks.d.ts +13 -0
- package/dist/processor/transform/mdxish/collapse-foreign-content-blank-lines.d.ts +6 -0
- package/dist/processor/transform/mdxish/indentation.d.ts +19 -0
- package/dist/render-fixture.node.js +174 -81
- package/dist/render-fixture.node.js.map +1 -1
- package/dist/utils/common-html-words.d.ts +6 -0
- package/package.json +1 -2
|
@@ -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
|
@@ -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
|
*
|
|
@@ -89658,63 +89664,6 @@ function rehypeSanitize(options) {
|
|
|
89658
89664
|
}
|
|
89659
89665
|
}
|
|
89660
89666
|
|
|
89661
|
-
;// ./node_modules/mdast-util-newline-to-break/lib/index.js
|
|
89662
|
-
/**
|
|
89663
|
-
* @typedef {import('mdast').Nodes} Nodes
|
|
89664
|
-
* @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction
|
|
89665
|
-
*/
|
|
89666
|
-
|
|
89667
|
-
|
|
89668
|
-
|
|
89669
|
-
/**
|
|
89670
|
-
* Turn normal line endings into hard breaks.
|
|
89671
|
-
*
|
|
89672
|
-
* @param {Nodes} tree
|
|
89673
|
-
* Tree to change.
|
|
89674
|
-
* @returns {undefined}
|
|
89675
|
-
* Nothing.
|
|
89676
|
-
*/
|
|
89677
|
-
function newlineToBreak(tree) {
|
|
89678
|
-
findAndReplace(tree, [/\r?\n|\r/g, lib_replace])
|
|
89679
|
-
}
|
|
89680
|
-
|
|
89681
|
-
/**
|
|
89682
|
-
* Replace line endings.
|
|
89683
|
-
*
|
|
89684
|
-
* @type {ReplaceFunction}
|
|
89685
|
-
*/
|
|
89686
|
-
function lib_replace() {
|
|
89687
|
-
return {type: 'break'}
|
|
89688
|
-
}
|
|
89689
|
-
|
|
89690
|
-
;// ./node_modules/remark-breaks/lib/index.js
|
|
89691
|
-
/**
|
|
89692
|
-
* @typedef {import('mdast').Root} Root
|
|
89693
|
-
*/
|
|
89694
|
-
|
|
89695
|
-
|
|
89696
|
-
|
|
89697
|
-
/**
|
|
89698
|
-
* Support hard breaks without needing spaces or escapes (turns enters into
|
|
89699
|
-
* `<br>`s).
|
|
89700
|
-
*
|
|
89701
|
-
* @returns
|
|
89702
|
-
* Transform.
|
|
89703
|
-
*/
|
|
89704
|
-
function remarkBreaks() {
|
|
89705
|
-
/**
|
|
89706
|
-
* Transform.
|
|
89707
|
-
*
|
|
89708
|
-
* @param {Root} tree
|
|
89709
|
-
* Tree.
|
|
89710
|
-
* @returns {undefined}
|
|
89711
|
-
* Nothing.
|
|
89712
|
-
*/
|
|
89713
|
-
return function (tree) {
|
|
89714
|
-
newlineToBreak(tree)
|
|
89715
|
-
}
|
|
89716
|
-
}
|
|
89717
|
-
|
|
89718
89667
|
;// ./errors/mdx-syntax-error.ts
|
|
89719
89668
|
class MdxSyntaxError extends SyntaxError {
|
|
89720
89669
|
original = null;
|
|
@@ -89736,6 +89685,22 @@ class MdxSyntaxError extends SyntaxError {
|
|
|
89736
89685
|
}
|
|
89737
89686
|
}
|
|
89738
89687
|
|
|
89688
|
+
;// ./processor/plugin/hard-breaks.ts
|
|
89689
|
+
|
|
89690
|
+
/**
|
|
89691
|
+
* Converts LF and CRLF line endings into hard breaks while leaving standalone
|
|
89692
|
+
* carriage returns as soft whitespace.
|
|
89693
|
+
*
|
|
89694
|
+
* Unlike `remark-breaks`, this does not promote a lone `\r` into a `<br>`.
|
|
89695
|
+
* Standalone carriage returns can be left behind by generators that replace
|
|
89696
|
+
* the LF in Windows line endings with an explicit `<br>`, producing input such
|
|
89697
|
+
* as `\r<br>`. Treating both characters as hard breaks doubles the spacing.
|
|
89698
|
+
*/
|
|
89699
|
+
const hardBreaks = () => tree => {
|
|
89700
|
+
findAndReplace(tree, [/\r?\n/g, () => ({ type: 'break' })]);
|
|
89701
|
+
};
|
|
89702
|
+
/* harmony default export */ const hard_breaks = (hardBreaks);
|
|
89703
|
+
|
|
89739
89704
|
;// ./node_modules/estree-util-value-to-estree/dist/estree-util-value-to-estree.js
|
|
89740
89705
|
/**
|
|
89741
89706
|
* Create an ESTree identifier node for a given name.
|
|
@@ -92440,7 +92405,7 @@ const compile_compile = (text, { components = {}, missingComponents, copyButtons
|
|
|
92440
92405
|
const remarkPlugins = [
|
|
92441
92406
|
remarkFrontmatter,
|
|
92442
92407
|
remarkGfm,
|
|
92443
|
-
...(hardBreaks ? [
|
|
92408
|
+
...(hardBreaks ? [hard_breaks] : []),
|
|
92444
92409
|
...Object.values(transforms),
|
|
92445
92410
|
[codeTabsTransformer, { copyButtons }],
|
|
92446
92411
|
[
|
|
@@ -98971,6 +98936,9 @@ function getComponentName(componentName, components) {
|
|
|
98971
98936
|
|
|
98972
98937
|
|
|
98973
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);
|
|
98974
98942
|
function isElementContentNode(node) {
|
|
98975
98943
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
98976
98944
|
}
|
|
@@ -99146,6 +99114,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
99146
99114
|
visit(tree, 'element', (node, index, parent) => {
|
|
99147
99115
|
if (index === undefined || !parent)
|
|
99148
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;
|
|
99149
99123
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
99150
99124
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
99151
99125
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -99457,6 +99431,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
99457
99431
|
return restoreCodeBlocks(result, protectedCode);
|
|
99458
99432
|
}
|
|
99459
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
|
+
|
|
99460
99509
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
99461
99510
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
99462
99511
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -102624,10 +102673,36 @@ const mdxishInlineMdxComponents = () => tree => {
|
|
|
102624
102673
|
};
|
|
102625
102674
|
/* harmony default export */ const inline_mdx_blocks = (mdxishInlineMdxComponents);
|
|
102626
102675
|
|
|
102676
|
+
;// ./processor/transform/mdxish/indentation.ts
|
|
102677
|
+
/**
|
|
102678
|
+
* CommonMark indentation helpers, shared by the mdxish preprocessors so tab- and
|
|
102679
|
+
* space-indented content is measured (and sliced) on one scale.
|
|
102680
|
+
*
|
|
102681
|
+
* CommonMark's indented-code threshold is 4 *columns*, and a tab is a 4-column tab
|
|
102682
|
+
* stop — not a fixed 4 characters. Counting characters (tab = 1) under-measures
|
|
102683
|
+
* tab-indented lines, letting them slip past the 4-column gate so their content
|
|
102684
|
+
* fragments into code blocks. Keeping one implementation here stops the two callers
|
|
102685
|
+
* from drifting on what "4 columns" means.
|
|
102686
|
+
*/
|
|
102687
|
+
/** The run of leading spaces/tabs on a line. */
|
|
102688
|
+
const leadingIndent = (line) => line.match(/^[ \t]*/)?.[0] ?? '';
|
|
102689
|
+
/**
|
|
102690
|
+
* Expand a leading-whitespace run to spaces using CommonMark's 4-column tab stops,
|
|
102691
|
+
* so a run of mixed tabs/spaces can be measured by length and sliced by column.
|
|
102692
|
+
*/
|
|
102693
|
+
function expandIndentToColumns(indent) {
|
|
102694
|
+
return indent
|
|
102695
|
+
.split('')
|
|
102696
|
+
.reduce((columns, char) => columns + (char === '\t' ? ' '.repeat(4 - (columns.length % 4)) : ' '), '');
|
|
102697
|
+
}
|
|
102698
|
+
/** Indentation width of a line in CommonMark columns (a tab advances to the next 4-column stop). */
|
|
102699
|
+
const indentWidth = (line) => expandIndentToColumns(leadingIndent(line)).length;
|
|
102700
|
+
|
|
102627
102701
|
;// ./processor/transform/mdxish/terminate-html-flow-blocks.ts
|
|
102628
102702
|
|
|
102629
102703
|
|
|
102630
102704
|
|
|
102705
|
+
|
|
102631
102706
|
const STANDALONE_HTML_LINE_REGEX = /^(<[a-z][^<>]*>|<\/[a-z][^<>]*>)+\s*$/;
|
|
102632
102707
|
const HTML_LINE_WITH_CONTENT_REGEX = /^<[a-z][^<>]*>.*<\/[a-z][^<>]*>(?:[^<]*)$/;
|
|
102633
102708
|
// A line that is exactly one lowercase opening (or self-closing) tag — the shape
|
|
@@ -102653,11 +102728,6 @@ function countRawContentTags(line) {
|
|
|
102653
102728
|
closes: (line.match(close) ?? []).length,
|
|
102654
102729
|
}));
|
|
102655
102730
|
}
|
|
102656
|
-
// Indentation width in columns, counting a tab as 4 per CommonMark.
|
|
102657
|
-
function indentWidth(line) {
|
|
102658
|
-
const leading = line.match(/^[ \t]*/)?.[0] ?? '';
|
|
102659
|
-
return leading.replace(/\t/g, ' ').length;
|
|
102660
|
-
}
|
|
102661
102731
|
/**
|
|
102662
102732
|
* Decides whether a blank line belongs between `line` and `next` so the HTML
|
|
102663
102733
|
* flow block opened on `line` terminates and `next` parses as markdown.
|
|
@@ -102729,6 +102799,7 @@ function terminateHtmlFlowBlocks(content) {
|
|
|
102729
102799
|
|
|
102730
102800
|
|
|
102731
102801
|
|
|
102802
|
+
|
|
102732
102803
|
// Matches a JSX attribute expression (e.g. `key={i}`) anywhere in a string. */
|
|
102733
102804
|
const NESTED_ATTR_EXPRESSION_RE = /[\w-]+\s*=\s*\{/;
|
|
102734
102805
|
// Name shape mirrors `componentTagPattern`; the lookbehind skips the inner tag
|
|
@@ -102739,25 +102810,33 @@ const NESTED_COMPONENT_TAG_RE = /(?<!<)<([A-Z][A-Za-z0-9_]*)[\s/>]/g;
|
|
|
102739
102810
|
const hasNestedGenericComponentTag = (content) => [...content.matchAll(NESTED_COMPONENT_TAG_RE)].some(match => !GENERIC_MDX_COMPONENT_EXCLUDED_TAGS.has(match[1]));
|
|
102740
102811
|
/**
|
|
102741
102812
|
* Strip the shared leading indentation from a component body so readability indentation
|
|
102742
|
-
* isn't parsed as indented code (4+
|
|
102813
|
+
* isn't parsed as indented code (4+ columns), e.g. ` <p>` / ` text` -> `<p>` / ` text`.
|
|
102743
102814
|
* Relative indentation is kept, so content genuinely 4+ columns deeper stays code. We
|
|
102744
102815
|
* only strip when a line actually reaches 4 columns; otherwise the body is left as-is so
|
|
102745
102816
|
* its leading whitespace survives as text nodes (mixed component + HTML content needs it).
|
|
102817
|
+
*
|
|
102818
|
+
* Indentation is measured in CommonMark columns (tab = up to 4), matching how the parser
|
|
102819
|
+
* decides indented code. A char count (tab = 1) under-measures tab-indented bodies, so
|
|
102820
|
+
* they slip past the 4-column gate and their nested content fragments into code blocks.
|
|
102746
102821
|
*/
|
|
102747
102822
|
function safeDeindent(text) {
|
|
102748
102823
|
const lines = text.split('\n');
|
|
102749
102824
|
const nonEmptyLines = lines.filter(line => line.trim().length > 0);
|
|
102750
102825
|
if (nonEmptyLines.length === 0)
|
|
102751
102826
|
return text;
|
|
102752
|
-
|
|
102753
|
-
// (tab = 4) in terminate-html-flow-blocks.
|
|
102754
|
-
const indents = nonEmptyLines.map(line => line.match(/^(\s*)/)?.[1].length ?? 0);
|
|
102827
|
+
const indents = nonEmptyLines.map(line => expandIndentToColumns(leadingIndent(line)).length);
|
|
102755
102828
|
const minIndent = Math.min(...indents);
|
|
102756
102829
|
const maxIndent = Math.max(...indents);
|
|
102757
|
-
|
|
102758
|
-
if (stripAmount === 0)
|
|
102830
|
+
if (maxIndent < 4 || minIndent === 0)
|
|
102759
102831
|
return text;
|
|
102760
|
-
|
|
102832
|
+
// Expand each line's leading run to spaces before slicing so a shared indent of mixed
|
|
102833
|
+
// tabs/spaces (and partial-tab remainders) strips cleanly while relative depth survives.
|
|
102834
|
+
return lines
|
|
102835
|
+
.map(line => {
|
|
102836
|
+
const indent = leadingIndent(line);
|
|
102837
|
+
return expandIndentToColumns(indent).slice(minIndent) + line.slice(indent.length);
|
|
102838
|
+
})
|
|
102839
|
+
.join('\n');
|
|
102761
102840
|
}
|
|
102762
102841
|
/**
|
|
102763
102842
|
* Parse component-body markdown into mdast children. Dedenting shifts columns and
|
|
@@ -103934,7 +104013,7 @@ const textToBlock = (text) => [{ children: textToInline(text), type: 'paragraph'
|
|
|
103934
104013
|
/**
|
|
103935
104014
|
* Converts leading newlines in magic block content to `<br>` tags.
|
|
103936
104015
|
* Leading newlines are stripped by remark-parse before they become soft break nodes,
|
|
103937
|
-
* so
|
|
104016
|
+
* so the hard-breaks plugin cannot handle them. We convert them to HTML `<br>` tags instead.
|
|
103938
104017
|
*/
|
|
103939
104018
|
const ensureLeadingBreaks = (text) => text.replace(/^\n+/, match => '<br>'.repeat(match.length));
|
|
103940
104019
|
/** Preprocesses magic block body content before parsing. */
|
|
@@ -103946,7 +104025,7 @@ const contentParser = unified()
|
|
|
103946
104025
|
.data('micromarkExtensions', [syntax_gemoji(), legacyVariable(), looseHtmlEntity()])
|
|
103947
104026
|
.data('fromMarkdownExtensions', [gemojiFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
|
|
103948
104027
|
.use(remarkParse)
|
|
103949
|
-
.use(
|
|
104028
|
+
.use(hard_breaks)
|
|
103950
104029
|
.use(remarkGfm)
|
|
103951
104030
|
.use(normalize_malformed_md_syntax);
|
|
103952
104031
|
/**
|
|
@@ -106566,6 +106645,7 @@ function loadComponents() {
|
|
|
106566
106645
|
|
|
106567
106646
|
|
|
106568
106647
|
|
|
106648
|
+
|
|
106569
106649
|
|
|
106570
106650
|
|
|
106571
106651
|
const defaultTransformers = [
|
|
@@ -106580,10 +106660,11 @@ const defaultTransformers = [
|
|
|
106580
106660
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
106581
106661
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
106582
106662
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
106583
|
-
* 3.
|
|
106584
|
-
* 4.
|
|
106585
|
-
* 5.
|
|
106586
|
-
* 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
|
|
106587
106668
|
*/
|
|
106588
106669
|
function preprocessContent(content, opts) {
|
|
106589
106670
|
const { knownComponents } = opts;
|
|
@@ -106591,6 +106672,10 @@ function preprocessContent(content, opts) {
|
|
|
106591
106672
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
106592
106673
|
let result = normalizeClosingTagWhitespace(content);
|
|
106593
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);
|
|
106594
106679
|
result = terminateHtmlFlowBlocks(result);
|
|
106595
106680
|
result = closeSelfClosingHtmlTags(result);
|
|
106596
106681
|
result = normalizeCompactHeadings(result);
|
|
@@ -106730,7 +106815,7 @@ function mdxish(mdContent, opts = {}) {
|
|
|
106730
106815
|
const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
|
|
106731
106816
|
processor
|
|
106732
106817
|
.use(safeMode ? undefined : evaluate_exports) // Evaluate `export const/function` and stash scope on file.data.mdxishScope
|
|
106733
|
-
.use(
|
|
106818
|
+
.use(hard_breaks) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
|
|
106734
106819
|
.use(safeMode ? undefined : evaluate_expressions) // Evaluate self-contained MDX expressions (e.g. `{1+1}`)
|
|
106735
106820
|
.use(safeMode ? undefined : evaluate_style_block_expressions) // Evaluate `<style>{`...`}</style>` template literals into plain CSS
|
|
106736
106821
|
.use(variables_code, { variables }) // Resolve <<...>> and {user.*} inside code and inline code nodes
|
|
@@ -107314,6 +107399,8 @@ function restoreMagicBlocks(replaced, blocks) {
|
|
|
107314
107399
|
|
|
107315
107400
|
|
|
107316
107401
|
|
|
107402
|
+
|
|
107403
|
+
|
|
107317
107404
|
/**
|
|
107318
107405
|
* Removes Markdown and MDX comments.
|
|
107319
107406
|
*/
|
|
@@ -107324,10 +107411,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
107324
107411
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
107325
107412
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
107326
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
|
|
107327
107415
|
if (mdxish) {
|
|
107328
107416
|
processor
|
|
107329
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
107330
|
-
.data('fromMarkdownExtensions', [
|
|
107417
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
107418
|
+
.data('fromMarkdownExtensions', [
|
|
107419
|
+
htmlBlockComponentFromMarkdown(),
|
|
107420
|
+
jsxTableFromMarkdown(),
|
|
107421
|
+
mdxComponentFromMarkdown(),
|
|
107422
|
+
mdxExpressionFromMarkdown(),
|
|
107423
|
+
])
|
|
107331
107424
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
107332
107425
|
}
|
|
107333
107426
|
processor
|