-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
executable file
·76 lines (60 loc) · 1.72 KB
/
index.js
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
import parse5 from 'parse5'
import { map } from 'unist-util-map'
import { fromParse5 } from 'hast-util-from-parse5'
import { torchlight, Block } from '@torchlight-api/torchlight-cli'
export default function plugin (options = {}) {
torchlight.init(options.config)
return tree => transform(tree, options)
}
function transform (tree, options) {
const blocks = []
const withPlaceholders = map(tree, node => {
if (!isBlockCode(node)) {
return node
}
const block = new Block({
language: node.lang,
code: node.value
})
blocks.push(block)
node.data = node.data ?? {}
node.data.torchlight = block
return node
})
return torchlight.highlight(blocks).then(() => {
return map(withPlaceholders, node => {
if (!node?.data?.torchlight) {
return node
}
const block = node.data.torchlight
const hast = fromParse5(parse5.parse(block.highlighted))
// The fragment that is returned from the API gets wrapped in a
// document and body, so we need to find the actual content
// inside all of the wrappers.
const highlighted = hast.children.pop().children.find(child => child.tagName === 'body').children
const code = h('code', {
className: `language-${block.language}`
}, highlighted)
return h('pre', {
className: [block.classes],
style: block.styles
}, [code])
})
})
}
const h = (type, attrs = {}, children = []) => {
return {
type: 'element',
tagName: type,
data: {
hName: type,
hProperties: attrs,
hChildren: children
},
properties: attrs,
children
}
}
function isBlockCode (node) {
return node.type === 'code' || node.tagName === 'code'
}