-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkeymapper.js
91 lines (80 loc) · 2.1 KB
/
keymapper.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
90
91
const readline = require('readline')
const read_lines = file => {
return readline.createInterface({
input: fs.createReadStream(file)
})
}
const modifier = mod => {
const mods = {
C: 'MOD_LC',
S: 'MOD_LS',
A: 'MOD_LA',
G: 'MOD_LG',
c: 'MOD_RC',
s: 'MOD_RS',
a: 'MOD_RA',
g: 'MOD_RG',
}
let arr = []
for (const char of mod) {
arr.push(mods[char])
}
return `(${arr.join('|')})`
}
const letter = (string) => {
if (string.length > 1) {
if (string.includes('+')) {
const [mod, key] = string.split('+')
return `(${modifier(mod)}|string2code["${key}"].first), string2code["${key}"].second`
} else {
throw new Error(`Bad letter <${string}>`)
}
} else {
return `string2code["${string}"].first, string2code["${string}"].second`
}
}
const rule = (index, string) => {
if (string == '??' || string == '__') {
return
}
if (string.includes('(')) {
const parts = string.split('(')
const fn = parts[0]
const args = parts[1]
.replace(')', '')
.split(',')
.filter(e => !!e)
// if (fn == '') TODO
} else {
return `interpreter.addRule(${index}, kc(${letter(string)}));\n`
}
}
const parse = async file => {
let result = ''
let mode = ''
let map = []
let arr = []
const process = () => {
if (mode == 'map') {
map = arr.map(n => parseInt(n))
} else {
let i = 0
const layer = parseInt(mode)
for (const item of arr) {
i++
const index = layer + (map[i] || i)
result += rule(index, item)
}
}
}
for await (const line of read_lines(file)) {
if (line.includes(':::')) {
process()
mode = line.replace(':::', '').trim().toLocaleLowerCase()
} else {
arr = arr.concat(line.split(/\s+/g).filter(e => !!e))
}
}
return result
}
module.exports = parse