-
Notifications
You must be signed in to change notification settings - Fork 0
/
hooks.ts
50 lines (46 loc) · 1.72 KB
/
hooks.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
import * as React from 'react'
import unified, { Transformer } from 'unified'
import markdown from 'remark-parse'
import slug from 'remark-slug'
import remark2rehype from 'remark-rehype'
import rehype2react from 'rehype-react'
import highlight from 'rehype-highlight'
import { hljsDefineGraphQL } from 'utils'
import util from 'mdast-util-toc'
const tocProcessor = unified()
.use(remark2rehype)
.use(rehype2react, { createElement: React.createElement })
export const useRemark = (body: string, skipToc?: boolean) => {
const [toc, setToc] = React.useState<JSX.Element | null>(null)
const docProcessor = React.useMemo(
() =>
unified()
.use(markdown)
.use(() => {
const transformer: Transformer = (node) => {
if (skipToc) return
const result = util(node, {})
if (!result.map) return
const tocNode = tocProcessor().runSync(result.map)
setToc(tocProcessor().stringify(tocNode) as any)
}
return transformer
})
.use(slug)
.use(remark2rehype)
.use(highlight, {
ignoreMissing: true,
languages: {
graphql: hljsDefineGraphQL,
},
})
.use(rehype2react, { createElement: React.createElement }),
[skipToc]
)
const doc = React.useMemo<JSX.Element>(() => {
if (!body) return null
const md = docProcessor().processSync(body) as any
return md.result
}, [docProcessor, body])
return [doc, toc] as const
}