-
Notifications
You must be signed in to change notification settings - Fork 9
/
index-compiler.js
89 lines (77 loc) · 2.36 KB
/
index-compiler.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
82
83
84
85
86
87
88
89
const pangu = require('pangu')
// List of Markdown AST: <https://github.com/syntax-tree/mdast>
// AST Explorer: <https://astexplorer.net/#/gist/7a794a8fc43b2e75e27024c85fb77aad/0934495eb735dffdf739dc7943f7848940070f8e>
//
// AST we should format:
// 1. text node:
// * paragraph children
// * blockquote children
// * heading children
// * emphasis children
// * strong children
// * listItems children
// * tableCell children
// * delete children
// * link children
// * image children
// * footnote children
// 2. inlineCode value
// 3. link title
// 4. image title/alt
// 5. imageReference alt
// 6. definition title
//
//
// AST we ignored:
// 1. YAML
// 2. html (it can contain link: <a> <img>)
// 3. 临接情况
// 1. 粗体:我的a**粗体**
// 2. 强调:我的a*强调*
// 3. ...
function format(value) {
if (!value) return value
return pangu.spacing(value)
}
function createFormatNodeVisitorCreator(nodeKey) {
return function visitorCreator(originVisitor) {
return function valueVisitor(node, ...args) {
const formattedNode = Object.assign({}, node, {
[nodeKey]: format(node[nodeKey]),
})
return originVisitor.call(this, formattedNode, ...args)
}
}
}
function assignVisitors(visitors, types, createVisitor) {
types.forEach(type => {
visitors[type] = createVisitor(visitors[type])
})
}
function assignValueVisitors(visitors) {
const valueVisitorCreator = createFormatNodeVisitorCreator('value')
assignVisitors(visitors, ['text', 'inlineCode'], valueVisitorCreator)
}
function assignTitleVisitor(visitors) {
const titleVisitorCreator = createFormatNodeVisitorCreator('title')
assignVisitors(visitors, ['link', 'image', 'definition'], titleVisitorCreator)
}
function assignAltVisitor(visitors) {
const altVisitorCreator = createFormatNodeVisitorCreator('alt')
assignVisitors(visitors, ['image', 'imageReference'], altVisitorCreator)
}
function isRemarkCompiler(compiler) {
return Boolean(compiler && compiler.prototype && compiler.prototype.visitors)
}
function attachCompiler(compiler) {
const proto = compiler.prototype
assignValueVisitors(proto.visitors)
assignTitleVisitor(proto.visitors)
assignAltVisitor(proto.visitors)
}
module.exports = function remarkPangu() {
const compiler = this.Compiler
if (isRemarkCompiler(compiler)) {
attachCompiler(compiler)
}
}