safe-mdx 0.0.6 → 0.1.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/src/safe-mdx.tsx CHANGED
@@ -3,6 +3,9 @@ import { htmlToJsx } from 'html-to-jsx-transform'
3
3
  import { Node, Parent, RootContent } from 'mdast'
4
4
  import remarkFrontmatter from 'remark-frontmatter'
5
5
 
6
+ import { collapseWhiteSpace } from 'collapse-white-space'
7
+ import { visit } from 'unist-util-visit'
8
+
6
9
  import { Root, Yaml } from 'mdast'
7
10
  import { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx'
8
11
  import { remark } from 'remark'
@@ -10,34 +13,44 @@ import remarkGfm from 'remark-gfm'
10
13
  import remarkMdx from 'remark-mdx'
11
14
 
12
15
  import { Fragment, ReactNode } from 'react'
13
- import { remarkMarkAndUnravel } from './plugins.js'
14
16
 
15
17
  type MyRootContent = RootContent | Root
16
18
 
17
- const processor = remark()
18
- .use(remarkMdx)
19
- .use(remarkMarkAndUnravel)
20
- .use(remarkFrontmatter, ['yaml', 'toml'])
21
- .use(remarkGfm)
22
- .use(() => {
23
- return (tree, file) => {
24
- file.data.ast = tree
25
- }
26
- })
27
-
28
19
  export function mdxParse(code: string) {
29
- const file = processor.processSync(code)
20
+ const file = mdxProcessor.processSync(code)
30
21
  return file.data.ast as Root
31
22
  }
32
23
 
33
- void React
24
+ declare module 'mdast' {
25
+ export interface Data {
26
+ hProperties?: {
27
+ id?: string
28
+ }
29
+ }
30
+ }
31
+
32
+ export type CustomTransformer = (
33
+ node: MyRootContent,
34
+ transform: (node: MyRootContent) => ReactNode,
35
+ ) => ReactNode | undefined
34
36
 
35
37
  export function SafeMdxRenderer({
36
38
  components,
37
39
  code = '',
38
40
  mdast = null as any,
41
+ customTransformer,
42
+ }: {
43
+ components?: ComponentsMap
44
+ code?: string
45
+ mdast?: MyRootContent
46
+ customTransformer?: CustomTransformer
39
47
  }) {
40
- const visitor = new MdastToJsx({ code, mdast, components })
48
+ const visitor = new MdastToJsx({
49
+ code,
50
+ mdast,
51
+ components,
52
+ customTransformer,
53
+ })
41
54
  const result = visitor.run()
42
55
  return result
43
56
  }
@@ -48,13 +61,25 @@ export class MdastToJsx {
48
61
  jsxStr: string = ''
49
62
  c: ComponentsMap
50
63
  errors: { message: string }[] = []
64
+ customTransformer?: CustomTransformer
65
+
51
66
  constructor({
52
67
  code = '',
53
68
  mdast = undefined as any,
54
69
  components = {} as ComponentsMap,
70
+ customTransformer,
71
+ }: {
72
+ code?: string
73
+ mdast?: MyRootContent
74
+ components?: ComponentsMap
75
+ customTransformer?: (
76
+ node: MyRootContent,
77
+ transform: (node: MyRootContent) => ReactNode,
78
+ ) => ReactNode | undefined
55
79
  }) {
56
80
  this.str = code
57
81
  this.mdast = mdast || mdxParse(code)
82
+ this.customTransformer = customTransformer
58
83
 
59
84
  this.c = {
60
85
  ...Object.fromEntries(
@@ -150,6 +175,17 @@ export class MdastToJsx {
150
175
  return []
151
176
  }
152
177
 
178
+ // Check for custom transformer first, giving it higher priority
179
+ if (this.customTransformer) {
180
+ const customResult = this.customTransformer(
181
+ node,
182
+ this.mdastTransformer.bind(this),
183
+ )
184
+ if (customResult !== undefined) {
185
+ return customResult
186
+ }
187
+ }
188
+
153
189
  switch (node.type) {
154
190
  case 'mdxjsEsm': {
155
191
  const start = node.position?.start?.offset
@@ -192,16 +228,24 @@ export class MdastToJsx {
192
228
  }
193
229
  case 'heading': {
194
230
  const level = node.depth
195
-
196
231
  const Tag = this.c[`h${level}`] ?? `h${level}`
197
- return <Tag>{this.mapMdastChildren(node)}</Tag>
232
+
233
+ return (
234
+ <Tag {...node.data?.hProperties}>
235
+ {this.mapMdastChildren(node)}
236
+ </Tag>
237
+ )
198
238
  }
199
239
  case 'paragraph': {
200
- return <this.c.p>{this.mapMdastChildren(node)}</this.c.p>
240
+ return (
241
+ <this.c.p {...node.data?.hProperties}>
242
+ {this.mapMdastChildren(node)}
243
+ </this.c.p>
244
+ )
201
245
  }
202
246
  case 'blockquote': {
203
247
  return (
204
- <this.c.blockquote>
248
+ <this.c.blockquote {...node.data?.hProperties}>
205
249
  {this.mapMdastChildren(node)}
206
250
  </this.c.blockquote>
207
251
  )
@@ -216,7 +260,7 @@ export class MdastToJsx {
216
260
  const language = node.lang || ''
217
261
  const code = node.value
218
262
  const codeBlock = (className?: string) => (
219
- <this.c.pre>
263
+ <this.c.pre {...node.data?.hProperties}>
220
264
  <this.c.code className={className}>{code}</this.c.code>
221
265
  </this.c.pre>
222
266
  )
@@ -241,23 +285,37 @@ export class MdastToJsx {
241
285
  case 'list': {
242
286
  if (node.ordered) {
243
287
  return (
244
- <this.c.ol start={node.start!}>
288
+ <this.c.ol
289
+ start={node.start!}
290
+ {...node.data?.hProperties}
291
+ >
245
292
  {this.mapMdastChildren(node)}
246
293
  </this.c.ol>
247
294
  )
248
295
  }
249
- return <this.c.ul>{this.mapMdastChildren(node)}</this.c.ul>
296
+ return (
297
+ <this.c.ul {...node.data?.hProperties}>
298
+ {this.mapMdastChildren(node)}
299
+ </this.c.ul>
300
+ )
250
301
  }
251
302
  case 'listItem': {
252
303
  // https://github.com/syntax-tree/mdast-util-gfm-task-list-item#syntax-tree
253
304
  if (node?.checked != null) {
254
305
  return (
255
- <this.c.li data-checked={node.checked}>
306
+ <this.c.li
307
+ data-checked={node.checked}
308
+ {...node.data?.hProperties}
309
+ >
256
310
  {this.mapMdastChildren(node)}
257
311
  </this.c.li>
258
312
  )
259
313
  }
260
- return <this.c.li>{this.mapMdastChildren(node)}</this.c.li>
314
+ return (
315
+ <this.c.li {...node.data?.hProperties}>
316
+ {this.mapMdastChildren(node)}
317
+ </this.c.li>
318
+ )
261
319
  }
262
320
  case 'text': {
263
321
  if (!node.value) {
@@ -269,33 +327,54 @@ export class MdastToJsx {
269
327
  const src = node.url || ''
270
328
  const alt = node.alt || ''
271
329
  const title = node.title || ''
272
- return <this.c.img src={src} alt={alt} title={title} />
330
+ return (
331
+ <this.c.img
332
+ src={src}
333
+ alt={alt}
334
+ title={title}
335
+ {...node.data?.hProperties}
336
+ />
337
+ )
273
338
  }
274
339
  case 'link': {
275
340
  const href = node.url || ''
276
341
  const title = node.title || ''
277
342
  return (
278
- <this.c.a {...{ href, title }}>
343
+ <this.c.a {...{ href, title }} {...node.data?.hProperties}>
279
344
  {this.mapMdastChildren(node)}
280
345
  </this.c.a>
281
346
  )
282
347
  }
283
348
  case 'strong': {
284
349
  return (
285
- <this.c.strong>{this.mapMdastChildren(node)}</this.c.strong>
350
+ <this.c.strong {...node.data?.hProperties}>
351
+ {this.mapMdastChildren(node)}
352
+ </this.c.strong>
286
353
  )
287
354
  }
288
355
  case 'emphasis': {
289
- return <this.c.em>{this.mapMdastChildren(node)}</this.c.em>
356
+ return (
357
+ <this.c.em {...node.data?.hProperties}>
358
+ {this.mapMdastChildren(node)}
359
+ </this.c.em>
360
+ )
290
361
  }
291
362
  case 'delete': {
292
- return <this.c.del>{this.mapMdastChildren(node)}</this.c.del>
363
+ return (
364
+ <this.c.del {...node.data?.hProperties}>
365
+ {this.mapMdastChildren(node)}
366
+ </this.c.del>
367
+ )
293
368
  }
294
369
  case 'inlineCode': {
295
370
  if (!node.value) {
296
371
  return []
297
372
  }
298
- return <this.c.code>{node.value}</this.c.code>
373
+ return (
374
+ <this.c.code {...node.data?.hProperties}>
375
+ {node.value}
376
+ </this.c.code>
377
+ )
299
378
  }
300
379
  case 'break': {
301
380
  return <this.c.br />
@@ -308,7 +387,7 @@ export class MdastToJsx {
308
387
  this.mapMdastChildren(node),
309
388
  )
310
389
  return (
311
- <this.c.table>
390
+ <this.c.table {...node.data?.hProperties}>
312
391
  {head && <this.c.thead>{head}</this.c.thead>}
313
392
  {!!body?.length && <this.c.tbody>{body}</this.c.tbody>}
314
393
  </this.c.table>
@@ -316,15 +395,18 @@ export class MdastToJsx {
316
395
  }
317
396
  case 'tableRow': {
318
397
  return (
319
- <this.c.tr className=''>
398
+ <this.c.tr className='' {...node.data?.hProperties}>
320
399
  {this.mapMdastChildren(node)}
321
400
  </this.c.tr>
322
401
  )
323
402
  }
324
403
  case 'tableCell': {
325
404
  let content = this.mapMdastChildren(node)
326
-
327
- return <this.c.td className=''>{content}</this.c.td>
405
+ return (
406
+ <this.c.td className='' {...node.data?.hProperties}>
407
+ {content}
408
+ </this.c.td>
409
+ )
328
410
  }
329
411
  case 'definition': {
330
412
  return []
@@ -341,7 +423,7 @@ export class MdastToJsx {
341
423
  })
342
424
 
343
425
  return (
344
- <this.c.a href={href}>
426
+ <this.c.a href={href} {...node.data?.hProperties}>
345
427
  {this.mapMdastChildren(node)}
346
428
  </this.c.a>
347
429
  )
@@ -403,10 +485,9 @@ export function getJsxAttrs(
403
485
  .map((attr) => {
404
486
  if (attr.type === 'mdxJsxExpressionAttribute') {
405
487
  onError({
406
- message: `Expressions in jsx props are not supported (${attr.value.replace(
407
- /\n+/g,
408
- ' ',
409
- )})`,
488
+ message: `Expressions in jsx props are not supported (${attr.value
489
+ .replace(/\n+/g, ' ')
490
+ .replace(/ +/g, ' ')})`,
410
491
  })
411
492
  return
412
493
  }
@@ -553,6 +634,22 @@ const nativeTags = [
553
634
  'video',
554
635
  'code',
555
636
  'pre',
637
+ 'figure',
638
+ 'canvas',
639
+ 'details',
640
+ 'dl',
641
+ 'dt',
642
+ 'dd',
643
+ 'fieldset',
644
+ 'footer',
645
+ 'header',
646
+ 'legend',
647
+ 'main',
648
+ 'mark',
649
+ 'nav',
650
+ 'progress',
651
+ 'summary',
652
+ 'time',
556
653
  ] as const
557
654
 
558
655
  const supportedLanguages = [
@@ -836,4 +933,98 @@ const supportedLanguages = [
836
933
  ] as const
837
934
  const supportedLanguagesSet = new Set(supportedLanguages)
838
935
 
839
- type ComponentsMap = { [k in (typeof nativeTags)[number]]?: any }
936
+ type ComponentsMap = { [k in (typeof nativeTags)[number]]?: any } & {
937
+ [key: string]: any
938
+ }
939
+
940
+ /**
941
+ * https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
942
+ * A tiny plugin that unravels `<p><h1>x</h1></p>` but also
943
+ * `<p><Component /></p>` (so it has no knowledge of "HTML").
944
+ *
945
+ * It also marks JSX as being explicitly JSX, so when a user passes a `h1`
946
+ * component, it is used for `# heading` but not for `<h1>heading</h1>`.
947
+ *
948
+ */
949
+ export function remarkMarkAndUnravel() {
950
+ return function (tree: Root) {
951
+ visit(tree, function (node, index, parent) {
952
+ let offset = -1
953
+ let all = true
954
+ let oneOrMore = false
955
+
956
+ if (
957
+ parent &&
958
+ typeof index === 'number' &&
959
+ node.type === 'paragraph'
960
+ ) {
961
+ const children = node.children
962
+
963
+ while (++offset < children.length) {
964
+ const child = children[offset]
965
+
966
+ if (
967
+ child.type === 'mdxJsxTextElement' ||
968
+ child.type === 'mdxTextExpression'
969
+ ) {
970
+ oneOrMore = true
971
+ } else if (
972
+ child.type === 'text' &&
973
+ collapseWhiteSpace(child.value, {
974
+ style: 'html',
975
+ trim: true,
976
+ }) === ''
977
+ ) {
978
+ // Empty.
979
+ } else {
980
+ all = false
981
+ break
982
+ }
983
+ }
984
+
985
+ if (all && oneOrMore) {
986
+ offset = -1
987
+
988
+ const newChildren: RootContent[] = []
989
+
990
+ while (++offset < children.length) {
991
+ const child = children[offset]
992
+
993
+ if (child.type === 'mdxJsxTextElement') {
994
+ // @ts-expect-error: mutate because it is faster; content model is fine.
995
+ child.type = 'mdxJsxFlowElement'
996
+ }
997
+
998
+ if (child.type === 'mdxTextExpression') {
999
+ // @ts-expect-error: mutate because it is faster; content model is fine.
1000
+ child.type = 'mdxFlowExpression'
1001
+ }
1002
+
1003
+ if (
1004
+ child.type === 'text' &&
1005
+ /^[\t\r\n ]+$/.test(String(child.value))
1006
+ ) {
1007
+ // Empty.
1008
+ } else {
1009
+ newChildren.push(child)
1010
+ }
1011
+ }
1012
+
1013
+ parent.children.splice(index, 1, ...newChildren)
1014
+ return index
1015
+ }
1016
+ }
1017
+ })
1018
+ }
1019
+ }
1020
+
1021
+ const mdxProcessor = remark()
1022
+ .use(remarkMdx)
1023
+ .use(remarkFrontmatter, ['yaml', 'toml'])
1024
+ .use(remarkGfm)
1025
+ .use(remarkMarkAndUnravel)
1026
+ .use(() => {
1027
+ return (tree, file) => {
1028
+ file.data.ast = tree
1029
+ }
1030
+ })
package/dist/plugins.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import { Root } from 'mdast';
2
- /**
3
- * https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
4
- * A tiny plugin that unravels `<p><h1>x</h1></p>` but also
5
- * `<p><Component /></p>` (so it has no knowledge of "HTML").
6
- *
7
- * It also marks JSX as being explicitly JSX, so when a user passes a `h1`
8
- * component, it is used for `# heading` but not for `<h1>heading</h1>`.
9
- *
10
- */
11
- export declare function remarkMarkAndUnravel(): (tree: Root) => void;
12
- //# sourceMappingURL=plugins.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAe,MAAM,OAAO,CAAA;AAKzC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,WACT,IAAI,UAuE9B"}
package/dist/plugins.js DELETED
@@ -1,68 +0,0 @@
1
- import { collapseWhiteSpace } from 'collapse-white-space';
2
- import { visit } from 'unist-util-visit';
3
- /**
4
- * https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
5
- * A tiny plugin that unravels `<p><h1>x</h1></p>` but also
6
- * `<p><Component /></p>` (so it has no knowledge of "HTML").
7
- *
8
- * It also marks JSX as being explicitly JSX, so when a user passes a `h1`
9
- * component, it is used for `# heading` but not for `<h1>heading</h1>`.
10
- *
11
- */
12
- export function remarkMarkAndUnravel() {
13
- return function (tree) {
14
- visit(tree, function (node, index, parent) {
15
- let offset = -1;
16
- let all = true;
17
- let oneOrMore = false;
18
- if (parent &&
19
- typeof index === 'number' &&
20
- node.type === 'paragraph') {
21
- const children = node.children;
22
- while (++offset < children.length) {
23
- const child = children[offset];
24
- if (child.type === 'mdxJsxTextElement' ||
25
- child.type === 'mdxTextExpression') {
26
- oneOrMore = true;
27
- }
28
- else if (child.type === 'text' &&
29
- collapseWhiteSpace(child.value, {
30
- style: 'html',
31
- trim: true,
32
- }) === '') {
33
- // Empty.
34
- }
35
- else {
36
- all = false;
37
- break;
38
- }
39
- }
40
- if (all && oneOrMore) {
41
- offset = -1;
42
- const newChildren = [];
43
- while (++offset < children.length) {
44
- const child = children[offset];
45
- if (child.type === 'mdxJsxTextElement') {
46
- // @ts-expect-error: mutate because it is faster; content model is fine.
47
- child.type = 'mdxJsxFlowElement';
48
- }
49
- if (child.type === 'mdxTextExpression') {
50
- // @ts-expect-error: mutate because it is faster; content model is fine.
51
- child.type = 'mdxFlowExpression';
52
- }
53
- if (child.type === 'text' &&
54
- /^[\t\r\n ]+$/.test(String(child.value))) {
55
- // Empty.
56
- }
57
- else {
58
- newChildren.push(child);
59
- }
60
- }
61
- parent.children.splice(index, 1, ...newChildren);
62
- return index;
63
- }
64
- }
65
- });
66
- };
67
- }
68
- //# sourceMappingURL=plugins.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAGxC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAChC,OAAO,UAAU,IAAU;QAEvB,KAAK,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,KAAK,EAAE,MAAM;YACrC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAA;YACf,IAAI,GAAG,GAAG,IAAI,CAAA;YACd,IAAI,SAAS,GAAG,KAAK,CAAA;YAGrB,IACI,MAAM;gBACN,OAAO,KAAK,KAAK,QAAQ;gBACzB,IAAI,CAAC,IAAI,KAAK,WAAW,EAC3B;gBACE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;gBAE9B,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE;oBAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;oBAE9B,IACI,KAAK,CAAC,IAAI,KAAK,mBAAmB;wBAClC,KAAK,CAAC,IAAI,KAAK,mBAAmB,EACpC;wBACE,SAAS,GAAG,IAAI,CAAA;qBACnB;yBAAM,IACH,KAAK,CAAC,IAAI,KAAK,MAAM;wBACrB,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE;4BAC5B,KAAK,EAAE,MAAM;4BACb,IAAI,EAAE,IAAI;yBACb,CAAC,KAAK,EAAE,EACX;wBACE,SAAS;qBACZ;yBAAM;wBACH,GAAG,GAAG,KAAK,CAAA;wBACX,MAAK;qBACR;iBACJ;gBAED,IAAI,GAAG,IAAI,SAAS,EAAE;oBAClB,MAAM,GAAG,CAAC,CAAC,CAAA;oBAEX,MAAM,WAAW,GAAkB,EAAE,CAAA;oBAErC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE;wBAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;wBAE9B,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE;4BACpC,wEAAwE;4BACxE,KAAK,CAAC,IAAI,GAAG,mBAAmB,CAAA;yBACnC;wBAED,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE;4BACpC,wEAAwE;4BACxE,KAAK,CAAC,IAAI,GAAG,mBAAmB,CAAA;yBACnC;wBAED,IACI,KAAK,CAAC,IAAI,KAAK,MAAM;4BACrB,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAC1C;4BACE,SAAS;yBACZ;6BAAM;4BACH,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;yBAC1B;qBACJ;oBAED,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAA;oBAChD,OAAO,KAAK,CAAA;iBACf;aACJ;QACL,CAAC,CAAC,CAAA;IACN,CAAC,CAAA;AACL,CAAC"}
package/src/plugins.ts DELETED
@@ -1,87 +0,0 @@
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
- }