@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
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Root } from 'mdast';
|
|
2
|
+
import type { Plugin } from 'unified';
|
|
3
|
+
/**
|
|
4
|
+
* Converts LF and CRLF line endings into hard breaks while leaving standalone
|
|
5
|
+
* carriage returns as soft whitespace.
|
|
6
|
+
*
|
|
7
|
+
* Unlike `remark-breaks`, this does not promote a lone `\r` into a `<br>`.
|
|
8
|
+
* Standalone carriage returns can be left behind by generators that replace
|
|
9
|
+
* the LF in Windows line endings with an explicit `<br>`, producing input such
|
|
10
|
+
* as `\r<br>`. Treating both characters as hard breaks doubles the spacing.
|
|
11
|
+
*/
|
|
12
|
+
declare const hardBreaks: Plugin<[], Root>;
|
|
13
|
+
export default hardBreaks;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
3
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
4
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
5
|
+
*/
|
|
6
|
+
export declare function collapseForeignContentBlankLines(content: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommonMark indentation helpers, shared by the mdxish preprocessors so tab- and
|
|
3
|
+
* space-indented content is measured (and sliced) on one scale.
|
|
4
|
+
*
|
|
5
|
+
* CommonMark's indented-code threshold is 4 *columns*, and a tab is a 4-column tab
|
|
6
|
+
* stop — not a fixed 4 characters. Counting characters (tab = 1) under-measures
|
|
7
|
+
* tab-indented lines, letting them slip past the 4-column gate so their content
|
|
8
|
+
* fragments into code blocks. Keeping one implementation here stops the two callers
|
|
9
|
+
* from drifting on what "4 columns" means.
|
|
10
|
+
*/
|
|
11
|
+
/** The run of leading spaces/tabs on a line. */
|
|
12
|
+
export declare const leadingIndent: (line: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Expand a leading-whitespace run to spaces using CommonMark's 4-column tab stops,
|
|
15
|
+
* so a run of mixed tabs/spaces can be measured by length and sliced by column.
|
|
16
|
+
*/
|
|
17
|
+
export declare function expandIndentToColumns(indent: string): string;
|
|
18
|
+
/** Indentation width of a line in CommonMark columns (a tab advances to the next 4-column stop). */
|
|
19
|
+
export declare const indentWidth: (line: string) => number;
|
|
@@ -86449,8 +86449,8 @@ function Anchor(props) {
|
|
|
86449
86449
|
|
|
86450
86450
|
|
|
86451
86451
|
|
|
86452
|
-
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, target, title }) => {
|
|
86453
|
-
const Tag = href ?
|
|
86452
|
+
const Card = ({ badge, children, href, kind = 'card', icon, iconColor, LinkComponent = 'a', target, title, }) => {
|
|
86453
|
+
const Tag = href ? LinkComponent : 'div';
|
|
86454
86454
|
return (external_react_default().createElement(Tag, { className: `Card Card_${kind}`, href: href, target: target },
|
|
86455
86455
|
icon && external_react_default().createElement(components_Icon, { className: "Card-icon", icon: icon, iconColor: iconColor }),
|
|
86456
86456
|
external_react_default().createElement("div", { className: "Card-content" },
|
|
@@ -96476,6 +96476,12 @@ const HTML_TABLE_STRUCTURE_TAGS = new Set([
|
|
|
96476
96476
|
'caption',
|
|
96477
96477
|
'colgroup',
|
|
96478
96478
|
]);
|
|
96479
|
+
/**
|
|
96480
|
+
* The two HTML "foreign content" namespaces: SVG and MathML. Their descendants
|
|
96481
|
+
* (`<path>`, `<mrow>`, …) are namespaced XML, not HTML tags or components. A closed
|
|
96482
|
+
* set per the HTML spec, so transforms can treat these roots as opaque islands.
|
|
96483
|
+
*/
|
|
96484
|
+
const FOREIGN_CONTENT_TAGS = ['svg', 'math'];
|
|
96479
96485
|
/**
|
|
96480
96486
|
* HTML void elements — elements that have no closing tag and no children.
|
|
96481
96487
|
*
|
|
@@ -109833,63 +109839,6 @@ function rehypeSanitize(options) {
|
|
|
109833
109839
|
}
|
|
109834
109840
|
}
|
|
109835
109841
|
|
|
109836
|
-
;// ./node_modules/mdast-util-newline-to-break/lib/index.js
|
|
109837
|
-
/**
|
|
109838
|
-
* @typedef {import('mdast').Nodes} Nodes
|
|
109839
|
-
* @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction
|
|
109840
|
-
*/
|
|
109841
|
-
|
|
109842
|
-
|
|
109843
|
-
|
|
109844
|
-
/**
|
|
109845
|
-
* Turn normal line endings into hard breaks.
|
|
109846
|
-
*
|
|
109847
|
-
* @param {Nodes} tree
|
|
109848
|
-
* Tree to change.
|
|
109849
|
-
* @returns {undefined}
|
|
109850
|
-
* Nothing.
|
|
109851
|
-
*/
|
|
109852
|
-
function newlineToBreak(tree) {
|
|
109853
|
-
findAndReplace(tree, [/\r?\n|\r/g, lib_replace])
|
|
109854
|
-
}
|
|
109855
|
-
|
|
109856
|
-
/**
|
|
109857
|
-
* Replace line endings.
|
|
109858
|
-
*
|
|
109859
|
-
* @type {ReplaceFunction}
|
|
109860
|
-
*/
|
|
109861
|
-
function lib_replace() {
|
|
109862
|
-
return {type: 'break'}
|
|
109863
|
-
}
|
|
109864
|
-
|
|
109865
|
-
;// ./node_modules/remark-breaks/lib/index.js
|
|
109866
|
-
/**
|
|
109867
|
-
* @typedef {import('mdast').Root} Root
|
|
109868
|
-
*/
|
|
109869
|
-
|
|
109870
|
-
|
|
109871
|
-
|
|
109872
|
-
/**
|
|
109873
|
-
* Support hard breaks without needing spaces or escapes (turns enters into
|
|
109874
|
-
* `<br>`s).
|
|
109875
|
-
*
|
|
109876
|
-
* @returns
|
|
109877
|
-
* Transform.
|
|
109878
|
-
*/
|
|
109879
|
-
function remarkBreaks() {
|
|
109880
|
-
/**
|
|
109881
|
-
* Transform.
|
|
109882
|
-
*
|
|
109883
|
-
* @param {Root} tree
|
|
109884
|
-
* Tree.
|
|
109885
|
-
* @returns {undefined}
|
|
109886
|
-
* Nothing.
|
|
109887
|
-
*/
|
|
109888
|
-
return function (tree) {
|
|
109889
|
-
newlineToBreak(tree)
|
|
109890
|
-
}
|
|
109891
|
-
}
|
|
109892
|
-
|
|
109893
109842
|
;// ./errors/mdx-syntax-error.ts
|
|
109894
109843
|
class MdxSyntaxError extends SyntaxError {
|
|
109895
109844
|
original = null;
|
|
@@ -109911,6 +109860,22 @@ class MdxSyntaxError extends SyntaxError {
|
|
|
109911
109860
|
}
|
|
109912
109861
|
}
|
|
109913
109862
|
|
|
109863
|
+
;// ./processor/plugin/hard-breaks.ts
|
|
109864
|
+
|
|
109865
|
+
/**
|
|
109866
|
+
* Converts LF and CRLF line endings into hard breaks while leaving standalone
|
|
109867
|
+
* carriage returns as soft whitespace.
|
|
109868
|
+
*
|
|
109869
|
+
* Unlike `remark-breaks`, this does not promote a lone `\r` into a `<br>`.
|
|
109870
|
+
* Standalone carriage returns can be left behind by generators that replace
|
|
109871
|
+
* the LF in Windows line endings with an explicit `<br>`, producing input such
|
|
109872
|
+
* as `\r<br>`. Treating both characters as hard breaks doubles the spacing.
|
|
109873
|
+
*/
|
|
109874
|
+
const hardBreaks = () => tree => {
|
|
109875
|
+
findAndReplace(tree, [/\r?\n/g, () => ({ type: 'break' })]);
|
|
109876
|
+
};
|
|
109877
|
+
/* harmony default export */ const hard_breaks = (hardBreaks);
|
|
109878
|
+
|
|
109914
109879
|
;// ./node_modules/estree-util-value-to-estree/dist/estree-util-value-to-estree.js
|
|
109915
109880
|
/**
|
|
109916
109881
|
* Create an ESTree identifier node for a given name.
|
|
@@ -112615,7 +112580,7 @@ const compile_compile = (text, { components = {}, missingComponents, copyButtons
|
|
|
112615
112580
|
const remarkPlugins = [
|
|
112616
112581
|
remarkFrontmatter,
|
|
112617
112582
|
lib_remarkGfm,
|
|
112618
|
-
...(hardBreaks ? [
|
|
112583
|
+
...(hardBreaks ? [hard_breaks] : []),
|
|
112619
112584
|
...Object.values(transforms),
|
|
112620
112585
|
[codeTabsTransformer, { copyButtons }],
|
|
112621
112586
|
[
|
|
@@ -117726,6 +117691,9 @@ function getComponentName(componentName, components) {
|
|
|
117726
117691
|
|
|
117727
117692
|
|
|
117728
117693
|
|
|
117694
|
+
// Foreign-content (SVG/MathML) roots — subtrees the component transform leaves
|
|
117695
|
+
// untouched (their children are namespaced XML, not HTML tags/components).
|
|
117696
|
+
const FOREIGN_CONTENT_ROOTS = new Set(FOREIGN_CONTENT_TAGS);
|
|
117729
117697
|
function isElementContentNode(node) {
|
|
117730
117698
|
return node.type === 'element' || node.type === 'text' || node.type === 'comment';
|
|
117731
117699
|
}
|
|
@@ -117901,6 +117869,12 @@ const rehypeMdxishComponents = ({ components, processMarkdown }) => {
|
|
|
117901
117869
|
lib_visit(tree, 'element', (node, index, parent) => {
|
|
117902
117870
|
if (index === undefined || !parent)
|
|
117903
117871
|
return;
|
|
117872
|
+
// Skip foreign-content subtrees: their namespaced children (<path>, <mrow>, …)
|
|
117873
|
+
// aren't HTML tags or components, so the "unknown component" removal below would
|
|
117874
|
+
// otherwise delete them. (svg/math themselves are standard HTML tags, kept.)
|
|
117875
|
+
// eslint-disable-next-line consistent-return
|
|
117876
|
+
if (FOREIGN_CONTENT_ROOTS.has(node.tagName))
|
|
117877
|
+
return lib_SKIP;
|
|
117904
117878
|
// Parse Image caption as markdown so it renders formatted (bold, code,
|
|
117905
117879
|
// decoded entities) in the figcaption instead of as a raw string.
|
|
117906
117880
|
// rehypeRaw strips children from <img> (void element), so we must
|
|
@@ -118212,6 +118186,81 @@ function closeSelfClosingHtmlTags(content) {
|
|
|
118212
118186
|
return restoreCodeBlocks(result, protectedCode);
|
|
118213
118187
|
}
|
|
118214
118188
|
|
|
118189
|
+
;// ./processor/transform/mdxish/collapse-foreign-content-blank-lines.ts
|
|
118190
|
+
|
|
118191
|
+
|
|
118192
|
+
// `svg|math`, from the canonical list so this stays in sync with the component transform.
|
|
118193
|
+
const ROOT_ALT = FOREIGN_CONTENT_TAGS.join('|');
|
|
118194
|
+
// A foreign-content opener. The `[\s/>]` boundary requires a real tag delimiter after the
|
|
118195
|
+
// root name, so lookalikes like `<svgfoo>` and custom elements like `<svg-icon>` are ignored.
|
|
118196
|
+
const ANY_ROOT_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])`, 'i');
|
|
118197
|
+
// Tag body: swallows whole quoted attribute values so a `>` inside a quote (e.g.
|
|
118198
|
+
// `<svg data-x="a > b" />`) can't be mistaken for the tag terminator; other non-`>`
|
|
118199
|
+
// chars (including newlines) are consumed one at a time.
|
|
118200
|
+
const TAG_BODY = '(?:"[^"]*"|\'[^\']*\'|[^>\'"])*?';
|
|
118201
|
+
// One whole svg/math tag (opener, self-closer, or closer), matched whole so attributes
|
|
118202
|
+
// and `>` may span lines. The `[\s/>]` boundary after the root name keeps `<svgfoo>`/
|
|
118203
|
+
// `<svg-icon>` out. Group 1 is `/` only for a self-closer.
|
|
118204
|
+
const FOREIGN_TAG_RE = new RegExp(`<(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}(/)?>|</(?:${ROOT_ALT})(?=[\\s/>])${TAG_BODY}>`, 'gi');
|
|
118205
|
+
// An HTML comment. Foreign markup inside one is inert and must not open an island.
|
|
118206
|
+
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
118207
|
+
const withinAny = (spans, offset) => spans.some(([start, end]) => offset >= start && offset < end);
|
|
118208
|
+
/**
|
|
118209
|
+
* `[start, end)` spans of every *matched* SVG/MathML pair — the regions whose blank
|
|
118210
|
+
* lines are known-insignificant XML. Matching whole tags (not per-line open/close
|
|
118211
|
+
* counts) keeps multi-line openers and self-closers balanced, so a wrapped
|
|
118212
|
+
* `<svg … />` can't latch and swallow the doc (#1545).
|
|
118213
|
+
*
|
|
118214
|
+
* Tags are paired innermost-first, as a parser would; an opener still unpaired at EOF
|
|
118215
|
+
* closed nothing and so covers nothing. That keeps a stray `<svg>` in prose from
|
|
118216
|
+
* swallowing every blank line after it, without hiding the real islands that follow.
|
|
118217
|
+
*/
|
|
118218
|
+
function findForeignContentSpans(text) {
|
|
118219
|
+
const spans = [];
|
|
118220
|
+
// Foreign tags inside an HTML comment are inert; a stray `<svg>`/`<math>` in a comment
|
|
118221
|
+
// must not open an island and latch onto the rest of the doc.
|
|
118222
|
+
const comments = [...text.matchAll(HTML_COMMENT_RE)].map((m) => [m.index ?? 0, (m.index ?? 0) + m[0].length]);
|
|
118223
|
+
// Offsets of openers still waiting for their closer, innermost last.
|
|
118224
|
+
const openOffsets = [];
|
|
118225
|
+
[...text.matchAll(FOREIGN_TAG_RE)].forEach(match => {
|
|
118226
|
+
const offset = match.index ?? 0;
|
|
118227
|
+
if (withinAny(comments, offset))
|
|
118228
|
+
return; // markup inside an HTML comment is inert
|
|
118229
|
+
if (match[1] === '/')
|
|
118230
|
+
return; // self-closing tag opens no island
|
|
118231
|
+
if (match[0].startsWith('</')) {
|
|
118232
|
+
const start = openOffsets.pop();
|
|
118233
|
+
if (start !== undefined)
|
|
118234
|
+
spans.push([start, offset + match[0].length]); // a closer with no opener closes nothing
|
|
118235
|
+
}
|
|
118236
|
+
else {
|
|
118237
|
+
openOffsets.push(offset);
|
|
118238
|
+
}
|
|
118239
|
+
});
|
|
118240
|
+
return spans;
|
|
118241
|
+
}
|
|
118242
|
+
/**
|
|
118243
|
+
* Drop blank lines inside `<svg>`/`<math>` islands: their whitespace is
|
|
118244
|
+
* insignificant XML, but a blank line ends the CommonMark HTML block and spills the
|
|
118245
|
+
* children out as a code block (#1545). Collapsing keeps the island one block.
|
|
118246
|
+
*/
|
|
118247
|
+
function collapseForeignContentBlankLines(content) {
|
|
118248
|
+
// Fast path: nothing to do when the doc has no foreign-content island.
|
|
118249
|
+
if (!ANY_ROOT_RE.test(content))
|
|
118250
|
+
return content;
|
|
118251
|
+
const { protectedContent, protectedCode } = protectCodeBlocks(content);
|
|
118252
|
+
const islands = findForeignContentSpans(protectedContent);
|
|
118253
|
+
// Drop blank lines inside an island; keep everything else verbatim.
|
|
118254
|
+
const lines = [];
|
|
118255
|
+
let lineStart = 0;
|
|
118256
|
+
protectedContent.split('\n').forEach(line => {
|
|
118257
|
+
if (line.trim().length > 0 || !withinAny(islands, lineStart))
|
|
118258
|
+
lines.push(line);
|
|
118259
|
+
lineStart += line.length + 1; // +1 for the '\n' that split() removed
|
|
118260
|
+
});
|
|
118261
|
+
return restoreCodeBlocks(lines.join('\n'), protectedCode);
|
|
118262
|
+
}
|
|
118263
|
+
|
|
118215
118264
|
;// ./lib/utils/mdxish/mdxish-component-tag-parser.ts
|
|
118216
118265
|
// Extract the tag name (PascalCase or lowercase HTML) at the start of a tag string.
|
|
118217
118266
|
const tagNamePattern = /^<([A-Za-z][A-Za-z0-9_-]*)/;
|
|
@@ -121379,10 +121428,36 @@ const mdxishInlineMdxComponents = () => tree => {
|
|
|
121379
121428
|
};
|
|
121380
121429
|
/* harmony default export */ const inline_mdx_blocks = (mdxishInlineMdxComponents);
|
|
121381
121430
|
|
|
121431
|
+
;// ./processor/transform/mdxish/indentation.ts
|
|
121432
|
+
/**
|
|
121433
|
+
* CommonMark indentation helpers, shared by the mdxish preprocessors so tab- and
|
|
121434
|
+
* space-indented content is measured (and sliced) on one scale.
|
|
121435
|
+
*
|
|
121436
|
+
* CommonMark's indented-code threshold is 4 *columns*, and a tab is a 4-column tab
|
|
121437
|
+
* stop — not a fixed 4 characters. Counting characters (tab = 1) under-measures
|
|
121438
|
+
* tab-indented lines, letting them slip past the 4-column gate so their content
|
|
121439
|
+
* fragments into code blocks. Keeping one implementation here stops the two callers
|
|
121440
|
+
* from drifting on what "4 columns" means.
|
|
121441
|
+
*/
|
|
121442
|
+
/** The run of leading spaces/tabs on a line. */
|
|
121443
|
+
const leadingIndent = (line) => line.match(/^[ \t]*/)?.[0] ?? '';
|
|
121444
|
+
/**
|
|
121445
|
+
* Expand a leading-whitespace run to spaces using CommonMark's 4-column tab stops,
|
|
121446
|
+
* so a run of mixed tabs/spaces can be measured by length and sliced by column.
|
|
121447
|
+
*/
|
|
121448
|
+
function expandIndentToColumns(indent) {
|
|
121449
|
+
return indent
|
|
121450
|
+
.split('')
|
|
121451
|
+
.reduce((columns, char) => columns + (char === '\t' ? ' '.repeat(4 - (columns.length % 4)) : ' '), '');
|
|
121452
|
+
}
|
|
121453
|
+
/** Indentation width of a line in CommonMark columns (a tab advances to the next 4-column stop). */
|
|
121454
|
+
const indentWidth = (line) => expandIndentToColumns(leadingIndent(line)).length;
|
|
121455
|
+
|
|
121382
121456
|
;// ./processor/transform/mdxish/terminate-html-flow-blocks.ts
|
|
121383
121457
|
|
|
121384
121458
|
|
|
121385
121459
|
|
|
121460
|
+
|
|
121386
121461
|
const STANDALONE_HTML_LINE_REGEX = /^(<[a-z][^<>]*>|<\/[a-z][^<>]*>)+\s*$/;
|
|
121387
121462
|
const HTML_LINE_WITH_CONTENT_REGEX = /^<[a-z][^<>]*>.*<\/[a-z][^<>]*>(?:[^<]*)$/;
|
|
121388
121463
|
// A line that is exactly one lowercase opening (or self-closing) tag — the shape
|
|
@@ -121408,11 +121483,6 @@ function countRawContentTags(line) {
|
|
|
121408
121483
|
closes: (line.match(close) ?? []).length,
|
|
121409
121484
|
}));
|
|
121410
121485
|
}
|
|
121411
|
-
// Indentation width in columns, counting a tab as 4 per CommonMark.
|
|
121412
|
-
function indentWidth(line) {
|
|
121413
|
-
const leading = line.match(/^[ \t]*/)?.[0] ?? '';
|
|
121414
|
-
return leading.replace(/\t/g, ' ').length;
|
|
121415
|
-
}
|
|
121416
121486
|
/**
|
|
121417
121487
|
* Decides whether a blank line belongs between `line` and `next` so the HTML
|
|
121418
121488
|
* flow block opened on `line` terminates and `next` parses as markdown.
|
|
@@ -121484,6 +121554,7 @@ function terminateHtmlFlowBlocks(content) {
|
|
|
121484
121554
|
|
|
121485
121555
|
|
|
121486
121556
|
|
|
121557
|
+
|
|
121487
121558
|
// Matches a JSX attribute expression (e.g. `key={i}`) anywhere in a string. */
|
|
121488
121559
|
const NESTED_ATTR_EXPRESSION_RE = /[\w-]+\s*=\s*\{/;
|
|
121489
121560
|
// Name shape mirrors `componentTagPattern`; the lookbehind skips the inner tag
|
|
@@ -121494,25 +121565,33 @@ const NESTED_COMPONENT_TAG_RE = /(?<!<)<([A-Z][A-Za-z0-9_]*)[\s/>]/g;
|
|
|
121494
121565
|
const hasNestedGenericComponentTag = (content) => [...content.matchAll(NESTED_COMPONENT_TAG_RE)].some(match => !GENERIC_MDX_COMPONENT_EXCLUDED_TAGS.has(match[1]));
|
|
121495
121566
|
/**
|
|
121496
121567
|
* Strip the shared leading indentation from a component body so readability indentation
|
|
121497
|
-
* isn't parsed as indented code (4+
|
|
121568
|
+
* isn't parsed as indented code (4+ columns), e.g. ` <p>` / ` text` -> `<p>` / ` text`.
|
|
121498
121569
|
* Relative indentation is kept, so content genuinely 4+ columns deeper stays code. We
|
|
121499
121570
|
* only strip when a line actually reaches 4 columns; otherwise the body is left as-is so
|
|
121500
121571
|
* its leading whitespace survives as text nodes (mixed component + HTML content needs it).
|
|
121572
|
+
*
|
|
121573
|
+
* Indentation is measured in CommonMark columns (tab = up to 4), matching how the parser
|
|
121574
|
+
* decides indented code. A char count (tab = 1) under-measures tab-indented bodies, so
|
|
121575
|
+
* they slip past the 4-column gate and their nested content fragments into code blocks.
|
|
121501
121576
|
*/
|
|
121502
121577
|
function safeDeindent(text) {
|
|
121503
121578
|
const lines = text.split('\n');
|
|
121504
121579
|
const nonEmptyLines = lines.filter(line => line.trim().length > 0);
|
|
121505
121580
|
if (nonEmptyLines.length === 0)
|
|
121506
121581
|
return text;
|
|
121507
|
-
|
|
121508
|
-
// (tab = 4) in terminate-html-flow-blocks.
|
|
121509
|
-
const indents = nonEmptyLines.map(line => line.match(/^(\s*)/)?.[1].length ?? 0);
|
|
121582
|
+
const indents = nonEmptyLines.map(line => expandIndentToColumns(leadingIndent(line)).length);
|
|
121510
121583
|
const minIndent = Math.min(...indents);
|
|
121511
121584
|
const maxIndent = Math.max(...indents);
|
|
121512
|
-
|
|
121513
|
-
if (stripAmount === 0)
|
|
121585
|
+
if (maxIndent < 4 || minIndent === 0)
|
|
121514
121586
|
return text;
|
|
121515
|
-
|
|
121587
|
+
// Expand each line's leading run to spaces before slicing so a shared indent of mixed
|
|
121588
|
+
// tabs/spaces (and partial-tab remainders) strips cleanly while relative depth survives.
|
|
121589
|
+
return lines
|
|
121590
|
+
.map(line => {
|
|
121591
|
+
const indent = leadingIndent(line);
|
|
121592
|
+
return expandIndentToColumns(indent).slice(minIndent) + line.slice(indent.length);
|
|
121593
|
+
})
|
|
121594
|
+
.join('\n');
|
|
121516
121595
|
}
|
|
121517
121596
|
/**
|
|
121518
121597
|
* Parse component-body markdown into mdast children. Dedenting shifts columns and
|
|
@@ -124107,7 +124186,7 @@ const textToBlock = (text) => [{ children: textToInline(text), type: 'paragraph'
|
|
|
124107
124186
|
/**
|
|
124108
124187
|
* Converts leading newlines in magic block content to `<br>` tags.
|
|
124109
124188
|
* Leading newlines are stripped by remark-parse before they become soft break nodes,
|
|
124110
|
-
* so
|
|
124189
|
+
* so the hard-breaks plugin cannot handle them. We convert them to HTML `<br>` tags instead.
|
|
124111
124190
|
*/
|
|
124112
124191
|
const ensureLeadingBreaks = (text) => text.replace(/^\n+/, match => '<br>'.repeat(match.length));
|
|
124113
124192
|
/** Preprocesses magic block body content before parsing. */
|
|
@@ -124119,7 +124198,7 @@ const contentParser = lib_unified()
|
|
|
124119
124198
|
.data('micromarkExtensions', [syntax_gemoji(), legacyVariable(), looseHtmlEntity()])
|
|
124120
124199
|
.data('fromMarkdownExtensions', [gemojiFromMarkdown(), legacyVariableFromMarkdown(), emptyTaskListItemFromMarkdown(), looseHtmlEntityFromMarkdown()])
|
|
124121
124200
|
.use(lib_remarkParse)
|
|
124122
|
-
.use(
|
|
124201
|
+
.use(hard_breaks)
|
|
124123
124202
|
.use(lib_remarkGfm)
|
|
124124
124203
|
.use(normalize_malformed_md_syntax);
|
|
124125
124204
|
/**
|
|
@@ -126739,6 +126818,7 @@ function loadComponents() {
|
|
|
126739
126818
|
|
|
126740
126819
|
|
|
126741
126820
|
|
|
126821
|
+
|
|
126742
126822
|
|
|
126743
126823
|
|
|
126744
126824
|
const defaultTransformers = [
|
|
@@ -126753,10 +126833,11 @@ const defaultTransformers = [
|
|
|
126753
126833
|
* Runs a series of string-level transformations before micromark/remark parsing:
|
|
126754
126834
|
* 1. Canonicalize closing tags with stray whitespace (e.g., `</ td >` → `</td>`)
|
|
126755
126835
|
* 2. Normalize malformed table separator syntax (e.g., `|: ---` → `| :---`)
|
|
126756
|
-
* 3.
|
|
126757
|
-
* 4.
|
|
126758
|
-
* 5.
|
|
126759
|
-
* 6.
|
|
126836
|
+
* 3. Collapse blank lines inside `<svg>`/`<math>` so their children aren't fragmented
|
|
126837
|
+
* 4. Terminate HTML flow blocks so subsequent content isn't swallowed
|
|
126838
|
+
* 5. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
|
|
126839
|
+
* 6. Normalize compact ATX headings (e.g., `#Heading` → `# Heading`)
|
|
126840
|
+
* 7. Replace snake_case component names with parser-safe placeholders
|
|
126760
126841
|
*/
|
|
126761
126842
|
function preprocessContent(content, opts) {
|
|
126762
126843
|
const { knownComponents } = opts;
|
|
@@ -126764,6 +126845,10 @@ function preprocessContent(content, opts) {
|
|
|
126764
126845
|
// classification in `terminateHtmlFlowBlocks` is accurate)
|
|
126765
126846
|
let result = normalizeClosingTagWhitespace(content);
|
|
126766
126847
|
result = normalizeTableSeparator(result);
|
|
126848
|
+
// Before terminateHtmlFlowBlocks: a blank line inside an <svg>/<math> island
|
|
126849
|
+
// would otherwise fragment it (children spill out as an indented code block once
|
|
126850
|
+
// a wrapper re-parses its deindented body — #1545).
|
|
126851
|
+
result = collapseForeignContentBlankLines(result);
|
|
126767
126852
|
result = terminateHtmlFlowBlocks(result);
|
|
126768
126853
|
result = closeSelfClosingHtmlTags(result);
|
|
126769
126854
|
result = normalizeCompactHeadings(result);
|
|
@@ -126903,7 +126988,7 @@ function mdxish_mdxish(mdContent, opts = {}) {
|
|
|
126903
126988
|
const { processor, parserReadyContent } = mdxishAstProcessor(contentWithoutComments, opts);
|
|
126904
126989
|
processor
|
|
126905
126990
|
.use(safeMode ? undefined : evaluate_exports) // Evaluate `export const/function` and stash scope on file.data.mdxishScope
|
|
126906
|
-
.use(
|
|
126991
|
+
.use(hard_breaks) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
|
|
126907
126992
|
.use(safeMode ? undefined : evaluate_expressions) // Evaluate self-contained MDX expressions (e.g. `{1+1}`)
|
|
126908
126993
|
.use(safeMode ? undefined : evaluate_style_block_expressions) // Evaluate `<style>{`...`}</style>` template literals into plain CSS
|
|
126909
126994
|
.use(variables_code, { variables }) // Resolve <<...>> and {user.*} inside code and inline code nodes
|
|
@@ -127379,6 +127464,8 @@ const mdxishTags_tags = (doc) => {
|
|
|
127379
127464
|
|
|
127380
127465
|
|
|
127381
127466
|
|
|
127467
|
+
|
|
127468
|
+
|
|
127382
127469
|
/**
|
|
127383
127470
|
* Removes Markdown and MDX comments.
|
|
127384
127471
|
*/
|
|
@@ -127389,10 +127476,16 @@ async function stripComments(doc, { mdx, mdxish } = {}) {
|
|
|
127389
127476
|
// 1. we can rely on remarkMdx to parse MDXish
|
|
127390
127477
|
// 2. we need to parse JSX comments into mdxTextExpression nodes so that the transformers can pick them up
|
|
127391
127478
|
// 3. we need to claim <HTMLBlock> before htmlFlow intercepts its inner HTML tags
|
|
127479
|
+
// 4. we need mdxComponent to parse custom components as one node, and prevent the tag from getting escaped
|
|
127392
127480
|
if (mdxish) {
|
|
127393
127481
|
processor
|
|
127394
|
-
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxExpression({ allowEmpty: true })])
|
|
127395
|
-
.data('fromMarkdownExtensions', [
|
|
127482
|
+
.data('micromarkExtensions', [htmlBlockComponent(), jsxTable(), mdxComponent(), mdxExpression({ allowEmpty: true })])
|
|
127483
|
+
.data('fromMarkdownExtensions', [
|
|
127484
|
+
htmlBlockComponentFromMarkdown(),
|
|
127485
|
+
jsxTableFromMarkdown(),
|
|
127486
|
+
mdxComponentFromMarkdown(),
|
|
127487
|
+
mdxExpressionFromMarkdown(),
|
|
127488
|
+
])
|
|
127396
127489
|
.data('toMarkdownExtensions', [mdxExpressionToMarkdown()]);
|
|
127397
127490
|
}
|
|
127398
127491
|
processor
|