index.js
3.32 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const unified = require('unified')
const toMDAST = require('remark-parse')
const remarkMdx = require('remark-mdx')
const squeeze = require('remark-squeeze-paragraphs')
const visit = require('unist-util-visit')
const raw = require('hast-util-raw')
const toMDXAST = require('./md-ast-to-mdx-ast')
const mdxAstToMdxHast = require('./mdx-ast-to-mdx-hast')
const mdxHastToJsx = require('./mdx-hast-to-jsx')
const DEFAULT_OPTIONS = {
footnotes: true,
remarkPlugins: [],
rehypePlugins: [],
compilers: []
}
function createMdxAstCompiler(options) {
const mdPlugins = options.mdPlugins
const remarkPlugins = options.remarkPlugins
const plugins = mdPlugins || remarkPlugins
if (mdPlugins) {
console.error(`
@mdx-js/mdx: The mdPlugins option has been deprecated in favor of remarkPlugins
Support for mdPlugins will be removed in MDX v2
`)
}
const fn = unified()
.use(toMDAST, options)
.use(remarkMdx, options)
.use(squeeze, options)
.use(toMDXAST, options)
plugins.forEach(plugin => {
// Handle [plugin, pluginOptions] syntax
if (Array.isArray(plugin) && plugin.length > 1) {
fn.use(plugin[0], plugin[1])
} else {
fn.use(plugin)
}
})
fn.use(mdxAstToMdxHast, options)
return fn
}
function applyHastPluginsAndCompilers(compiler, options) {
const hastPlugins = options.hastPlugins
const rehypePlugins = options.rehypePlugins
const plugins = hastPlugins || rehypePlugins
if (hastPlugins) {
console.error(`
@mdx-js/mdx: The hastPlugins option has been deprecated in favor of rehypePlugins
Support for hastPlugins will be removed in MDX v2
`)
}
const compilers = options.compilers
// Convert raw nodes into HAST
compiler.use(() => ast => {
visit(ast, 'raw', node => {
const {children, tagName, properties} = raw(node)
node.type = 'element'
node.children = children
node.tagName = tagName
node.properties = properties
})
})
plugins.forEach(plugin => {
// Handle [plugin, pluginOptions] syntax
if (Array.isArray(plugin) && plugin.length > 1) {
compiler.use(plugin[0], plugin[1])
} else {
compiler.use(plugin)
}
})
compiler.use(mdxHastToJsx, options)
for (const compilerPlugin of compilers) {
compiler.use(compilerPlugin, options)
}
return compiler
}
function createCompiler(options) {
const compiler = createMdxAstCompiler(options)
const compilerWithPlugins = applyHastPluginsAndCompilers(compiler, options)
return compilerWithPlugins
}
function sync(mdx, options) {
const opts = Object.assign({}, DEFAULT_OPTIONS, options)
const compiler = createCompiler(opts)
const fileOpts = {contents: mdx}
if (opts.filepath) {
fileOpts.path = opts.filepath
}
const {contents} = compiler.processSync(fileOpts)
return `/* @jsx mdx */
${contents}`
}
async function compile(mdx, options = {}) {
const opts = Object.assign({}, DEFAULT_OPTIONS, options)
const compiler = createCompiler(opts)
const fileOpts = {contents: mdx}
if (opts.filepath) {
fileOpts.path = opts.filepath
}
const {contents} = await compiler.process(fileOpts)
return `/* @jsx mdx */
${contents}`
}
compile.sync = sync
module.exports = compile
exports = compile
exports.sync = sync
exports.createMdxAstCompiler = createMdxAstCompiler
exports.default = compile