-
Notifications
You must be signed in to change notification settings - Fork 12
/
prepare-mdx.ts
103 lines (84 loc) · 2.21 KB
/
prepare-mdx.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import path from 'path'
import {remarkMdxImages} from 'remark-mdx-images'
const getRehypeMdxCodeMeta = async () => {
const {visit} = await import('unist-util-visit')
return (options = {}) => {
return tree => {
visit(tree, 'element', visitor)
}
function visitor(node, index, parentNode) {
if (node.tagName === 'code' && node.data && node.data.meta) {
const blocks = node.data.meta.split(' ') as string[]
node.properties = blocks.reduce((props, block) => {
const [prop, value] = block.split('=')
if (typeof value === 'undefined') {
props.line = prop
return props
}
props[prop] = value
return props
}, node.properties)
}
}
}
}
export const prepareMDX = async (
source: string,
options: {
files?: Record<string, string>
directory?: string
imagesUrl?: string
}
) => {
if (process.platform === 'win32') {
process.env.ESBUILD_BINARY_PATH = path.join(
process.cwd(),
'node_modules',
'esbuild-windows-64',
'esbuild.exe'
)
} else {
process.env.ESBUILD_BINARY_PATH = path.join(
process.cwd(),
'node_modules',
'esbuild',
'bin',
'esbuild'
)
}
const {bundleMDX} = await import('mdx-bundler')
const {directory, imagesUrl} = options
const gfm = (await import('remark-gfm')) as any
const rehypeMdxCodeMeta = await getRehypeMdxCodeMeta()
const {code, errors} = await bundleMDX(source, {
cwd: directory,
xdmOptions: options => {
options.remarkPlugins = [
...(options.remarkPlugins ?? []),
gfm,
remarkMdxImages
]
options.rehypePlugins = [
...(options.rehypePlugins ?? []),
rehypeMdxCodeMeta
]
return options
},
esbuildOptions: options => {
options.outdir = path.join(process.cwd(), 'public', imagesUrl)
options.loader = {
...options.loader,
'.png': 'file',
'.jpg': 'file',
'.gif': 'file'
}
options.publicPath = imagesUrl
options.write = true
return options
}
})
if (errors.length > 0) {
console.dir(errors.map(({detail}) => detail))
}
return code
}