safe-mdx 1.7.0 → 1.8.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.
Files changed (40) hide show
  1. package/README.md +56 -0
  2. package/dist/html/html-and-md.test.js +14 -41
  3. package/dist/html/html-and-md.test.js.map +1 -1
  4. package/dist/html/html-to-mdx-ast.d.ts +26 -1
  5. package/dist/html/html-to-mdx-ast.d.ts.map +1 -1
  6. package/dist/html/html-to-mdx-ast.js +40 -0
  7. package/dist/html/html-to-mdx-ast.js.map +1 -1
  8. package/dist/incremental-parse.d.ts +41 -0
  9. package/dist/incremental-parse.d.ts.map +1 -0
  10. package/dist/incremental-parse.js +139 -0
  11. package/dist/incremental-parse.js.map +1 -0
  12. package/dist/incremental-parse.test.d.ts +2 -0
  13. package/dist/incremental-parse.test.d.ts.map +1 -0
  14. package/dist/incremental-parse.test.js +299 -0
  15. package/dist/incremental-parse.test.js.map +1 -0
  16. package/dist/markdown-html.test.d.ts +2 -0
  17. package/dist/markdown-html.test.d.ts.map +1 -0
  18. package/dist/markdown-html.test.js +129 -0
  19. package/dist/markdown-html.test.js.map +1 -0
  20. package/dist/markdown.d.ts +3 -0
  21. package/dist/markdown.d.ts.map +1 -0
  22. package/dist/markdown.js +4 -0
  23. package/dist/markdown.js.map +1 -0
  24. package/dist/parse.d.ts +9 -2
  25. package/dist/parse.d.ts.map +1 -1
  26. package/dist/parse.js +24 -12
  27. package/dist/parse.js.map +1 -1
  28. package/dist/safe-mdx.d.ts.map +1 -1
  29. package/dist/safe-mdx.js +6 -24
  30. package/dist/safe-mdx.js.map +1 -1
  31. package/package.json +9 -1
  32. package/src/html/html-and-md.test.ts +15 -47
  33. package/src/html/html-to-mdx-ast.ts +53 -1
  34. package/src/incremental-parse.test.ts +315 -0
  35. package/src/incremental-parse.ts +219 -0
  36. package/src/markdown-html.test.tsx +144 -0
  37. package/src/markdown.ts +4 -0
  38. package/src/parse.ts +36 -13
  39. package/src/safe-mdx.test.tsx +2 -0
  40. package/src/safe-mdx.tsx +6 -26
package/src/parse.ts CHANGED
@@ -5,9 +5,9 @@ import { Root, RootContent } from 'mdast'
5
5
  import { remark } from 'remark'
6
6
  import remarkGfm from 'remark-gfm'
7
7
  import remarkMdx from 'remark-mdx'
8
- import { parseHtmlToMdxAst, remarkMdxJsxNormalize } from './html/html-to-mdx-ast.ts'
8
+ import { remarkMdxJsxNormalize } from './html/remark-mdx-jsx-normalize.ts'
9
9
 
10
- export { parseHtmlToMdxAst, remarkMdxJsxNormalize }
10
+ export { remarkMdxJsxNormalize }
11
11
 
12
12
  /* ── Import extraction ──────────────────────────────────────────────── */
13
13
 
