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
}
|