Skip to content

Commit

Permalink
Add Hanyu-Pinyin input support. (#15)
Browse files Browse the repository at this point in the history
* Add rudimental Hanyu-Pinyin input support.

* Deprecate useless Phonabets enum table.
  • Loading branch information
ShikiSuen authored May 18, 2022
1 parent c2a48db commit dbfab55
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 64 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

鐵恨引擎是用來處理注音輸入法並擊行為的一個模組。該倉庫乃威注音專案的弒神行動(Operation Longinus)的一部分。

目前暫時缺乏漢語拼音輸入支援(僅支援輸出)
羅馬拼音輸入目前僅支援漢語拼音

Tekkon Engine is a module made for processing combo-composition of stroke-based Mandarin Chinese phonetics (i.e. Zhuyin / Bopomofo). This repository is part of Operation Longinus of The vChewing Project.

Hanyu Pinyin input support is currently not available yet (only output functions are available).
We support Hanyu Pinyin as the only romaji input mode at this moment.

## 使用說明

Expand Down
202 changes: 141 additions & 61 deletions Sources/Tekkon/TekkonSyllableComposer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ public struct Tekkon {
/// 聲調。
public var intonation: Phonabet = ""

/// 為拉丁字母專用的組音區
public var romajiBuffer: String = ""

/// 注音排列種類。預設情況下是大千排列(Windows / macOS 預設注音排列)。
public var parser: MandarinParser = .ofDachen

Expand Down Expand Up @@ -234,6 +237,26 @@ public struct Tekkon {
}
}

// 該函數僅用來獲取給 macOS InputMethod Kit 的內文組字區使用的顯示字串。
/// - Parameters:
/// - isHanyuPinyin: 是否將輸出結果轉成漢語拼音。
public func getInlineCompositionForIMK(isHanyuPinyin: Bool = false) -> String {
switch parser {
case .ofHanyuPinyin:
var toneReturned = ""
switch intonation.value {
case " ": toneReturned = "1"
case "ˊ": toneReturned = "2"
case "ˇ": toneReturned = "3"
case "ˋ": toneReturned = "4"
case "˙": toneReturned = "5"
default: break
}
return romajiBuffer + toneReturned
default: return getComposition(isHanyuPinyin: isHanyuPinyin)
}
}

/// 注拼槽內容是否為空。
public var isEmpty: Bool {
intonation.isEmpty && vowel.isEmpty && semivowel.isEmpty && consonant.isEmpty
Expand Down Expand Up @@ -263,6 +286,7 @@ public struct Tekkon {
semivowel.clear()
vowel.clear()
intonation.clear()
romajiBuffer = ""
}

// MARK: - Public Functions
Expand Down Expand Up @@ -308,14 +332,22 @@ public struct Tekkon {
/// - Parameters:
/// - fromString: 傳入的 String 內容。
public mutating func receiveKey(fromString input: String = "") {
let translatedInput = translate(key: String(input))
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
switch parser {
case .ofHanyuPinyin:
if mapArayuruPinyinIntonation.contains(input) {
if let theTone = mapArayuruPinyinIntonationTable[input] {
intonation = Phonabet(theTone)
}
} else {
// 為了防止 romajiBuffer 越敲越長帶來算力負擔,這裡讓它在要溢出時自動丟掉先取音頭。
if romajiBuffer.count > 5 {
romajiBuffer = String(romajiBuffer.dropFirst())
}
let romajiBufferBackup = romajiBuffer + input
receiveSequence(romajiBufferBackup, isRomaji: true)
romajiBuffer = romajiBufferBackup
}
default: receiveKey(fromPhonabet: translate(key: String(input)))
}
}

Expand All @@ -331,13 +363,41 @@ public struct Tekkon {
}
}

/// 接受傳入的按鍵訊號時的處理,處理對象為單個注音符號。
/// 主要就是將注音符號拆分辨識且分配到正確的貯存位置而已。
/// - Parameters:
/// - fromPhonabet: 傳入的單個注音符號字串。
public mutating func receiveKey(fromPhonabet phonabet: String = "") {
let thePhone: Phonabet = .init(phonabet)
switch thePhone.type {
case .consonant: consonant = thePhone
case .semivowel: semivowel = thePhone
case .vowel: vowel = thePhone
case .intonation: intonation = thePhone
default: break
}
}

/// 處理一連串的按鍵輸入。
/// - Parameters:
/// - givenSequence: 傳入的 String 內容,用以處理一整串擊鍵輸入。
public mutating func receiveSequence(_ givenSequence: String = "") {
/// - isRomaji: 如果輸入的字串是諸如漢語拼音這樣的西文字母拼音的話,請啟用此選項。
public mutating func receiveSequence(_ givenSequence: String = "", isRomaji: Bool = false) {
clear()
for key in givenSequence {
receiveKey(fromString: String(key))
if isRomaji {
switch parser {
case .ofHanyuPinyin:
if let dictResult = mapHanyuPinyin[givenSequence] {
for phonabet in dictResult {
receiveKey(fromPhonabet: String(phonabet))
}
}
default: break
}
} else {
for key in givenSequence {
receiveKey(fromString: String(key))
}
}
}

Expand All @@ -354,7 +414,13 @@ public struct Tekkon {
/// @--DISCUSSION--@
/// 基本上就是按順序從游標前方開始往後刪。
public mutating func doBackSpace() {
if !intonation.isEmpty {
if parser == .ofHanyuPinyin, !romajiBuffer.isEmpty {
if !intonation.isEmpty {
intonation.clear()
} else {
romajiBuffer = String(romajiBuffer.dropLast())
}
} else if !intonation.isEmpty {
intonation.clear()
} else if !vowel.isEmpty {
vowel.clear()
Expand Down Expand Up @@ -411,7 +477,7 @@ public struct Tekkon {
return Tekkon.mapSeigyou[key] ?? ""
case .ofFakeSeigyou:
return Tekkon.mapFakeSeigyou[key] ?? ""
case .ofHanyuPinyin: break // TODO: 待辦
case .ofHanyuPinyin: break // 漢語拼音單獨用另外的函數處理
}
return ""
}
Expand Down Expand Up @@ -708,53 +774,6 @@ public struct Tekkon {
}
}

// MARK: - Phonabets (Enum)

/// 該 Enum 羅列了所有合理的注音符號,將來做漢語拼音功能支援時可能會用到。
enum Phonabets: Phonabet {
case ofBO = ""
case ofPO = ""
case ofMO = ""
case ofFO = ""
case ofDE = ""
case ofTE = ""
case ofNE = ""
case ofLE = ""
case ofGE = ""
case ofKE = ""
case ofHE = ""
case ofJI = ""
case ofQI = ""
case ofXI = ""
case ofZH = ""
case ofCH = ""
case ofSH = ""
case ofRI = ""
case ofZI = ""
case ofCI = ""
case ofSI = ""
case ofYI = ""
case ofWU = ""
case ofYU = ""
case ofAA = ""
case ofOO = ""
case ofEE = ""
case ofEA = ""
case ofAI = ""
case ofEI = ""
case ofAO = ""
case ofOU = ""
case ofAN = ""
case ofEN = ""
case ofAG = ""
case ofOG = ""
case ofT1 = " "
case ofT2 = "ˊ"
case ofT3 = "ˇ"
case ofT4 = "ˋ"
case ofT5 = "˙"
}

// MARK: - Phonabet to Hanyu-Pinyin Conversion Processing

/// 注音轉拼音,要求陰平必須是空格。
Expand Down Expand Up @@ -884,7 +903,68 @@ public struct Tekkon {
// MARK: - Maps for Keyboard-to-Phonabet parsers

/// 任何形式的拼音排列都會用到的陣列,用 Strings 反而省事一些。
static let mapArayuruPinyin: String = "abcdefghijklmnopqrstuvwxyz12345 "
/// 這裡同時兼容大千注音的調號數字,所以也將 6、7 號數字鍵放在允許範圍內。
static let mapArayuruPinyin: String = "abcdefghijklmnopqrstuvwxyz1234567 "
static let mapArayuruPinyinIntonation: String = "1234567 "
static let mapArayuruPinyinIntonationTable: [String: String] = [
"1": " ", "2": "ˊ", "3": "ˇ", "4": "ˋ", "5": "˙", "6": "ˊ", "7": "˙", " ": " ",
]
/// 漢語拼音排列專用處理陣列。
static let mapHanyuPinyin: [String: String] = [
"chuang": "ㄔㄨㄤ", "shuang": "ㄕㄨㄤ", "zhuang": "ㄓㄨㄤ", "chang": "ㄔㄤ", "cheng": "ㄔㄥ", "chong": "ㄔㄨㄥ", "chuai": "ㄔㄨㄞ",
"chuan": "ㄔㄨㄢ", "guang": "ㄍㄨㄤ", "huang": "ㄏㄨㄤ", "jiang": "ㄐㄧㄤ", "jiong": "ㄐㄩㄥ", "kiang": "ㄎㄧㄤ", "kuang": "ㄎㄨㄤ",
"liang": "ㄌㄧㄤ", "niang": "ㄋㄧㄤ", "qiang": "ㄑㄧㄤ", "qiong": "ㄑㄩㄥ", "shang": "ㄕㄤ", "sheng": "ㄕㄥ", "shuai": "ㄕㄨㄞ",
"shuan": "ㄕㄨㄢ", "xiang": "ㄒㄧㄤ", "xiong": "ㄒㄩㄥ", "zhang": "ㄓㄤ", "zheng": "ㄓㄥ", "zhong": "ㄓㄨㄥ", "zhuai": "ㄓㄨㄞ",
"zhuan": "ㄓㄨㄢ", "bang": "ㄅㄤ", "beng": "ㄅㄥ", "bian": "ㄅㄧㄢ", "biao": "ㄅㄧㄠ", "bing": "ㄅㄧㄥ", "cang": "ㄘㄤ", "ceng": "ㄘㄥ",
"chai": "ㄔㄞ", "chan": "ㄔㄢ", "chao": "ㄔㄠ", "chen": "ㄔㄣ", "chou": "ㄔㄡ", "chua": "ㄔㄨㄚ", "chui": "ㄔㄨㄟ", "chun": "ㄔㄨㄣ",
"chuo": "ㄔㄨㄛ", "cong": "ㄘㄨㄥ", "cuan": "ㄘㄨㄢ", "dang": "ㄉㄤ", "deng": "ㄉㄥ", "dian": "ㄉㄧㄢ", "diao": "ㄉㄧㄠ",
"ding": "ㄉㄧㄥ", "dong": "ㄉㄨㄥ", "duan": "ㄉㄨㄢ", "fang": "ㄈㄤ", "feng": "ㄈㄥ", "fiao": "ㄈㄧㄠ", "fong": "ㄈㄨㄥ", "gang": "ㄍㄤ",
"geng": "ㄍㄥ", "giao": "ㄍㄧㄠ", "gong": "ㄍㄨㄥ", "guai": "ㄍㄨㄞ", "guan": "ㄍㄨㄢ", "hang": "ㄏㄤ", "heng": "ㄏㄥ", "hong": "ㄏㄨㄥ",
"huai": "ㄏㄨㄞ", "huan": "ㄏㄨㄢ", "jian": "ㄐㄧㄢ", "jiao": "ㄐㄧㄠ", "jing": "ㄐㄧㄥ", "juan": "ㄐㄩㄢ", "kang": "ㄎㄤ",
"keng": "ㄎㄥ", "kong": "ㄎㄨㄥ", "kuai": "ㄎㄨㄞ", "kuan": "ㄎㄨㄢ", "lang": "ㄌㄤ", "leng": "ㄌㄥ", "lian": "ㄌㄧㄢ", "liao": "ㄌㄧㄠ",
"ling": "ㄌㄧㄥ", "long": "ㄌㄨㄥ", "luan": "ㄌㄨㄢ", "lvan": "ㄌㄩㄢ", "mang": "ㄇㄤ", "meng": "ㄇㄥ", "mian": "ㄇㄧㄢ",
"miao": "ㄇㄧㄠ", "ming": "ㄇㄧㄥ", "nang": "ㄋㄤ", "neng": "ㄋㄥ", "nian": "ㄋㄧㄢ", "niao": "ㄋㄧㄠ", "ning": "ㄋㄧㄥ",
"nong": "ㄋㄨㄥ", "nuan": "ㄋㄨㄢ", "pang": "ㄆㄤ", "peng": "ㄆㄥ", "pian": "ㄆㄧㄢ", "piao": "ㄆㄧㄠ", "ping": "ㄆㄧㄥ",
"qian": "ㄑㄧㄢ", "qiao": "ㄑㄧㄠ", "qing": "ㄑㄧㄥ", "quan": "ㄑㄩㄢ", "rang": "ㄖㄤ", "reng": "ㄖㄥ", "rong": "ㄖㄨㄥ",
"ruan": "ㄖㄨㄢ", "sang": "ㄙㄤ", "seng": "ㄙㄥ", "shai": "ㄕㄞ", "shan": "ㄕㄢ", "shao": "ㄕㄠ", "shei": "ㄕㄟ", "shen": "ㄕㄣ",
"shou": "ㄕㄡ", "shua": "ㄕㄨㄚ", "shui": "ㄕㄨㄟ", "shun": "ㄕㄨㄣ", "shuo": "ㄕㄨㄛ", "song": "ㄙㄨㄥ", "suan": "ㄙㄨㄢ",
"tang": "ㄊㄤ", "teng": "ㄊㄥ", "tian": "ㄊㄧㄢ", "tiao": "ㄊㄧㄠ", "ting": "ㄊㄧㄥ", "tong": "ㄊㄨㄥ", "tuan": "ㄊㄨㄢ", "wang": "ㄨㄤ",
"weng": "ㄨㄥ", "xian": "ㄒㄧㄢ", "xiao": "ㄒㄧㄠ", "xing": "ㄒㄧㄥ", "xuan": "ㄒㄩㄢ", "yang": "ㄧㄤ", "ying": "ㄧㄥ", "yong": "ㄩㄥ",
"yuan": "ㄩㄢ", "zang": "ㄗㄤ", "zeng": "ㄗㄥ", "zhai": "ㄓㄞ", "zhan": "ㄓㄢ", "zhao": "ㄓㄠ", "zhei": "ㄓㄟ", "zhen": "ㄓㄣ",
"zhou": "ㄓㄡ", "zhua": "ㄓㄨㄚ", "zhui": "ㄓㄨㄟ", "zhun": "ㄓㄨㄣ", "zhuo": "ㄓㄨㄛ", "zong": "ㄗㄨㄥ", "zuan": "ㄗㄨㄢ",
"jun": "ㄐㄩㄣ", "ang": "", "bai": "ㄅㄞ", "ban": "ㄅㄢ", "bao": "ㄅㄠ", "bei": "ㄅㄟ", "ben": "ㄅㄣ", "bie": "ㄅㄧㄝ",
"bin": "ㄅㄧㄣ", "cai": "ㄘㄞ", "can": "ㄘㄢ", "cao": "ㄘㄠ", "cei": "ㄘㄟ", "cen": "ㄘㄣ", "cha": "ㄔㄚ", "che": "ㄔㄜ", "chi": "",
"chu": "ㄔㄨ", "cou": "ㄘㄡ", "cui": "ㄘㄨㄟ", "cun": "ㄘㄨㄣ", "cuo": "ㄘㄨㄛ", "dai": "ㄉㄞ", "dan": "ㄉㄢ", "dao": "ㄉㄠ",
"dei": "ㄉㄟ", "den": "ㄉㄣ", "dia": "ㄉㄧㄚ", "die": "ㄉㄧㄝ", "diu": "ㄉㄧㄡ", "dou": "ㄉㄡ", "dui": "ㄉㄨㄟ", "dun": "ㄉㄨㄣ",
"duo": "ㄉㄨㄛ", "eng": "", "fan": "ㄈㄢ", "fei": "ㄈㄟ", "fen": "ㄈㄣ", "fou": "ㄈㄡ", "gai": "ㄍㄞ", "gan": "ㄍㄢ", "gao": "ㄍㄠ",
"gei": "ㄍㄟ", "gin": "ㄍㄧㄣ", "gen": "ㄍㄣ", "gou": "ㄍㄡ", "gua": "ㄍㄨㄚ", "gue": "ㄍㄨㄜ", "gui": "ㄍㄨㄟ", "gun": "ㄍㄨㄣ",
"guo": "ㄍㄨㄛ", "hai": "ㄏㄞ", "han": "ㄏㄢ", "hao": "ㄏㄠ", "hei": "ㄏㄟ", "hen": "ㄏㄣ", "hou": "ㄏㄡ", "hua": "ㄏㄨㄚ",
"hui": "ㄏㄨㄟ", "hun": "ㄏㄨㄣ", "huo": "ㄏㄨㄛ", "jia": "ㄐㄧㄚ", "jie": "ㄐㄧㄝ", "jin": "ㄐㄧㄣ", "jiu": "ㄐㄧㄡ", "jue": "ㄐㄩㄝ",
"kai": "ㄎㄞ", "kan": "ㄎㄢ", "kao": "ㄎㄠ", "ken": "ㄎㄣ", "kiu": "ㄎㄧㄡ", "kou": "ㄎㄡ", "kua": "ㄎㄨㄚ", "kui": "ㄎㄨㄟ",
"kun": "ㄎㄨㄣ", "kuo": "ㄎㄨㄛ", "lai": "ㄌㄞ", "lan": "ㄌㄢ", "lao": "ㄌㄠ", "lei": "ㄌㄟ", "lia": "ㄌㄧㄚ", "lie": "ㄌㄧㄝ",
"lin": "ㄌㄧㄣ", "liu": "ㄌㄧㄡ", "lou": "ㄌㄡ", "lun": "ㄌㄨㄣ", "luo": "ㄌㄨㄛ", "lve": "ㄌㄩㄝ", "mai": "ㄇㄞ", "man": "ㄇㄢ",
"mao": "ㄇㄠ", "mei": "ㄇㄟ", "men": "ㄇㄣ", "mie": "ㄇㄧㄝ", "min": "ㄇㄧㄣ", "miu": "ㄇㄧㄡ", "mou": "ㄇㄡ", "nai": "ㄋㄞ",
"nan": "ㄋㄢ", "nao": "ㄋㄠ", "nei": "ㄋㄟ", "nen": "ㄋㄣ", "nie": "ㄋㄧㄝ", "nin": "ㄋㄧㄣ", "niu": "ㄋㄧㄡ", "nou": "ㄋㄡ",
"nui": "ㄋㄨㄟ", "nun": "ㄋㄨㄣ", "nuo": "ㄋㄨㄛ", "nve": "ㄋㄩㄝ", "pai": "ㄆㄞ", "pan": "ㄆㄢ", "pao": "ㄆㄠ", "pei": "ㄆㄟ",
"pen": "ㄆㄣ", "pia": "ㄆㄧㄚ", "pie": "ㄆㄧㄝ", "pin": "ㄆㄧㄣ", "pou": "ㄆㄡ", "qia": "ㄑㄧㄚ", "qie": "ㄑㄧㄝ", "qin": "ㄑㄧㄣ",
"qiu": "ㄑㄧㄡ", "que": "ㄑㄩㄝ", "qun": "ㄑㄩㄣ", "ran": "ㄖㄢ", "rao": "ㄖㄠ", "ren": "ㄖㄣ", "rou": "ㄖㄡ", "rui": "ㄖㄨㄟ",
"run": "ㄖㄨㄣ", "ruo": "ㄖㄨㄛ", "sai": "ㄙㄞ", "san": "ㄙㄢ", "sao": "ㄙㄠ", "sei": "ㄙㄟ", "sen": "ㄙㄣ", "sha": "ㄕㄚ",
"she": "ㄕㄜ", "shi": "", "shu": "ㄕㄨ", "sou": "ㄙㄡ", "sui": "ㄙㄨㄟ", "sun": "ㄙㄨㄣ", "suo": "ㄙㄨㄛ", "tai": "ㄊㄞ",
"tan": "ㄊㄢ", "tao": "ㄊㄠ", "tie": "ㄊㄧㄝ", "tou": "ㄊㄡ", "tui": "ㄊㄨㄟ", "tun": "ㄊㄨㄣ", "tuo": "ㄊㄨㄛ", "wai": "ㄨㄞ",
"wan": "ㄨㄢ", "wei": "ㄨㄟ", "wen": "ㄨㄣ", "xia": "ㄒㄧㄚ", "xie": "ㄒㄧㄝ", "xin": "ㄒㄧㄣ", "xiu": "ㄒㄧㄡ", "xue": "ㄒㄩㄝ",
"xun": "ㄒㄩㄣ", "yai": "ㄧㄞ", "yan": "ㄧㄢ", "yao": "ㄧㄠ", "yin": "ㄧㄣ", "you": "ㄧㄡ", "yue": "ㄩㄝ", "yun": "ㄩㄣ",
"zai": "ㄗㄞ", "zan": "ㄗㄢ", "zao": "ㄗㄠ", "zei": "ㄗㄟ", "zen": "ㄗㄣ", "zha": "ㄓㄚ", "zhe": "ㄓㄜ", "zhi": "", "zhu": "ㄓㄨ",
"zou": "ㄗㄡ", "zui": "ㄗㄨㄟ", "zun": "ㄗㄨㄣ", "zuo": "ㄗㄨㄛ", "ai": "", "an": "", "ao": "", "ba": "ㄅㄚ", "bi": "ㄅㄧ",
"bo": "ㄅㄛ", "bu": "ㄅㄨ", "ca": "ㄘㄚ", "ce": "ㄘㄜ", "ci": "", "cu": "ㄘㄨ", "da": "ㄉㄚ", "de": "ㄉㄜ", "di": "ㄉㄧ",
"du": "ㄉㄨ", "eh": "", "ei": "", "en": "", "er": "", "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": "ㄋㄩ", "ou": "",
"pa": "ㄆㄚ", "pi": "ㄆㄧ", "po": "ㄆㄛ", "pu": "ㄆㄨ", "qi": "ㄑㄧ", "qu": "ㄑㄩ", "re": "ㄖㄜ", "ri": "", "ru": "ㄖㄨ",
"sa": "ㄙㄚ", "se": "ㄙㄜ", "si": "", "su": "ㄙㄨ", "ta": "ㄊㄚ", "te": "ㄊㄜ", "ti": "ㄊㄧ", "tu": "ㄊㄨ", "wa": "ㄨㄚ",
"wo": "ㄨㄛ", "wu": "", "xi": "ㄒㄧ", "xu": "ㄒㄩ", "ya": "ㄧㄚ", "ye": "ㄧㄝ", "yi": "", "yo": "ㄧㄛ", "yu": "", "za": "ㄗㄚ",
"ze": "ㄗㄜ", "zi": "", "zu": "ㄗㄨ", "a": "", "e": "", "o": "", "q": "",
]

/// 標準大千排列專用處理陣列。
/// @--DISCUSSION--@
Expand Down
52 changes: 51 additions & 1 deletion Tests/TekkonTests/TekkonTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,56 @@ final class TekkonTests: XCTestCase {
XCTAssert(result == true)
}

func testKeyReceivingAndCompositions() throws {
func testHanyuPinyinKeyReceivingAndCompositions() throws {
var composer = Tekkon.Composer(arrange: .ofHanyuPinyin)
var toneMarkerIndicator = true

// Test Key Receiving
composer.receiveKey(fromCharCode: 100) // d
composer.receiveKey(fromString: "i")
composer.receiveKey(fromString: "a")
composer.receiveKey(fromString: "o")

// Testing missing tone markers
toneMarkerIndicator = composer.hasToneMarker()
XCTAssert(!toneMarkerIndicator)

composer.receiveKey(fromString: "3") // 上聲
XCTAssertEqual(composer.value, "ㄉㄧㄠˇ")
composer.doBackSpace()
composer.receiveKey(fromString: " ") // 陰平
XCTAssertEqual(composer.value, "ㄉㄧㄠ ") // 這裡回傳的結果的陰平是空格

// Test Getting Real Composition
XCTAssertEqual(composer.realComposition, "ㄉㄧㄠ") // 這裡回傳的結果的陰平無空格

// Test Getting Displayed Composition
XCTAssertEqual(composer.getComposition(), "ㄉㄧㄠ")
XCTAssertEqual(composer.getComposition(isHanyuPinyin: true), "diao1")
XCTAssertEqual(composer.getComposition(isHanyuPinyin: true, isTextBookStyle: true), "diāo")
XCTAssertEqual(composer.getInlineCompositionForIMK(isHanyuPinyin: true), "diao1")

// Test Tone 5
composer.receiveKey(fromString: "7") // 輕聲
XCTAssertEqual(composer.getComposition(), "ㄉㄧㄠ˙")
XCTAssertEqual(composer.getComposition(isTextBookStyle: true), "˙ㄉㄧㄠ")

// Testing having tone markers
toneMarkerIndicator = composer.hasToneMarker()
XCTAssert(toneMarkerIndicator)

// Testing having not-only tone markers
toneMarkerIndicator = composer.hasToneMarker(withNothingElse: true)
XCTAssert(!toneMarkerIndicator)

// Testing having only tone markers
composer.clear()
composer.receiveKey(fromString: "3") // 上聲
toneMarkerIndicator = composer.hasToneMarker(withNothingElse: true)
XCTAssert(toneMarkerIndicator)
}

func testPhonabetKeyReceivingAndCompositions() throws {
var composer = Tekkon.Composer(arrange: .ofDachen)
var toneMarkerIndicator = true

Expand All @@ -93,6 +142,7 @@ final class TekkonTests: XCTestCase {
XCTAssertEqual(composer.getComposition(), "ㄉㄧㄠ")
XCTAssertEqual(composer.getComposition(isHanyuPinyin: true), "diao1")
XCTAssertEqual(composer.getComposition(isHanyuPinyin: true, isTextBookStyle: true), "diāo")
XCTAssertEqual(composer.getInlineCompositionForIMK(isHanyuPinyin: true), "diao1")

// Test Tone 5
composer.receiveKey(fromString: "7") // 輕聲
Expand Down

0 comments on commit dbfab55

Please sign in to comment.