@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.
@@ -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 = ({ badge, children, href, kind = 'card', icon, iconColor, target, title }: CardProps) => {
19
- const Tag = href ? 'a' : 'div';
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 ? 'a' : 'div';
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 ? [remarkBreaks] : []),
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+ spaces), e.g. ` <p>` / ` text` -> `<p>` / ` text`.
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
- // Indent counts characters (tab = 1), unlike indentWidth's CommonMark columns
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
- const stripAmount = maxIndent > 3 ? minIndent : 0;
102758
- if (stripAmount === 0)
102830
+ if (maxIndent < 4 || minIndent === 0)
102759
102831
  return text;
102760
- return lines.map(line => line.slice(stripAmount)).join('\n');
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 remark-breaks cannot handle them. We convert them to HTML `<br>` tags instead.
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(remarkBreaks)
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. Terminate HTML flow blocks so subsequent content isn't swallowed
106584
- * 4. Close invalid "self-closing" HTML tags (e.g., `<i />` → `<i></i>`)
106585
- * 5. Normalize compact ATX headings (e.g., `#Heading``# Heading`)
106586
- * 6. Replace snake_case component names with parser-safe placeholders
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(remarkBreaks) // Must precede evaluateExpressions to avoid splitting the \n in an evaluated template literal into a <br> node
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', [htmlBlockComponentFromMarkdown(), jsxTableFromMarkdown(), mdxExpressionFromMarkdown()])
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