Tekkon // Hsu parser fix & HYPY output support, etc.

This commit is contained in:
ShikiSuen 2022-05-14 13:33:22 +08:00
parent 4d8cbb2db5
commit 66e016d06e
2 changed files with 283 additions and 55 deletions

View File

@ -166,7 +166,7 @@ extension KeyHandler {
// However, Swift does not support "|=".
composeReading = composeReading || (!_composer.isEmpty && (input.isSpace || input.isEnter))
if composeReading {
let reading = _composer.getRealComposition()
let reading = _composer.realComposition
// See whether we have a unigram for this...
if !ifLangModelHasUnigrams(forKey: reading) {

View File

@ -28,14 +28,16 @@ import Foundation
public struct Tekkon {
// MARK: - Static Constants and Basic Enums
///
public enum PhoneType: Int {
case null = 0 //
case consonant = 1 //
case semivowel = 2 //
case vowel = 3 //
case semivowel = 2 //
case vowel = 3 //
case intonation = 4 // 調
}
///
public enum MandarinParser: Int {
case ofDachen = 0
case ofEten = 1
@ -45,7 +47,7 @@ public struct Tekkon {
case ofMiTAC = 5
case ofFakeSeigyou = 6
case ofSeigyou = 7
case ofHanyuPinyin = 10
case ofHanyuPinyin = 10 //
var name: String {
switch self {
@ -71,52 +73,75 @@ public struct Tekkon {
}
}
///
public static let allowedConsonants = [
"", "", "", "", "", "", "", "",
"", "", "", "", "", "",
"", "", "", "", "", "", "",
]
///
public static let allowedsemivowels = ["", "", ""]
///
public static let allowedVowels = [
"", "", "", "", "", "",
"", "", "", "", "", "", "",
]
/// 調
public static let allowedIntonations = [" ", "ˊ", "ˇ", "ˋ", "˙"]
/// 調
public static var allowedPhonabets: [String] {
allowedConsonants + allowedsemivowels + allowedVowels + allowedIntonations
}
// MARK: - Phonabet Structure
///
/// value PhoneType 調
/// value PhoneType null
/// init let Phonabet
/// value valueStorage
@frozen public struct Phonabet: Equatable, Hashable, ExpressibleByStringLiteral {
public var type: PhoneType = .null
public var value: String = ""
private var valueStorage = ""
public var value: String { valueStorage }
public var isEmpty: Bool {
value.isEmpty
}
/// input PhoneType
public init(_ input: String = "") {
if !input.isEmpty {
if allowedPhonabets.contains(String(input.reversed()[0])) {
value = String(input.reversed()[0])
if Tekkon.allowedConsonants.contains(value) { type = .consonant }
if Tekkon.allowedsemivowels.contains(value) { type = .semivowel }
if Tekkon.allowedVowels.contains(value) { type = .vowel }
if Tekkon.allowedIntonations.contains(value) { type = .intonation }
valueStorage = String(input.reversed()[0])
if Tekkon.allowedConsonants.contains(value) {
type = .consonant
} else if Tekkon.allowedsemivowels.contains(value) {
type = .semivowel
} else if Tekkon.allowedVowels.contains(value) {
type = .vowel
} else if Tekkon.allowedIntonations.contains(value) {
type = .intonation
} else {
type = .null
valueStorage = ""
}
}
}
}
///
public mutating func clear() {
value = ""
valueStorage = ""
}
// MARK: - Misc Definitions
/// 滿 "Equatable, Hashable, ExpressibleByStringLiteral"
public static func == (lhs: Phonabet, rhs: Phonabet) -> Bool {
lhs.value == rhs.value
}
@ -141,25 +166,76 @@ public struct Tekkon {
// MARK: - Syllable Composer
/// Syllable Composer
/// 使 Struct
/// 調
/// @--DISCUSSION--@
/// String Literal @input
/// @arrange .ofDachen
@frozen public struct Composer: Equatable, Hashable, ExpressibleByStringLiteral {
///
public var consonant: Phonabet = ""
///
public var semivowel: Phonabet = ""
///
public var vowel: Phonabet = ""
/// 調
public var intonation: Phonabet = ""
/// Windows / macOS
public var parser: MandarinParser = .ofDachen
/// 調
/// 調
/// 使.realComposition.value
public var value: String {
consonant.value + semivowel.value + vowel.value + intonation.value.replacingOccurrences(of: " ", with: "")
consonant.value + semivowel.value + vowel.value + intonation.value
}
/// Key
public var realComposition: String {
value.replacingOccurrences(of: " ", with: "")
}
/// value /
/// 調
public func getComposition(isHanyuPinyin: Bool = false, isTextBookStyle: Bool = false) -> String {
switch isHanyuPinyin {
case false:
var valReturnZhuyin = value.replacingOccurrences(of: " ", with: "")
if isTextBookStyle, valReturnZhuyin.contains("˙") {
valReturnZhuyin = String(valReturnZhuyin.dropLast())
valReturnZhuyin.insert("˙", at: valReturnZhuyin.startIndex)
}
return valReturnZhuyin
case true:
var valReturnPinyin = Tekkon.cnvPhonaToHanyuPinyin(target: value)
if isTextBookStyle {
valReturnPinyin = Tekkon.cnvHanyuPinyinToTextbookStyle(target: valReturnPinyin)
}
return valReturnPinyin
}
}
///
public var isEmpty: Bool {
intonation.isEmpty && vowel.isEmpty && semivowel.isEmpty && consonant.isEmpty
}
// MARK:
/// @input
/// @arrange .ofDachen
public init(_ input: String = "", arrange parser: MandarinParser = .ofDachen) {
receiveKey(fromString: input)
ensureParser(arrange: parser)
receiveKey(fromString: input)
}
/// 調
/// ensureParser
public mutating func clear() {
consonant.clear()
semivowel.clear()
@ -170,9 +246,10 @@ public struct Tekkon {
// MARK: - Public Functions
///
/// Phonabet String Struct
///
/// 調
/// @--DISCUSSION--@
/// parser
/// - Parameters:
/// - key: UniChar
public func inputValidityCheck(key inputKey: UniChar = 0) -> Bool {
if let scalar = UnicodeScalar(inputKey) {
let input = String(scalar)
@ -200,6 +277,12 @@ public struct Tekkon {
return false
}
/// String
/// UniChar
/// @--DISCUSSION--@
/// 調
/// - Parameters:
/// - fromString: String
public mutating func receiveKey(fromString input: String = "") {
let translatedInput = translate(key: String(input))
let thePhone: Phonabet = .init(translatedInput)
@ -212,32 +295,22 @@ public struct Tekkon {
}
}
/// UniChar
/// UniChar String
/// @--DISCUSSION--@
/// 調
/// - Parameters:
/// - fromCharCode: UniChar
public mutating func receiveKey(fromCharCode inputCharCode: UniChar = 0) {
if let scalar = UnicodeScalar(inputCharCode) {
let translatedInput = translate(key: String(scalar))
let thePhone: Phonabet = .init(translatedInput)
switch thePhone.type {
case .consonant: consonant = thePhone
case .semivowel: semivowel = thePhone
case .vowel: vowel = thePhone
case .intonation: intonation = thePhone
default: break
}
receiveKey(fromString: String(scalar))
}
}
/// 西
/// /
public func getDisplayedComposition() -> String {
value
}
/// Key
public func getRealComposition() -> String {
value
}
/// 使 BackSpace
/// 調
/// @--DISCUSSION--@
///
public mutating func doBackSpace() {
if !intonation.isEmpty {
intonation.clear()
@ -250,7 +323,9 @@ public struct Tekkon {
}
}
/// 調
/// 調調
/// - Parameters:
/// - withNothingElse: 調
public func hasToneMarker(withNothingElse: Bool = false) -> Bool {
if !withNothingElse {
return !intonation.isEmpty
@ -258,23 +333,22 @@ public struct Tekkon {
return !intonation.isEmpty && vowel.isEmpty && semivowel.isEmpty && consonant.isEmpty
}
/// Phonabet 使
/// Phonabet type 調
public mutating func receiveCharCode(_ inputKey: UniChar = 0) {
// TODO:
if let scalar = UnicodeScalar(inputKey) {
let input = String(scalar)
receiveKey(fromString: input)
}
}
// Composer
// Composer
/// - Parameters:
/// - arrange:
public mutating func ensureParser(arrange: MandarinParser = .ofDachen) {
parser = arrange
}
// MARK: - Parser Processings
//
/// String
/// @--DISCUSSION--@
///
/// - Parameters:
/// - key: String
mutating func translate(key: String = "") -> String {
switch parser {
case .ofDachen:
@ -299,6 +373,10 @@ public struct Tekkon {
}
///
/// @--DISCUSSION--@
///
/// - Parameters:
/// - key: String
mutating func handleEten26(key: String = "") -> String {
var strReturn = ""
strReturn = Tekkon.mapEten26StaticKeys[key] ?? ""
@ -348,34 +426,54 @@ public struct Tekkon {
}
}
//
if "dfhjklmnpqtw".contains(key) { strReturn = "" }
//
return strReturn
}
///
/// @--DISCUSSION--@
///
/// - Parameters:
/// - key: String
mutating func handleHsu(key: String = "") -> String {
var strReturn = ""
strReturn = Tekkon.mapHsuStaticKeys[key] ?? ""
let incomingPhonabet = Phonabet(strReturn)
switch key {
case "e": if semivowel.isEmpty { semivowel = "" } else { vowel = "" }
case "a": if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "d": if consonant.isEmpty { consonant = "" } else { intonation = "ˊ" }
case "e": if semivowel.isEmpty { semivowel = "" } else { vowel = "" }
case "f": if consonant.isEmpty { consonant = "" } else { intonation = "ˇ" }
case "g": if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "h": if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "k": if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "l":
if value.isEmpty, !consonant.isEmpty, !semivowel.isEmpty {
vowel = ""
} else if consonant.isEmpty {
consonant = ""
} else {
vowel = ""
}
case "m": if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "n": if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "s": if consonant.isEmpty { consonant = "" } else { intonation = "˙" }
case "d": if consonant.isEmpty { consonant = "" } else { intonation = "ˊ" }
case "f": if consonant.isEmpty { consonant = "" } else { intonation = "ˇ" }
case "l": if value.isEmpty { vowel = "" } else if consonant.isEmpty { consonant = "" } else { vowel = "" }
case "j": if !consonant.isEmpty { intonation = "ˋ" }
default: break
}
//
if !consonant.isEmpty, incomingPhonabet.type == .semivowel {
switch consonant {
case "": //
switch incomingPhonabet {
case "": consonant = "" //
case "": consonant = "" //
case "": consonant = "" //
default: break
}
case "":
if intonation.isEmpty {
switch incomingPhonabet {
@ -396,11 +494,21 @@ public struct Tekkon {
}
}
if key == "j" { // 調
if !consonant.isEmpty { intonation = "ˋ" }
}
//
if "adefghklmns".contains(key) { strReturn = "" }
//
return strReturn
}
// MARK: - Misc Definitions
/// 滿 "Equatable, Hashable, ExpressibleByStringLiteral"
public static func == (lhs: Composer, rhs: Composer) -> Bool {
lhs.value == rhs.value
}
@ -427,6 +535,7 @@ public struct Tekkon {
// MARK: - Phonabets (Enum)
/// Enum
enum Phonabets: Phonabet {
case ofBO = ""
case ofPO = ""
@ -471,12 +580,129 @@ public struct Tekkon {
case ofT5 = "˙"
}
// MARK: - Phonabet to Hanyu-Pinyin Conversion Processing
///
/// - Parameters:
/// - target: String
static func cnvPhonaToHanyuPinyin(target: String) -> String {
var targetConverted = target
for pair in arrPhonaToHanyuPinyin {
targetConverted = targetConverted.replacingOccurrences(of: pair[0], with: pair[1])
}
return targetConverted
}
static func cnvHanyuPinyinToTextbookStyle(target: String) -> String {
var targetConverted = target
for pair in arrHanyuPinyinTextbookStyleConversionTable {
targetConverted = targetConverted.replacingOccurrences(of: pair[0], with: pair[1])
}
return targetConverted
}
/// 調
static let arrPhonaToHanyuPinyin = [ //
[" ", "1"], ["ˊ", "2"], ["ˇ", "3"], ["ˋ", "4"], ["˙", "5"], ["ㄔㄨㄤ", "chuang"], ["ㄕㄨㄤ", "shuang"],
["ㄓㄨㄤ", "zhuang"], ["ㄔㄨㄥ", "chong"], ["ㄔㄨㄞ", "chuai"], ["ㄔㄨㄢ", "chuan"], ["ㄍㄨㄤ", "guang"], ["ㄏㄨㄤ", "huang"],
["ㄐㄧㄤ", "jiang"], ["ㄐㄩㄥ", "jiong"], ["ㄎㄨㄤ", "kuang"], ["ㄌㄧㄤ", "liang"], ["ㄋㄧㄤ", "niang"], ["ㄑㄧㄤ", "qiang"],
["ㄑㄩㄥ", "qiong"], ["ㄕㄨㄞ", "shuai"], ["ㄕㄨㄢ", "shuan"], ["ㄒㄧㄤ", "xiang"], ["ㄒㄩㄥ", "xiong"], ["ㄓㄨㄥ", "zhong"],
["ㄓㄨㄞ", "zhuai"], ["ㄓㄨㄢ", "zhuan"], ["ㄅㄧㄢ", "bian"], ["ㄅㄧㄠ", "biao"], ["ㄅㄧㄥ", "bing"], ["ㄔㄨㄚ", "chua"],
["ㄔㄨㄟ", "chui"], ["ㄔㄨㄣ", "chun"], ["ㄔㄨㄛ", "chuo"], ["ㄘㄨㄥ", "cong"], ["ㄘㄨㄢ", "cuan"], ["ㄉㄧㄢ", "dian"],
["ㄉㄧㄠ", "diao"], ["ㄉㄧㄥ", "ding"], ["ㄉㄨㄥ", "dong"], ["ㄉㄨㄢ", "duan"], ["ㄈㄧㄠ", "fiao"], ["ㄍㄧㄠ", "giao"],
["ㄍㄧㄣ", "gin"], ["ㄍㄨㄥ", "gong"], ["ㄍㄨㄞ", "guai"], ["ㄍㄨㄢ", "guan"], ["ㄏㄨㄥ", "hong"], ["ㄏㄨㄞ", "huai"],
["ㄏㄨㄢ", "huan"], ["ㄐㄧㄢ", "jian"], ["ㄐㄧㄠ", "jiao"], ["ㄐㄧㄥ", "jing"], ["ㄐㄩㄢ", "juan"], ["ㄎㄧㄡ", "kiu"],
["ㄎㄨㄥ", "kong"], ["ㄎㄨㄞ", "kuai"], ["ㄎㄨㄢ", "kuan"], ["ㄌㄧㄢ", "lian"], ["ㄌㄧㄠ", "liao"], ["ㄌㄧㄥ", "ling"],
["ㄌㄨㄥ", "long"], ["ㄌㄨㄢ", "luan"], ["ㄌㄩㄢ", "lvan"], ["ㄇㄧㄢ", "mian"], ["ㄇㄧㄠ", "miao"], ["ㄇㄧㄥ", "ming"],
["ㄋㄧㄢ", "nian"], ["ㄋㄧㄠ", "niao"], ["ㄋㄧㄥ", "ning"], ["ㄋㄨㄥ", "nong"], ["ㄋㄨㄢ", "nuan"], ["ㄆㄧㄢ", "pian"],
["ㄆㄧㄠ", "piao"], ["ㄆㄧㄥ", "ping"], ["ㄑㄧㄢ", "qian"], ["ㄑㄧㄠ", "qiao"], ["ㄑㄧㄥ", "qing"], ["ㄑㄩㄢ", "quan"],
["ㄖㄨㄥ", "rong"], ["ㄖㄨㄢ", "ruan"], ["ㄕㄨㄚ", "shua"], ["ㄕㄨㄟ", "shui"], ["ㄕㄨㄣ", "shun"], ["ㄕㄨㄛ", "shuo"],
["ㄙㄨㄥ", "song"], ["ㄙㄨㄢ", "suan"], ["ㄊㄧㄢ", "tian"], ["ㄊㄧㄠ", "tiao"], ["ㄊㄧㄥ", "ting"], ["ㄊㄨㄥ", "tong"],
["ㄊㄨㄢ", "tuan"], ["ㄒㄧㄢ", "xian"], ["ㄒㄧㄠ", "xiao"], ["ㄒㄧㄥ", "xing"], ["ㄒㄩㄢ", "xuan"], ["ㄓㄨㄚ", "zhua"],
["ㄓㄨㄟ", "zhui"], ["ㄓㄨㄣ", "zhun"], ["ㄓㄨㄛ", "zhuo"], ["ㄗㄨㄥ", "zong"], ["ㄗㄨㄢ", "zuan"], ["ㄈㄨㄥ", "fong"],
["ㄐㄩㄣ", "jun"], ["ㄅㄧㄝ", "bie"], ["ㄅㄧㄣ", "bin"], ["ㄘㄨㄟ", "cui"], ["ㄘㄨㄣ", "cun"], ["ㄘㄨㄛ", "cuo"], ["ㄉㄧㄚ", "dia"],
["ㄉㄧㄝ", "die"], ["ㄉㄧㄡ", "diu"], ["ㄉㄨㄟ", "dui"], ["ㄉㄨㄣ", "dun"], ["ㄉㄨㄛ", "duo"], ["ㄍㄨㄚ", "gua"], ["ㄍㄨㄜ", "gue"],
["ㄍㄨㄟ", "gui"], ["ㄍㄨㄣ", "gun"], ["ㄍㄨㄛ", "guo"], ["ㄏㄨㄚ", "hua"], ["ㄏㄨㄟ", "hui"], ["ㄏㄨㄣ", "hun"], ["ㄏㄨㄛ", "huo"],
["ㄐㄧㄚ", "jia"], ["ㄐㄧㄝ", "jie"], ["ㄐㄧㄣ", "jin"], ["ㄐㄧㄡ", "jiu"], ["ㄐㄩㄝ", "jue"], ["ㄎㄨㄚ", "kua"], ["ㄎㄨㄟ", "kui"],
["ㄎㄨㄣ", "kun"], ["ㄎㄨㄛ", "kuo"], ["ㄌㄧㄚ", "lia"], ["ㄌㄧㄝ", "lie"], ["ㄌㄧㄣ", "lin"], ["ㄌㄧㄡ", "liu"], ["ㄌㄨㄣ", "lun"],
["ㄌㄨㄛ", "luo"], ["ㄌㄩㄝ", "lve"], ["ㄇㄧㄝ", "mie"], ["ㄇㄧㄣ", "min"], ["ㄇㄧㄡ", "miu"], ["ㄋㄧㄝ", "nie"], ["ㄋㄧㄣ", "nin"],
["ㄋㄧㄡ", "niu"], ["ㄋㄨㄟ", "nui"], ["ㄋㄨㄣ", "nun"], ["ㄋㄨㄛ", "nuo"], ["ㄋㄩㄝ", "nve"], ["ㄆㄧㄚ", "pia"], ["ㄆㄧㄝ", "pie"],
["ㄆㄧㄣ", "pin"], ["ㄑㄧㄚ", "qia"], ["ㄑㄧㄝ", "qie"], ["ㄑㄧㄣ", "qin"], ["ㄑㄧㄡ", "qiu"], ["ㄑㄩㄝ", "que"], ["ㄑㄩㄣ", "qun"],
["ㄖㄨㄟ", "rui"], ["ㄖㄨㄣ", "run"], ["ㄖㄨㄛ", "ruo"], ["ㄙㄨㄟ", "sui"], ["ㄙㄨㄣ", "sun"], ["ㄙㄨㄛ", "suo"], ["ㄊㄧㄝ", "tie"],
["ㄊㄨㄟ", "tui"], ["ㄊㄨㄣ", "tun"], ["ㄊㄨㄛ", "tuo"], ["ㄒㄧㄚ", "xia"], ["ㄒㄧㄝ", "xie"], ["ㄒㄧㄣ", "xin"], ["ㄒㄧㄡ", "xiu"],
["ㄒㄩㄝ", "xue"], ["ㄒㄩㄣ", "xun"], ["ㄗㄨㄟ", "zui"], ["ㄗㄨㄣ", "zun"], ["ㄗㄨㄛ", "zuo"], ["ㄘㄟ", "cei"], ["ㄔㄤ", "chang"],
["ㄔㄥ", "cheng"], ["ㄕㄤ", "shang"], ["ㄕㄥ", "sheng"], ["ㄓㄤ", "zhang"], ["ㄓㄥ", "zheng"], ["ㄅㄤ", "bang"],
["ㄅㄥ", "beng"], ["ㄘㄤ", "cang"], ["ㄘㄥ", "ceng"], ["ㄔㄞ", "chai"], ["ㄔㄢ", "chan"], ["ㄔㄠ", "chao"], ["ㄔㄣ", "chen"],
["ㄔㄡ", "chou"], ["ㄉㄤ", "dang"], ["ㄉㄥ", "deng"], ["ㄈㄤ", "fang"], ["ㄈㄥ", "feng"], ["ㄍㄤ", "gang"], ["ㄍㄥ", "geng"],
["ㄏㄤ", "hang"], ["ㄏㄥ", "heng"], ["ㄎㄤ", "kang"], ["ㄎㄥ", "keng"], ["ㄌㄤ", "lang"], ["ㄌㄥ", "leng"], ["ㄇㄤ", "mang"],
["ㄇㄥ", "meng"], ["ㄋㄤ", "nang"], ["ㄋㄥ", "neng"], ["ㄆㄤ", "pang"], ["ㄆㄥ", "peng"], ["ㄖㄤ", "rang"], ["ㄖㄥ", "reng"],
["ㄙㄤ", "sang"], ["ㄙㄥ", "seng"], ["ㄕㄞ", "shai"], ["ㄕㄢ", "shan"], ["ㄕㄠ", "shao"], ["ㄕㄟ", "shei"], ["ㄕㄣ", "shen"],
["ㄕㄡ", "shou"], ["ㄊㄤ", "tang"], ["ㄊㄥ", "teng"], ["ㄨㄤ", "wang"], ["ㄨㄥ", "weng"], ["ㄧㄤ", "yang"], ["ㄧㄥ", "ying"],
["ㄩㄥ", "yong"], ["ㄩㄢ", "yuan"], ["ㄗㄤ", "zang"], ["ㄗㄥ", "zeng"], ["ㄓㄞ", "zhai"], ["ㄓㄢ", "zhan"], ["ㄓㄠ", "zhao"],
["ㄓㄟ", "zhei"], ["ㄓㄣ", "zhen"], ["ㄓㄡ", "zhou"], ["ㄅㄞ", "bai"], ["ㄅㄢ", "ban"], ["ㄅㄠ", "bao"], ["ㄅㄟ", "bei"],
["ㄅㄣ", "ben"], ["ㄘㄞ", "cai"], ["ㄘㄢ", "can"], ["ㄘㄠ", "cao"], ["ㄘㄣ", "cen"], ["ㄔㄚ", "cha"], ["ㄔㄜ", "che"],
["ㄔㄨ", "chu"], ["ㄘㄡ", "cou"], ["ㄉㄞ", "dai"], ["ㄉㄢ", "dan"], ["ㄉㄠ", "dao"], ["ㄉㄟ", "dei"], ["ㄉㄣ", "den"],
["ㄉㄡ", "dou"], ["ㄈㄢ", "fan"], ["ㄈㄟ", "fei"], ["ㄈㄣ", "fen"], ["ㄈㄡ", "fou"], ["ㄍㄞ", "gai"], ["ㄍㄢ", "gan"],
["ㄍㄠ", "gao"], ["ㄍㄟ", "gei"], ["ㄍㄣ", "gen"], ["ㄍㄡ", "gou"], ["ㄏㄞ", "hai"], ["ㄏㄢ", "han"], ["ㄏㄠ", "hao"],
["ㄏㄟ", "hei"], ["ㄏㄣ", "hen"], ["ㄏㄡ", "hou"], ["ㄎㄞ", "kai"], ["ㄎㄢ", "kan"], ["ㄎㄠ", "kao"], ["ㄎㄣ", "ken"],
["ㄎㄡ", "kou"], ["ㄌㄞ", "lai"], ["ㄌㄢ", "lan"], ["ㄌㄠ", "lao"], ["ㄌㄟ", "lei"], ["ㄌㄡ", "lou"], ["ㄇㄞ", "mai"],
["ㄇㄢ", "man"], ["ㄇㄠ", "mao"], ["ㄇㄟ", "mei"], ["ㄇㄣ", "men"], ["ㄇㄡ", "mou"], ["ㄋㄞ", "nai"], ["ㄋㄢ", "nan"],
["ㄋㄠ", "nao"], ["ㄋㄟ", "nei"], ["ㄋㄣ", "nen"], ["ㄋㄡ", "nou"], ["ㄆㄞ", "pai"], ["ㄆㄢ", "pan"], ["ㄆㄠ", "pao"],
["ㄆㄟ", "pei"], ["ㄆㄣ", "pen"], ["ㄆㄡ", "pou"], ["ㄖㄢ", "ran"], ["ㄖㄠ", "rao"], ["ㄖㄣ", "ren"], ["ㄖㄡ", "rou"],
["ㄙㄞ", "sai"], ["ㄙㄢ", "san"], ["ㄙㄠ", "sao"], ["ㄙㄟ", "sei"], ["ㄙㄣ", "sen"], ["ㄕㄚ", "sha"], ["ㄕㄜ", "she"],
["ㄕㄨ", "shu"], ["ㄙㄡ", "sou"], ["ㄊㄞ", "tai"], ["ㄊㄢ", "tan"], ["ㄊㄠ", "tao"], ["ㄊㄡ", "tou"], ["ㄨㄞ", "wai"],
["ㄨㄢ", "wan"], ["ㄨㄟ", "wei"], ["ㄨㄣ", "wen"], ["ㄧㄞ", "yai"], ["ㄧㄢ", "yan"], ["ㄧㄠ", "yao"], ["ㄧㄣ", "yin"],
["ㄧㄡ", "you"], ["ㄩㄝ", "yue"], ["ㄩㄣ", "yun"], ["ㄗㄞ", "zai"], ["ㄗㄢ", "zan"], ["ㄗㄠ", "zao"], ["ㄗㄟ", "zei"],
["ㄗㄣ", "zen"], ["ㄓㄚ", "zha"], ["ㄓㄜ", "zhe"], ["ㄓㄨ", "zhu"], ["ㄗㄡ", "zou"], ["ㄅㄚ", "ba"], ["ㄅㄧ", "bi"],
["ㄅㄛ", "bo"], ["ㄅㄨ", "bu"], ["ㄘㄚ", "ca"], ["ㄘㄜ", "ce"], ["ㄘㄨ", "cu"], ["ㄉㄚ", "da"], ["ㄉㄜ", "de"], ["ㄉㄧ", "di"],
["ㄉㄨ", "du"], ["ㄈㄚ", "fa"], ["ㄈㄛ", "fo"], ["ㄈㄨ", "fu"], ["ㄍㄚ", "ga"], ["ㄍㄜ", "ge"], ["ㄍㄧ", "gi"], ["ㄍㄨ", "gu"],
["ㄏㄚ", "ha"], ["ㄏㄜ", "he"], ["ㄏㄨ", "hu"], ["ㄐㄧ", "ji"], ["ㄐㄩ", "ju"], ["ㄎㄚ", "ka"], ["ㄎㄜ", "ke"], ["ㄎㄨ", "ku"],
["ㄌㄚ", "la"], ["ㄌㄜ", "le"], ["ㄌㄧ", "li"], ["ㄌㄛ", "lo"], ["ㄌㄨ", "lu"], ["ㄌㄩ", "lv"], ["ㄇㄚ", "ma"], ["ㄇㄜ", "me"],
["ㄇㄧ", "mi"], ["ㄇㄛ", "mo"], ["ㄇㄨ", "mu"], ["ㄋㄚ", "na"], ["ㄋㄜ", "ne"], ["ㄋㄧ", "ni"], ["ㄋㄨ", "nu"], ["ㄋㄩ", "nv"],
["ㄆㄚ", "pa"], ["ㄆㄧ", "pi"], ["ㄆㄛ", "po"], ["ㄆㄨ", "pu"], ["ㄑㄧ", "qi"], ["ㄑㄩ", "qu"], ["ㄖㄜ", "re"], ["ㄖㄨ", "ru"],
["ㄙㄚ", "sa"], ["ㄙㄜ", "se"], ["ㄙㄨ", "su"], ["ㄊㄚ", "ta"], ["ㄊㄜ", "te"], ["ㄊㄧ", "ti"], ["ㄊㄨ", "tu"], ["ㄨㄚ", "wa"],
["ㄨㄛ", "wo"], ["ㄒㄧ", "xi"], ["ㄒㄩ", "xu"], ["ㄧㄚ", "ya"], ["ㄧㄝ", "ye"], ["ㄧㄛ", "yo"], ["ㄗㄚ", "za"], ["ㄗㄜ", "ze"],
["ㄗㄨ", "zu"], ["", "b"], ["", "p"], ["", "m"], ["", "f"], ["", "d"], ["", "t"], ["", "n"],
["", "l"], ["", "g"], ["", "k"], ["", "h"], ["", "j"], ["", "q"], ["", "x"], ["", "zhi"],
["", "chi"], ["", "shi"], ["", "ri"], ["", "zi"], ["", "ci"], ["", "si"], ["", "a"], ["", "o"], ["", "e"],
["", "eh"], ["", "ai"], ["", "ei"], ["", "ao"], ["", "ou"], ["", "an"], ["", "en"], ["", "ang"],
["", "eng"], ["", "er"], ["", "yi"], ["", "wu"], ["", "yu"],
]
///
static let arrHanyuPinyinTextbookStyleConversionTable = [ //
["iang1", "iāng"], ["iang2", "iáng"], ["iang3", "iǎng"], ["iang4", "iàng"], ["iong1", "iōng"], ["iong2", "ióng"],
["iong3", "iǒng"], ["iong4", "iòng"], ["uang1", "uāng"], ["uang2", "uáng"], ["uang3", "uǎng"], ["uang4", "uàng"],
["uang5", "uang"], ["ang1", "āng"], ["ang2", "áng"], ["ang3", "ǎng"], ["ang4", "àng"], ["ang5", "ang"],
["eng1", "ēng"], ["eng2", "éng"], ["eng3", "ěng"], ["eng4", "èng"], ["ian1", "iān"], ["ian2", "ián"],
["ian3", "iǎn"], ["ian4", "iàn"], ["iao1", "iāo"], ["iao2", "iáo"], ["iao3", "iǎo"], ["iao4", "iào"],
["ing1", "īng"], ["ing2", "íng"], ["ing3", "ǐng"], ["ing4", "ìng"], ["ong1", "ōng"], ["ong2", "óng"],
["ong3", "ǒng"], ["ong4", "òng"], ["uai1", "uāi"], ["uai2", "uái"], ["uai3", "uǎi"], ["uai4", "uài"],
["uan1", "uān"], ["uan2", "uán"], ["uan3", "uǎn"], ["uan4", "uàn"], ["van2", "üán"], ["van3", "üǎn"],
["ai1", "āi"], ["ai2", "ái"], ["ai3", "ǎi"], ["ai4", "ài"], ["ai5", "ai"], ["an1", "ān"], ["an2", "án"],
["an3", "ǎn"], ["an4", "àn"], ["ao1", "āo"], ["ao2", "áo"], ["ao3", "ǎo"], ["ao4", "ào"], ["ao5", "ao"],
["eh2", "ế"], ["eh3", "êˇ"], ["eh4", ""], ["eh5", "ê"], ["ei1", "ēi"], ["ei2", "éi"], ["ei3", "ěi"],
["ei4", "èi"], ["ei5", "ei"], ["en1", "ēn"], ["en2", "én"], ["en3", "ěn"], ["en4", "èn"], ["en5", "en"],
["er1", "ēr"], ["er2", "ér"], ["er3", "ěr"], ["er4", "èr"], ["er5", "er"], ["ia1", ""], ["ia2", ""],
["ia3", ""], ["ia4", ""], ["ie1", ""], ["ie2", ""], ["ie3", ""], ["ie4", ""], ["ie5", "ie"],
["in1", "īn"], ["in2", "ín"], ["in3", "ǐn"], ["in4", "ìn"], ["iu1", ""], ["iu2", ""], ["iu3", ""],
["iu4", ""], ["ou1", "ōu"], ["ou2", "óu"], ["ou3", "ǒu"], ["ou4", "òu"], ["ou5", "ou"], ["ua1", ""],
["ua2", ""], ["ua3", ""], ["ua4", ""], ["ue1", ""], ["ue2", ""], ["ue3", ""], ["ue4", ""],
["ui1", ""], ["ui2", ""], ["ui3", ""], ["ui4", ""], ["un1", "ūn"], ["un2", "ún"], ["un3", "ǔn"],
["un4", "ùn"], ["uo1", ""], ["uo2", ""], ["uo3", ""], ["uo4", ""], ["uo5", "uo"], ["ve1", "üē"],
["ve3", "üě"], ["ve4", "üè"], ["a1", "ā"], ["a2", "á"], ["a3", "ǎ"], ["a4", "à"], ["a5", "a"], ["e1", "ē"],
["e2", "é"], ["e3", "ě"], ["e4", "è"], ["e5", "e"], ["i1", "ī"], ["i2", "í"], ["i3", "ǐ"], ["i4", "ì"],
["i5", "i"], ["o1", "ō"], ["o2", "ó"], ["o3", "ǒ"], ["o4", "ò"], ["o5", "o"], ["u1", "ū"], ["u2", "ú"],
["u3", "ǔ"], ["u4", "ù"], ["v1", "ǖ"], ["v2", "ǘ"], ["v3", "ǚ"], ["v4", "ǜ"],
]
// MARK: - Maps for Keyboard-to-Phonabet parsers
// Strings
/// Strings
static let mapArayuruPinyin: String = "abcdefghijklmnopqrstuvwxyz12345 "
///
/// @--DISCUSSION--@
/// macOS 使 Ukelele
/// 使
static let mapQwertyDachen: [String: String] = [
@ -487,6 +713,7 @@ public struct Tekkon {
]
///
/// @--DISCUSSION--@
/// 便 validity check
///
static let mapHsuStaticKeys: [String: String] = [
@ -496,6 +723,7 @@ public struct Tekkon {
]
///
/// @--DISCUSSION--@
/// 便 validity check
/// ////
static let mapEten26StaticKeys: [String: String] = [