-
Notifications
You must be signed in to change notification settings - Fork 13
/
markdown.js
81 lines (73 loc) · 1.98 KB
/
markdown.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
77
78
79
80
81
import remark from 'remark'
import visit from 'unist-util-visit'
import find from 'unist-util-find'
import get from 'lodash.get'
import path from 'path'
const getter = name => v => get(v, name)
const getValue = getter('value')
const getUrl = getter('url')
const getByType = (node, type) => find(node, n => n.type === type)
const parseText = text => {
const matched = String(text).match(/\s*([^|]+)\s*\|?\s*([^|]+)?\s*/)
return {
title: matched && matched[1],
type: (matched && matched[2]) || 'empty'
}
}
const cleanTree = (tree, traverse, hasLink, depth = 0) => {
if (!tree) return []
const mapper = node => {
const text = getByType(node, 'text') || getByType(node, 'html')
const link = getByType(node, 'link')
const list = getByType(node, 'list')
const child = {}
child.depth = depth
if (text) {
child.text = getValue(text)
const { title, type } = parseText(child.text)
child.title = title
child.type = type
}
if (link) {
child.link = getUrl(link)
child.isRemoteUrl = /(https?:)?\/\//.test(child.link)
if (hasLink) {
hasLink(child.link)
}
}
if (list && list.children && list.children.length) {
child.children = cleanTree(
list.children,
traverse,
link => {
if (link && child.link === link) {
delete child.link
}
},
depth + 1
)
}
if (typeof traverse === 'function') {
traverse(child)
}
return child
}
if (Array.isArray(tree)) {
return tree.map(mapper)
} else {
const list = find(tree, node => node.type === 'list')
if (!list) return []
if (!list.children) return []
return cleanTree(list.children, traverse, false, depth + 1)
}
}
export const parseToc = async (text, traverse) => {
const { contents } = await remark()
.use(function() {
this.Compiler = root => {
return cleanTree(root, traverse)
}
})
.process(text)
return contents
}