-
Notifications
You must be signed in to change notification settings - Fork 2
/
spelling.go
151 lines (141 loc) · 2.97 KB
/
spelling.go
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
* Bamboo - A Vietnamese Input method editor
* Copyright (C) Luong Thanh Lam <ltlam93@gmail.com>
*
* This software is licensed under the MIT license. For more information,
* see <https://github.com/BambooEngine/bamboo-core/blob/master/LICENCE>.
*/
package bamboo
var firstConsonantSeqs = []string{
"b d đ g gh m n nh p ph r s t tr v z",
"c h k kh qu th",
"ch gi l ng ngh x",
"đ l",
"h",
}
var vowelSeqs = []string{
"ê i ua uê uy y",
"a iê oa uyê yê",
"â ă e o oo ô ơ oe u ư uâ uô ươ",
"oă",
"uơ",
"ai ao au âu ay ây eo êu ia iêu iu oai oao oay oeo oi ôi ơi ưa uây ui ưi uôi ươi ươu ưu uya uyu yêu",
"ă",
"i",
}
var lastConsonantSeqs = []string{
"ch nh",
"c ng",
"m n p t",
"k",
"c",
}
var cvMatrix = [][]int{
{0, 1, 2, 5},
{0, 1, 2, 3, 4, 5},
{0, 1, 2, 3, 5},
{6},
{7},
}
var vcMatrix = [][]int{
{0, 2},
{0, 1, 2},
{1, 2},
{1, 2},
{},
{},
{3},
{4},
}
func lookup(seq []string, input string, inputIsFull, inputIsComplete bool) []int {
var ret []int
var inputLen = len([]rune(input))
for index, row := range seq {
var i = 0
var rows = append([]rune(row), ' ')
for j, char := range rows {
if char != ' ' {
continue
}
var canvas = rows[i:j]
i = j + 1
if len(canvas) < inputLen || (inputIsFull && len(canvas) > inputLen) {
continue
}
var isMatch = true
for k, ic := range []rune(input) {
if ic != canvas[k] && !(!inputIsComplete && AddMarkToTonelessChar(canvas[k], 0) == ic) {
isMatch = false
break
}
}
if isMatch {
ret = append(ret, index)
break
}
}
}
return ret
}
func isValidCVC(fc, vo, lc string, inputIsFullComplete bool) bool {
var ret bool
var fcIndexes, voIndexes, lcIndexes []int
// log.Printf("fc=%s vo=%s lc=%s ret=%v", fc, vo, lc, ret)
if fc != "" {
if fcIndexes = lookup(firstConsonantSeqs, fc, inputIsFullComplete || vo != "", true); fcIndexes == nil {
return false
}
}
if vo != "" {
if voIndexes = lookup(vowelSeqs, vo, inputIsFullComplete || lc != "", inputIsFullComplete); voIndexes == nil {
return false
}
}
if lc != "" {
if lcIndexes = lookup(lastConsonantSeqs, lc, inputIsFullComplete, true); lcIndexes == nil {
return false
}
}
if voIndexes == nil {
// first consonant only
return fcIndexes != nil
}
if fcIndexes != nil {
// first consonant + vowel
if ret = isValidCV(fcIndexes, voIndexes); !ret || lcIndexes == nil {
return ret
}
}
if lcIndexes != nil {
// vowel + last consonant
ret = isValidVC(voIndexes, lcIndexes)
} else {
// vowel only
ret = true
}
return ret
}
func isValidCV(fcIndexes, voIndexes []int) bool {
for _, fc := range fcIndexes {
for _, c := range cvMatrix[fc] {
for _, vo := range voIndexes {
if c == vo {
return true
}
}
}
}
return false
}
func isValidVC(voIndexes, lcIndexes []int) bool {
for _, vo := range voIndexes {
for _, c := range vcMatrix[vo] {
for _, lc := range lcIndexes {
if c == lc {
return true
}
}
}
}
return false
}