-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
remark-mdx-html-plugin.ts
83 lines (77 loc) · 2.75 KB
/
remark-mdx-html-plugin.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
import toHast from "mdast-util-to-hast"
import { cachedImport } from "./cache-helpers"
import type { Node } from "unist-util-visit"
import type { Definition, Literal } from "mdast"
import type { MdxJsxAttribute, MdxJsxFlowElement } from "mdast-util-mdx"
// This plugin replaces html nodes with JSX divs that render given HTML via dangerouslySetInnerHTML
// We have to find out if this is really a good idea, but its processing footprint is very low
// compared to other solutions that would traverse the given HTML.
export const remarkMdxHtmlPlugin = () =>
async function transformer(markdownAST: Node): Promise<Node> {
const { visit } = await cachedImport<typeof import("unist-util-visit")>(
`unist-util-visit`
)
// Turn mdast nodes into hast nodes
// Required to support gatsby-plugin-autolink-headers
visit(markdownAST, node => {
if (node.data && Object.keys(node.data).includes(`hChildren`)) {
const converted = toHast(node as Definition, {
allowDangerousHtml: true,
})
if (converted) {
Object.assign(node, converted)
}
}
})
// Turn raw & html nodes into JSX divs with dangerouslySetInnerHTML
// Required to support gatsby-remark-images & gatsby-remark-autolink-headers
visit(markdownAST, node => {
if (![`html`, `raw`].includes(node.type)) {
return
}
const typedNode = node as MdxJsxFlowElement
typedNode.type = `mdxJsxFlowElement`
typedNode.name = `div`
typedNode.attributes = [
{
type: `mdxJsxAttribute`,
name: `dangerouslySetInnerHTML`,
value: {
type: `mdxJsxAttributeValueExpression`,
data: {
estree: {
type: `Program`,
body: [
{
type: `ExpressionStatement`,
expression: {
type: `ObjectExpression`,
properties: [
{
type: `Property`,
method: false,
shorthand: false,
computed: false,
key: {
type: `Identifier`,
name: `__html`,
},
value: {
type: `Literal`,
value: (node as Literal).value,
},
kind: `init`,
},
],
},
},
],
sourceType: `module`,
},
},
},
} as MdxJsxAttribute,
]
})
return markdownAST
}