/
core.ts
91 lines (81 loc) · 2.11 KB
/
core.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
84
85
86
87
88
89
90
91
import type * as MdAst from 'mdast'
import type { AdvAst, AdvMarkdown } from '@advjs/types'
import matter from 'gray-matter'
import { mdParse } from './markdown'
import { Serialize } from './Serialize'
import { resolveConfig } from './config'
import { isScript } from './syntax'
// import { AdvItem } from '@advjs/types'
const serialize = new Serialize()
/**
* 将 Markdown 语法树转译为 AdvScript
*/
export function convertMdToAdv(mdAst: MdAst.Root): AdvAst.Root {
const ast: AdvAst.Root = {
type: 'adv-root',
functions: {},
scene: {},
children: [],
}
// 深度优先
let i = 0
mdAst.children.forEach((child) => {
const advItem = parseChild(child)
if (advItem) {
ast.children.push(advItem)
if (advItem.type === 'scene')
ast.scene[advItem.place] = ast.children.length - 1
// mount code function
if (isScript(advItem)) {
const name = `advFunc${i}`
ast.functions[`advFunc${i}`] = advItem.value
advItem.value = name
i += 1
}
if (advItem.type === 'choices') {
advItem.choices.forEach((choice) => {
if (isScript(choice.do)) {
const name = `advFunc${i}`
ast.functions[`advFunc${i}`] = choice.do.value
choice.do.value = name
i += 1
}
})
}
}
})
return ast
}
export function parseChild(child: MdAst.Content) {
const node = serialize.parse(child)
return node
}
/**
* parse markdown to ast
* recommended: .adv.md
* 将纯文本内容解析为语法树
* @param content 文本内容
*/
export async function parseAst(content: string) {
// const mdAst = md.parse(content, {})
// return convertMdToAdv(mdAst)
const mdAst = await mdParse(content)
const advAst = convertMdToAdv(mdAst)
return advAst
}
/**
* parse adv.md config
* @param markdown
* @param filepath
*/
export function parse(markdown: string, filepath?: string): AdvMarkdown {
const { data } = matter(markdown)
const config = resolveConfig(data)
return {
raw: markdown,
filepath,
config,
features: config.features,
frontmatter: data,
}
}