safe-mdx 0.0.5 → 0.0.6

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.
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import React from 'react';
3
2
  import dedent from 'dedent';
4
- import { test, expect } from 'vitest';
5
- import { MdastToJsx } from './safe-mdx.js';
3
+ import React from 'react';
6
4
  import { renderToStaticMarkup } from 'react-dom/server';
5
+ import { expect, test } from 'vitest';
6
+ import { mdastBfs, MdastToJsx, mdxParse } from './safe-mdx.js';
7
7
  void React;
8
8
  const components = {
9
9
  Heading({ level, children }) {
@@ -17,15 +17,78 @@ function render(code) {
17
17
  // console.log(JSON.stringify(result, null, 2))
18
18
  return { result, errors: visitor.errors || [], html };
19
19
  }
20
+ test('remark and jsx does not wrap in p', () => {
21
+ const code = dedent `
22
+ # Hello
23
+
24
+ i am a paragraph
25
+
26
+ <Heading>heading</Heading>
27
+
28
+ something
29
+ `;
30
+ const mdast = mdxParse(code);
31
+ mdastBfs(mdast, (x) => {
32
+ delete x.position;
33
+ });
34
+ expect(mdast).toMatchInlineSnapshot(`
35
+ {
36
+ "children": [
37
+ {
38
+ "children": [
39
+ {
40
+ "type": "text",
41
+ "value": "Hello",
42
+ },
43
+ ],
44
+ "depth": 1,
45
+ "type": "heading",
46
+ },
47
+ {
48
+ "children": [
49
+ {
50
+ "type": "text",
51
+ "value": "i am a paragraph",
52
+ },
53
+ ],
54
+ "type": "paragraph",
55
+ },
56
+ {
57
+ "attributes": [],
58
+ "children": [
59
+ {
60
+ "type": "text",
61
+ "value": "heading",
62
+ },
63
+ ],
64
+ "name": "Heading",
65
+ "type": "mdxJsxFlowElement",
66
+ },
67
+ {
68
+ "children": [
69
+ {
70
+ "type": "text",
71
+ "value": "something",
72
+ },
73
+ ],
74
+ "type": "paragraph",
75
+ },
76
+ ],
77
+ "type": "root",
78
+ }
79
+ `);
80
+ });
20
81
  test('basic', () => {
21
82
  expect(render(dedent `
22
83
  # Hello
23
84
 
24
85
  i am a paragraph
86
+
87
+ <Heading>heading</Heading>
25
88
  `)).toMatchInlineSnapshot(`
26
89
  {
27
90
  "errors": [],
28
- "html": "<h1>Hello</h1><p>i am a paragraph</p>",
91
+ "html": "<h1>Hello</h1><p>i am a paragraph</p><h1>heading</h1>",
29
92
  "result": <React.Fragment>
30
93
  <h1>
31
94
  Hello
@@ -33,6 +96,9 @@ test('basic', () => {
33
96
  <p>
34
97
  i am a paragraph
35
98
  </p>
99
+ <Heading>
100
+ heading
101
+ </Heading>
36
102
  </React.Fragment>,
37
103
  }
38
104
  `);
@@ -192,15 +258,13 @@ test('inline jsx', () => {
192
258
  `)).toMatchInlineSnapshot(`
193
259
  {
194
260
  "errors": [],
195
- "html": "<p><h1>hello</h1></p>",
261
+ "html": "<h1>hello</h1>",
196
262
  "result": <React.Fragment>
197
- <p>
198
- <Heading
199
- level={2}
200
- >
201
- hello
202
- </Heading>
203
- </p>
263
+ <Heading
264
+ level={2}
265
+ >
266
+ hello
267
+ </Heading>
204
268
  </React.Fragment>,
205
269
  }
206
270
  `);
@@ -764,11 +828,41 @@ test('kitchen sink', () => {
764
828
  `)).toMatchInlineSnapshot(`
765
829
  {
766
830
  "errors": [
831
+ {
832
+ "message": "Unsupported language no-highlight",
833
+ },
834
+ {
835
+ "message": "Unsupported language no-highlight",
836
+ },
837
+ {
838
+ "message": "Unsupported language no-highlight",
839
+ },
840
+ {
841
+ "message": "Unsupported language no-highlight",
842
+ },
843
+ {
844
+ "message": "Unsupported language no-highlight",
845
+ },
846
+ {
847
+ "message": "Unsupported language no-highlight",
848
+ },
849
+ {
850
+ "message": "Unsupported language no-highlight",
851
+ },
852
+ {
853
+ "message": "Unsupported language no-highlight",
854
+ },
767
855
  {
768
856
  "message": "Unsupported jsx component dl",
769
857
  },
858
+ {
859
+ "message": "Unsupported language no-highlight",
860
+ },
861
+ {
862
+ "message": "Unsupported language no-highlight",
863
+ },
770
864
  ],
771
- "html": "<h1>Markdown Kitchen Sink</h1><p>This file is <a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet" title="">https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet</a> plus a few fixes and additions. Used by <a href="https://github.com/obedm503/bootmark" title="">obedm503/bootmark</a> to <a href="https://obedm503.github.io/bootmark/docs/markdown-cheatsheet.html" title="">demonstrate</a> it&#x27;s styling features.</p><p>This is intended as a quick reference and showcase. For more complete info, see <a href="http://daringfireball.net/projects/markdown/" title="">John Gruber&#x27;s original spec</a> and the <a href="http://github.github.com/github-flavored-markdown/" title="">Github-flavored Markdown info page</a>.</p><p>Note that there is also a <a href="./Markdown-Here-Cheatsheet" title="">Cheatsheet specific to Markdown Here</a> if that&#x27;s what you&#x27;re looking for. You can also check out <a href="./Other-Markdown-Tools" title="">more Markdown tools</a>.</p><h5>Table of Contents</h5><p><a href="#headers" title="">Headers</a><br/><a href="#emphasis" title="">Emphasis</a><br/><a href="#lists" title="">Lists</a><br/><a href="#links" title="">Links</a><br/><a href="#images" title="">Images</a><br/><a href="#code" title="">Code and Syntax Highlighting</a><br/><a href="#tables" title="">Tables</a><br/><a href="#blockquotes" title="">Blockquotes</a><br/><a href="#html" title="">Inline HTML</a><br/><a href="#hr" title="">Horizontal Rule</a><br/><a href="#lines" title="">Line Breaks</a><br/><a href="#videos" title="">YouTube Videos</a></p><a name="headers"></a><h2>Headers</h2><h1>H1</h1><h2>H2</h2><h3>H3</h3><h4>H4</h4><h5>H5</h5><h6>H6</h6><p>Alternatively, for H1 and H2, an underline-ish style:</p><h1>Alt-H1</h1><h2>Alt-H2</h2><h1>H1</h1><h2>H2</h2><h3>H3</h3><h4>H4</h4><h5>H5</h5><h6>H6</h6><p>Alternatively, for H1 and H2, an underline-ish style:</p><h1>Alt-H1</h1><h2>Alt-H2</h2><a name="emphasis"></a><h2>Emphasis</h2><pre><code>Emphasis, aka italics, with *asterisks* or _underscores_.
865
+ "html": "<link rel="preload" as="image" href="https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png"/><h1>Markdown Kitchen Sink</h1><p>This file is <a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet" title="">https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet</a> plus a few fixes and additions. Used by <a href="https://github.com/obedm503/bootmark" title="">obedm503/bootmark</a> to <a href="https://obedm503.github.io/bootmark/docs/markdown-cheatsheet.html" title="">demonstrate</a> it&#x27;s styling features.</p><p>This is intended as a quick reference and showcase. For more complete info, see <a href="http://daringfireball.net/projects/markdown/" title="">John Gruber&#x27;s original spec</a> and the <a href="http://github.github.com/github-flavored-markdown/" title="">Github-flavored Markdown info page</a>.</p><p>Note that there is also a <a href="./Markdown-Here-Cheatsheet" title="">Cheatsheet specific to Markdown Here</a> if that&#x27;s what you&#x27;re looking for. You can also check out <a href="./Other-Markdown-Tools" title="">more Markdown tools</a>.</p><h5>Table of Contents</h5><p><a href="#headers" title="">Headers</a><br/><a href="#emphasis" title="">Emphasis</a><br/><a href="#lists" title="">Lists</a><br/><a href="#links" title="">Links</a><br/><a href="#images" title="">Images</a><br/><a href="#code" title="">Code and Syntax Highlighting</a><br/><a href="#tables" title="">Tables</a><br/><a href="#blockquotes" title="">Blockquotes</a><br/><a href="#html" title="">Inline HTML</a><br/><a href="#hr" title="">Horizontal Rule</a><br/><a href="#lines" title="">Line Breaks</a><br/><a href="#videos" title="">YouTube Videos</a></p><a name="headers"></a><h2>Headers</h2><h1>H1</h1><h2>H2</h2><h3>H3</h3><h4>H4</h4><h5>H5</h5><h6>H6</h6><p>Alternatively, for H1 and H2, an underline-ish style:</p><h1>Alt-H1</h1><h2>Alt-H2</h2><h1>H1</h1><h2>H2</h2><h3>H3</h3><h4>H4</h4><h5>H5</h5><h6>H6</h6><p>Alternatively, for H1 and H2, an underline-ish style:</p><h1>Alt-H1</h1><h2>Alt-H2</h2><a name="emphasis"></a><h2>Emphasis</h2><pre><code>Emphasis, aka italics, with *asterisks* or _underscores_.
772
866
 
773
867
  Strong emphasis, aka bold, with **asterisks** or __underscores__.
774
868
 
@@ -821,11 +915,11 @@ test('kitchen sink', () => {
821
915
 
822
916
  [logo]: https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png &quot;Logo Title Text 2&quot;</code></pre><p>Here&#x27;s our logo (hover to see the title text):</p><p>Inline-style:
823
917
  <img src="https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png" alt="alt text" title="Logo Title Text 1"/></p><p>Reference-style:
824
- </p><a name="code"></a><h2>Code and Syntax Highlighting</h2><p>Code blocks are part of the Markdown spec, but syntax highlighting isn&#x27;t. However, many renderers -- like Github&#x27;s and <em>Markdown Here</em> -- support syntax highlighting. Which languages are supported and how those language names should be written will vary from renderer to renderer. <em>Markdown Here</em> supports highlighting for dozens of languages (and not-really-languages, like diffs and HTTP headers); to see the complete list, and how to write the language names, see the <a href="http://softwaremaniacs.org/media/soft/highlight/test.html" title="">highlight.js demo page</a>.</p><pre><code>Inline \`code\` has \`back-ticks around\` it.</code></pre><p>Inline <code>code</code> has <code>back-ticks around</code> it.</p><p>Blocks of code are either fenced by lines with three back-ticks <code>\`\`\`</code>, or are indented with four spaces. I recommend only using the fenced code blocks -- they&#x27;re easier and only they support syntax highlighting.</p><pre><code>var s = &quot;JavaScript syntax highlighting&quot;;
825
- alert(s);</code></pre><pre><code>s = &quot;Python syntax highlighting&quot;
918
+ </p><a name="code"></a><h2>Code and Syntax Highlighting</h2><p>Code blocks are part of the Markdown spec, but syntax highlighting isn&#x27;t. However, many renderers -- like Github&#x27;s and <em>Markdown Here</em> -- support syntax highlighting. Which languages are supported and how those language names should be written will vary from renderer to renderer. <em>Markdown Here</em> supports highlighting for dozens of languages (and not-really-languages, like diffs and HTTP headers); to see the complete list, and how to write the language names, see the <a href="http://softwaremaniacs.org/media/soft/highlight/test.html" title="">highlight.js demo page</a>.</p><pre><code>Inline \`code\` has \`back-ticks around\` it.</code></pre><p>Inline <code>code</code> has <code>back-ticks around</code> it.</p><p>Blocks of code are either fenced by lines with three back-ticks <code>\`\`\`</code>, or are indented with four spaces. I recommend only using the fenced code blocks -- they&#x27;re easier and only they support syntax highlighting.</p><pre><code class="language-javascript">var s = &quot;JavaScript syntax highlighting&quot;;
919
+ alert(s);</code></pre><pre><code class="language-python">s = &quot;Python syntax highlighting&quot;
826
920
  print s</code></pre><pre><code>No language indicated, so no syntax highlighting.
827
- But let&#x27;s throw in a &amp;lt;b&amp;gt;tag&amp;lt;/b&amp;gt;.</code></pre><pre><code>var s = &quot;JavaScript syntax highlighting&quot;;
828
- alert(s);</code></pre><pre><code>s = &quot;Python syntax highlighting&quot;
921
+ But let&#x27;s throw in a &amp;lt;b&amp;gt;tag&amp;lt;/b&amp;gt;.</code></pre><pre><code class="language-javascript">var s = &quot;JavaScript syntax highlighting&quot;;
922
+ alert(s);</code></pre><pre><code class="language-python">s = &quot;Python syntax highlighting&quot;
829
923
  print s</code></pre><pre><code>No language indicated, so no syntax highlighting in Markdown Here (varies on Github).
830
924
  But let&#x27;s throw in a &lt;b&gt;tag&lt;/b&gt;.</code></pre><a name="tables"></a><h2>Tables</h2><p>Tables aren&#x27;t part of the core Markdown spec, but they are part of GFM and <em>Markdown Here</em> supports them. They are an easy way of adding tables to your email -- a task that would otherwise require copy-pasting from another application.</p><pre><code>Colons can be used to align columns.
831
925
 
@@ -1418,13 +1512,17 @@ test('kitchen sink', () => {
1418
1512
  , or are indented with four spaces. I recommend only using the fenced code blocks -- they're easier and only they support syntax highlighting.
1419
1513
  </p>
1420
1514
  <pre>
1421
- <code>
1515
+ <code
1516
+ className="language-javascript"
1517
+ >
1422
1518
  var s = "JavaScript syntax highlighting";
1423
1519
  alert(s);
1424
1520
  </code>
1425
1521
  </pre>
1426
1522
  <pre>
1427
- <code>
1523
+ <code
1524
+ className="language-python"
1525
+ >
1428
1526
  s = "Python syntax highlighting"
1429
1527
  print s
1430
1528
  </code>
@@ -1436,13 +1534,17 @@ test('kitchen sink', () => {
1436
1534
  </code>
1437
1535
  </pre>
1438
1536
  <pre>
1439
- <code>
1537
+ <code
1538
+ className="language-javascript"
1539
+ >
1440
1540
  var s = "JavaScript syntax highlighting";
1441
1541
  alert(s);
1442
1542
  </code>
1443
1543
  </pre>
1444
1544
  <pre>
1445
- <code>
1545
+ <code
1546
+ className="language-python"
1547
+ >
1446
1548
  s = "Python syntax highlighting"
1447
1549
  print s
1448
1550
  </code>
@@ -1815,4 +1917,40 @@ test('kitchen sink', () => {
1815
1917
  }
1816
1918
  `);
1817
1919
  });
1920
+ test('code block rendering', () => {
1921
+ const code = dedent `
1922
+ `;
1923
+ expect(render(dedent `
1924
+ \`\`\`typescript
1925
+ const x = 1;
1926
+ \`\`\`
1927
+
1928
+ \`\`\`invalid-language
1929
+ const y = 2;
1930
+ \`\`\`
1931
+ `)).toMatchInlineSnapshot(`
1932
+ {
1933
+ "errors": [
1934
+ {
1935
+ "message": "Unsupported language invalid-language",
1936
+ },
1937
+ ],
1938
+ "html": "<pre><code class="language-typescript">const x = 1;</code></pre><pre><code>const y = 2;</code></pre>",
1939
+ "result": <React.Fragment>
1940
+ <pre>
1941
+ <code
1942
+ className="language-typescript"
1943
+ >
1944
+ const x = 1;
1945
+ </code>
1946
+ </pre>
1947
+ <pre>
1948
+ <code>
1949
+ const y = 2;
1950
+ </code>
1951
+ </pre>
1952
+ </React.Fragment>,
1953
+ }
1954
+ `);
1955
+ });
1818
1956
  //# sourceMappingURL=safe-mdx.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-mdx.test.js","sourceRoot":"","sources":["../src/safe-mdx.test.tsx"],"names":[],"mappings":"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A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA2ZZ,CAAC,CACL,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4hCvB,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"safe-mdx.test.js","sourceRoot":"","sources":["../src/safe-mdx.test.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safe-mdx",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "private": false,
5
5
  "description": "Render MDX in React without eval",
6
6
  "repository": "https://github.com/holocron-hq/safe-mdx",
@@ -27,27 +27,30 @@
27
27
  "react": "*"
28
28
  },
29
29
  "dependencies": {
30
+ "collapse-white-space": "^2.1.0",
30
31
  "html-to-jsx-transform": "^1.0.0",
31
- "remark": "^15.0.0",
32
+ "remark": "^15.0.1",
32
33
  "remark-frontmatter": "^5.0.0",
33
34
  "remark-gfm": "^4.0.0",
34
- "remark-mdx": "^3.0.0"
35
+ "remark-mdx": "^3.0.0",
36
+ "unified": "^11.0.5",
37
+ "unist-util-visit": "^5.0.0"
35
38
  },
36
39
  "devDependencies": {
37
40
  "@types/mdast": "^4.0.0",
38
41
  "@types/node": "^20.0.0",
39
42
  "@types/react": "^18.3.11",
40
43
  "@types/react-dom": "^18.0.0",
41
- "@vitest/coverage-v8": "^1.0.0",
44
+ "@vitest/coverage-v8": "^1.6.0",
42
45
  "dedent": "^1.5.1",
43
- "mdast-util-mdx-jsx": "^3.0.0",
44
- "react": "^18.3.1",
45
- "react-dom": "^18.3.1",
46
+ "mdast-util-mdx-jsx": "^3.2.0",
47
+ "react": "^19.0.0",
48
+ "react-dom": "^19.0.0",
46
49
  "typescript": "5.5.2",
47
- "vitest": "^1.6.0"
50
+ "vitest": "^3.1.1"
48
51
  },
49
52
  "scripts": {
50
53
  "build": "tsc",
51
- "test": "vitest run --coverage"
54
+ "test": "vitest"
52
55
  }
53
56
  }
