mdx-ast-to-mdx-hast.js
2.36 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
const toHAST = require('mdast-util-to-hast')
const detab = require('detab')
const u = require('unist-builder')
function mdxAstToMdxHast() {
return (tree, _file) => {
const handlers = {
// `inlineCode` gets passed as `code` by the HAST transform.
// This makes sure it ends up being `inlineCode`
inlineCode(h, node) {
return Object.assign({}, node, {
type: 'element',
tagName: 'inlineCode',
properties: {},
children: [
{
type: 'text',
value: node.value
}
]
})
},
code(h, node) {
const value = node.value ? detab(node.value + '\n') : ''
const lang = node.lang
const props = {}
if (lang) {
props.className = ['language-' + lang]
}
// MDAST sets `node.meta` to `null` instead of `undefined` if
// not present, which React doesn't like.
props.metastring = node.meta || undefined
const meta =
node.meta &&
node.meta.split(' ').reduce((acc, cur) => {
if (cur.split('=').length > 1) {
const t = cur.split('=')
acc[t[0]] = t[1]
return acc
}
acc[cur] = true
return acc
}, {})
if (meta) {
Object.keys(meta).forEach(key => {
const isClassKey = key === 'class' || key === 'className'
if (props.className && isClassKey) {
props.className.push(meta[key])
} else {
props[key] = meta[key]
}
})
}
return h(node.position, 'pre', [
h(node, 'code', props, [u('text', value)])
])
},
import(h, node) {
return Object.assign({}, node, {
type: 'import'
})
},
export(h, node) {
return Object.assign({}, node, {
type: 'export'
})
},
comment(h, node) {
return Object.assign({}, node, {
type: 'comment'
})
},
jsx(h, node) {
return Object.assign({}, node, {
type: 'jsx'
})
}
}
const hast = toHAST(tree, {
handlers,
// Enable passing of HTML nodes to HAST as raw nodes
allowDangerousHTML: true
})
return hast
}
}
module.exports = mdxAstToMdxHast