@@ -34,7 +34,7 @@ export function extractImports(ast: Root): MdxImport[] {
34
34
 
35
35
  for (const node of ast.children) {
36
36
  if (node.type !== 'mdxjsEsm') continue
37
- const estree = (node as any).data?.estree
37
+ const estree = node.data?.estree
38
38
  if (!estree) continue
39
39
 
40
40
  for (const statement of estree.body) {
@@ -70,6 +70,38 @@ export function mdxParse(code: string) {
70
70
  return file.data.ast as Root
71
71
  }
72
72
 
73
+ export type MdxProcessorOptions = {
74
+ /** Extra remark plugins appended after safe-mdx's default MDX, frontmatter, and GFM parsers. */
75
+ remarkPlugins?: any[]
76
+ }
77
+
78
+ export function createMdxProcessor({
79
+ remarkPlugins = [],
80
+ }: MdxProcessorOptions = {}) {
81
+ const processor = remark()
82
+ .use(remarkMdx)
83
+ .use(remarkFrontmatter, ['yaml', 'toml'])
84
+ .use(remarkGfm)
85
+
86
+ for (const plugin of remarkPlugins) {
87
+ if (Array.isArray(plugin)) {
88
+ processor.use(plugin[0], ...plugin.slice(1))
89
+ } else {
90
+ processor.use(plugin)
91
+ }
92
+ }
93
+
94
+ return processor
95
+ .use(remarkMarkAndUnravel)
96
+ .use(() => {
97
+ return (tree, file) => {
98
+ file.data.ast = tree
99
+ }
100
+ })
101
+ }
102
+
103
+ export type MdxProcessor = ReturnType<typeof createMdxProcessor>
104
+
73
105
  /**
74
106
  * https://github.com/mdx-js/mdx/blob/b3351fadcb6f78833a72757b7135dcfb8ab646fe/packages/mdx/lib/plugin/remark-mark-and-unravel.js
75
107
  * A tiny plugin that unravels `<p><h1>x</h1></p>` but also
@@ -262,13 +294,4 @@ export async function resolveModules({
262
294
  return result
263
295
  }
264
296
 
265
- const mdxProcessor = remark()
266
- .use(remarkMdx)
267
- .use(remarkFrontmatter, ['yaml', 'toml'])
268
- .use(remarkGfm)
269
- .use(remarkMarkAndUnravel)
270
- .use(() => {
271
- return (tree, file) => {
272
- file.data.ast = tree
273
- }
274
- })
297
+ export const mdxProcessor = createMdxProcessor()
@@ -4197,3 +4197,5 @@ test('scope with tagged template literal without generate', () => {
4197
4197
  expect(errors).toMatchInlineSnapshot(`[]`)
4198
4198
  expect(html).toMatchInlineSnapshot(`"hello WORLD"`)
4199
4199
  })
4200
+
4201
+
package/src/safe-mdx.tsx CHANGED
@@ -10,8 +10,7 @@ import { Fragment, ReactNode } from 'react'
10
10
  import { DynamicEsmComponent } from 'safe-mdx/client'
11
11
  import { extractComponentInfo, parseEsmImports } from './esm-parser.ts'
12
12
  import { resolveModulePath, type EagerModules } from './parse.ts'
13
- import { htmlToMdxAst } from './html/html-to-mdx-ast.ts'
14
- import { validHtmlElements, nativeTags } from './html/valid-html-elements.ts'
13
+ import { nativeTags } from './html/valid-html-elements.ts'
15
14
 
16
15
  export type MyRootContent = RootContent | Root
17
16
 
@@ -1081,30 +1080,11 @@ export class MdastToJsx {
1081
1080
  return []
1082
1081
  }
1083
1082
  case 'html': {
1084
- const start = node.position?.start?.offset
1085
- const end = node.position?.end?.offset
1086
- const text = this.str.slice(start, end)
1087
- if (!text) {
1088
- return []
1089
- }
1090
-
1091
- // Parse HTML to MDX AST using the new approach - always returns an array
1092
- const mdxAst = htmlToMdxAst({
1093
- html: text,
1094
- parentType: parentType || 'root',
1095
- convertTagName: ({ tagName }) => {
1096
- const lowerTag = tagName.toLowerCase()
1097
- // Only keep valid HTML elements
1098
- if (validHtmlElements.has(lowerTag)) {
1099
- return lowerTag
1100
- }
1101
- // Return empty string for non-HTML elements
1102
- return ''
1103
- }
1104
- })
1105
-
1106
- // Process the MDX AST nodes
1107
- return mdxAst.map(child => this.mdastTransformer(child, 'html'))
1083
+ // html nodes appear when rendering plain markdown (not MDX) without
1084
+ // the remarkHtmlToMdx pre-processing plugin. They are intentionally
1085
+ // ignored here use remarkHtmlToMdx from 'safe-mdx/markdown' to convert
1086
+ // them to mdxJsx nodes before passing the AST to MdastToJsx.
1087
+ return []
1108
1088
  }
1109
1089
  case 'imageReference': {
1110
1090
  return []