package/src/plugins.ts ADDED
@@ -0,0 +1,87 @@
1
+ import { Root, RootContent } from 'mdast'
2
+ import { collapseWhiteSpace } from 'collapse-white-space'
3
+ import { visit } from 'unist-util-visit'
4
+
5
+
6
+ /**
7
+ * https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
8
+ * A tiny plugin that unravels `<p><h1>x</h1></p>` but also
9
+ * `<p><Component /></p>` (so it has no knowledge of "HTML").
10
+ *
11
+ * It also marks JSX as being explicitly JSX, so when a user passes a `h1`
12
+ * component, it is used for `# heading` but not for `<h1>heading</h1>`.
13
+ *
14
+ */
15
+ export function remarkMarkAndUnravel() {
16
+ return function (tree: Root) {
17
+
18
+ visit(tree, function (node, index, parent) {
19
+ let offset = -1
20
+ let all = true
21
+ let oneOrMore = false
22
+
23
+
24
+ if (
25
+ parent &&
26
+ typeof index === 'number' &&
27
+ node.type === 'paragraph'
28
+ ) {
29
+ const children = node.children
30
+
31
+ while (++offset < children.length) {
32
+ const child = children[offset]
33
+
34
+ if (
35
+ child.type === 'mdxJsxTextElement' ||
36
+ child.type === 'mdxTextExpression'
37
+ ) {
38
+ oneOrMore = true
39
+ } else if (
40
+ child.type === 'text' &&
41
+ collapseWhiteSpace(child.value, {
42
+ style: 'html',
43
+ trim: true,
44
+ }) === ''
45
+ ) {
46
+ // Empty.
47
+ } else {
48
+ all = false
49
+ break
50
+ }
51
+ }
52
+
53
+ if (all && oneOrMore) {
54
+ offset = -1
55
+
56
+ const newChildren: RootContent[] = []
57
+
58
+ while (++offset < children.length) {
59
+ const child = children[offset]
60
+
61
+ if (child.type === 'mdxJsxTextElement') {
62
+ // @ts-expect-error: mutate because it is faster; content model is fine.
63
+ child.type = 'mdxJsxFlowElement'
64
+ }
65
+
66
+ if (child.type === 'mdxTextExpression') {
67
+ // @ts-expect-error: mutate because it is faster; content model is fine.
68
+ child.type = 'mdxFlowExpression'
69
+ }
70
+
71
+ if (
72
+ child.type === 'text' &&
73
+ /^[\t\r\n ]+$/.test(String(child.value))
74
+ ) {
75
+ // Empty.
76
+ } else {
77
+ newChildren.push(child)
78
+ }
79
+ }
80
+
81
+ parent.children.splice(index, 1, ...newChildren)
82
+ return index
83
+ }
84
+ }
85
+ })
86
+ }
87
+ }