diff --git a/Packages/vChewing_Tekkon/README.md b/Packages/vChewing_Tekkon/README.md index 96ee7349..516dbf7d 100644 --- a/Packages/vChewing_Tekkon/README.md +++ b/Packages/vChewing_Tekkon/README.md @@ -9,13 +9,13 @@ 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. -羅馬拼音輸入目前僅支援漢語拼音、國音二式、耶魯拼音、華羅拼音、通用拼音。 +羅馬拼音輸入目前僅支援漢語拼音、國音二式、耶魯拼音、華羅拼音、通用拼音、韋氏拼音(威妥瑪拼音)。 -- 因為**韋氏拼音(威妥瑪拼音)輔音清濁不分的問題非常嚴重**、無法與注音符號形成逐一對應,故鐵恨引擎在技術上無法實現對韋氏拼音的支援。 +- 因為**趙元任國語羅馬字拼音「無法製作通用的聲調確認鍵」**,故鐵恨引擎在技術上無法實現對趙元任國語羅馬字拼音的支援。 -Regarding pinyin input support, we only support: Hanyu Pinyin, Secondary Pinyin, Yale Pinyin, Hualuo Pinyin, and Universal Pinyin. +Regarding pinyin input support, we only support: Hanyu Pinyin, Secondary Pinyin, Yale Pinyin, Hualuo Pinyin, Wade-Giles Pinyin and Universal Pinyin. -- **Tekkon is unable to provide Wade–Giles Pinyin support** since it is impossible to make one-to-one mappings to all possible phonabet combinations (especially it cannot distinguish "k" and "g"). +- **Tekkon is unable to provide support for Zhao Yuan-Ren's Gwoyeu Romatzyh at this moment** because there is no consistent method to check whether the intonation key has been pressed. Tekkon is designed to confirm input with intonation keys. > 注意:該引擎會將「ㄅㄨㄥ ㄆㄨㄥ ㄇㄨㄥ ㄈㄨㄥ」這四種讀音自動轉換成「ㄅㄥ ㄆㄥ ㄇㄥ ㄈㄥ」、將「ㄅㄨㄛ ㄆㄨㄛ ㄇㄨㄛ ㄈㄨㄛ」這四種讀音自動轉換成「ㄅㄛ ㄆㄛ ㄇㄛ ㄈㄛ」。如果您正在開發的輸入法的詞庫內的「甮」字的讀音沒有從「ㄈㄨㄥˋ」改成「ㄈㄥˋ」、或者說需要保留「ㄈㄨㄥˋ」的讀音的話,請按需修改「receiveKey(fromPhonabet:)」函式當中的相關步驟、來跳過該轉換。該情形為十分罕見之情形。類似情形則是台澎金馬審音的慣用讀音「ㄌㄩㄢˊ」,因為使用者眾、所以不會被該引擎自動轉換成「ㄌㄨㄢˊ」。威注音輸入法內部已經從辭典角度做了處理、允許在敲「ㄌㄨㄢˊ」的時候出現以「ㄌㄩㄢˊ」為讀音的漢字。我們鼓勵輸入法開發者們使用 [威注音語彙庫](https://gitee.com/vChewing/libvchewing-data) 來實現對兩岸讀音習慣的同時兼顧。 diff --git a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Constants.swift b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Constants.swift index 534525af..6f5651f1 100644 --- a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Constants.swift +++ b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Constants.swift @@ -143,10 +143,15 @@ public enum Tekkon { // MARK: - Maps for Keyboard-to-Pinyin parsers - /// 任何形式的拼音排列都會用到的陣列,用 Strings 反而省事一些。 + /// 任何形式的拼音排列都會用到的陣列(韋氏拼音與趙元任國語羅馬字除外), + /// 用 Strings 反而省事一些。 /// 這裡同時兼容大千注音的調號數字,所以也將 6、7 號數字鍵放在允許範圍內。 static let mapArayuruPinyin: String = "abcdefghijklmnopqrstuvwxyz1234567 " + /// 韋氏拼音專用會用到的陣列,用 Strings 反而省事一些。 + /// 這裡同時兼容大千注音的調號數字,所以也將 6、7 號數字鍵放在允許範圍內。 + static var mapWadeGilesPinyinKeys: String = mapArayuruPinyin + "'" + /// 任何拼音都會用到的聲調鍵陣列 static let mapArayuruPinyinIntonation: [String: String] = [ "1": " ", "2": "ˊ", "3": "ˇ", "4": "ˋ", "5": "˙", "6": "ˊ", "7": "˙", " ": " ", @@ -453,6 +458,72 @@ public enum Tekkon { "c": "ㄑ", "o": "ㄛ", "e": "ㄜ", "a": "ㄚ", ] + /// 韋氏拼音排列專用處理陣列 + static let mapWadeGilesPinyin: [String: String] = [ + "a": "ㄚ", "ai": "ㄞ", "an": "ㄢ", "ang": "ㄤ", "ao": "ㄠ", "cha": "ㄓㄚ", "chai": "ㄓㄞ", "chan": "ㄓㄢ", + "chang": "ㄓㄤ", "chao": "ㄓㄠ", "che": "ㄓㄜ", "chei": "ㄓㄟ", "chen": "ㄓㄣ", "cheng": "ㄓㄥ", "chi": "ㄐㄧ", + "chia": "ㄐㄧㄚ", "chiang": "ㄐㄧㄤ", "chiao": "ㄐㄧㄠ", "chieh": "ㄐㄧㄝ", "chien": "ㄐㄧㄢ", "chih": "ㄓ", + "chin": "ㄐㄧㄣ", "ching": "ㄐㄧㄥ", "chiu": "ㄐㄧㄡ", "chiung": "ㄐㄩㄥ", "cho": "ㄓㄨㄛ", "chou": "ㄓㄡ", + "chu": "ㄓㄨ", "chua": "ㄓㄨㄚ", "chuai": "ㄓㄨㄞ", "chuan": "ㄓㄨㄢ", "chuang": "ㄓㄨㄤ", "chui": "ㄓㄨㄟ", + "chun": "ㄓㄨㄣ", "chung": "ㄓㄨㄥ", "ch'a": "ㄔㄚ", "ch'ai": "ㄔㄞ", "ch'an": "ㄔㄢ", "ch'ang": "ㄔㄤ", + "ch'ao": "ㄔㄠ", "ch'e": "ㄔㄜ", "ch'en": "ㄔㄣ", "ch'eng": "ㄔㄥ", "ch'i": "ㄑㄧ", "ch'ia": "ㄑㄧㄚ", + "ch'iang": "ㄑㄧㄤ", "ch'iao": "ㄑㄧㄠ", "ch'ieh": "ㄑㄧㄝ", "ch'ien": "ㄑㄧㄢ", "ch'ih": "ㄔ", "ch'in": "ㄑㄧㄣ", + "ch'ing": "ㄑㄧㄥ", "ch'iu": "ㄑㄧㄡ", "ch'iung": "ㄑㄩㄥ", "ch'o": "ㄔㄨㄛ", "ch'ou": "ㄔㄡ", "ch'u": "ㄔㄨ", + "ch'ua": "ㄔㄨㄚ", "ch'uai": "ㄔㄨㄞ", "ch'uan": "ㄔㄨㄢ", "ch'uang": "ㄔㄨㄤ", "ch'ui": "ㄔㄨㄟ", + "ch'un": "ㄔㄨㄣ", "ch'ung": "ㄔㄨㄥ", "ch'v": "ㄑㄩ", "ch'van": "ㄑㄩㄢ", "ch'veh": "ㄑㄩㄝ", "ch'vn": "ㄑㄩㄣ", + "chv": "ㄐㄩ", "chvan": "ㄐㄩㄢ", "chveh": "ㄐㄩㄝ", "chvn": "ㄐㄩㄣ", "e": "ㄜ", "ei": "ㄟ", "en": "ㄣ", + "erh": "ㄦ", "fa": "ㄈㄚ", "fan": "ㄈㄢ", "fang": "ㄈㄤ", "fei": "ㄈㄟ", "fen": "ㄈㄣ", "feng": "ㄈㄥ", + "fo": "ㄈㄛ", "fou": "ㄈㄡ", "fu": "ㄈㄨ", "ha": "ㄏㄚ", "hai": "ㄏㄞ", "han": "ㄏㄢ", "hang": "ㄏㄤ", + "hao": "ㄏㄠ", "hei": "ㄏㄟ", "hen": "ㄏㄣ", "heng": "ㄏㄥ", "ho": "ㄏㄜ", "hou": "ㄏㄡ", "hsi": "ㄒㄧ", + "hsia": "ㄒㄧㄚ", "hsiang": "ㄒㄧㄤ", "hsiao": "ㄒㄧㄠ", "hsieh": "ㄒㄧㄝ", "hsien": "ㄒㄧㄢ", "hsin": "ㄒㄧㄣ", + "hsing": "ㄒㄧㄥ", "hsiu": "ㄒㄧㄡ", "hsiung": "ㄒㄩㄥ", "hsv": "ㄒㄩ", "hsvan": "ㄒㄩㄢ", "hsveh": "ㄒㄩㄝ", + "hsvn": "ㄒㄩㄣ", "hu": "ㄏㄨ", "hua": "ㄏㄨㄚ", "huai": "ㄏㄨㄞ", "huan": "ㄏㄨㄢ", "huang": "ㄏㄨㄤ", + "hui": "ㄏㄨㄟ", "hun": "ㄏㄨㄣ", "hung": "ㄏㄨㄥ", "huo": "ㄏㄨㄛ", "i": "ㄧ", "jan": "ㄖㄢ", "jang": "ㄖㄤ", + "jao": "ㄖㄠ", "je": "ㄖㄜ", "jen": "ㄖㄣ", "jeng": "ㄖㄥ", "jih": "ㄖ", "jo": "ㄖㄨㄛ", "jou": "ㄖㄡ", + "ju": "ㄖㄨ", "juan": "ㄖㄨㄢ", "jui": "ㄖㄨㄟ", "jun": "ㄖㄨㄣ", "jung": "ㄖㄨㄥ", "ka": "ㄍㄚ", "kai": "ㄍㄞ", + "kan": "ㄍㄢ", "kang": "ㄍㄤ", "kao": "ㄍㄠ", "kei": "ㄍㄟ", "ken": "ㄍㄣ", "keng": "ㄍㄥ", "ko": "ㄍㄜ", + "kou": "ㄍㄡ", "ku": "ㄍㄨ", "kua": "ㄍㄨㄚ", "kuai": "ㄍㄨㄞ", "kuan": "ㄍㄨㄢ", "kuang": "ㄍㄨㄤ", + "kuei": "ㄍㄨㄟ", "kun": "ㄍㄨㄣ", "kung": "ㄍㄨㄥ", "kuo": "ㄍㄨㄛ", "k'a": "ㄎㄚ", "k'ai": "ㄎㄞ", "k'an": "ㄎㄢ", + "k'ang": "ㄎㄤ", "k'ao": "ㄎㄠ", "k'en": "ㄎㄣ", "k'eng": "ㄎㄥ", "k'o": "ㄎㄜ", "k'ou": "ㄎㄡ", "k'u": "ㄎㄨ", + "k'ua": "ㄎㄨㄚ", "k'uai": "ㄎㄨㄞ", "k'uan": "ㄎㄨㄢ", "k'uang": "ㄎㄨㄤ", "k'uei": "ㄎㄨㄟ", "k'un": "ㄎㄨㄣ", + "k'ung": "ㄎㄨㄥ", "k'uo": "ㄎㄨㄛ", "la": "ㄌㄚ", "lai": "ㄌㄞ", "lan": "ㄌㄢ", "lang": "ㄌㄤ", "lao": "ㄌㄠ", + "le": "ㄌㄜ", "lei": "ㄌㄟ", "leng": "ㄌㄥ", "li": "ㄌㄧ", "lia": "ㄌㄧㄚ", "liang": "ㄌㄧㄤ", "liao": "ㄌㄧㄠ", + "lieh": "ㄌㄧㄝ", "lien": "ㄌㄧㄢ", "lin": "ㄌㄧㄣ", "ling": "ㄌㄧㄥ", "liu": "ㄌㄧㄡ", "lo": "ㄌㄨㄛ", "lou": "ㄌㄡ", + "lu": "ㄌㄨ", "luan": "ㄌㄨㄢ", "lun": "ㄌㄨㄣ", "lung": "ㄌㄨㄥ", "lv": "ㄌㄩ", "lveh": "ㄌㄩㄝ", "lvn": "ㄌㄩㄣ", + "ma": "ㄇㄚ", "mai": "ㄇㄞ", "man": "ㄇㄢ", "mang": "ㄇㄤ", "mao": "ㄇㄠ", "me": "ㄇㄜ", "mei": "ㄇㄟ", + "men": "ㄇㄣ", "meng": "ㄇㄥ", "mi": "ㄇㄧ", "miao": "ㄇㄧㄠ", "mieh": "ㄇㄧㄝ", "mien": "ㄇㄧㄢ", "min": "ㄇㄧㄣ", + "ming": "ㄇㄧㄥ", "miu": "ㄇㄧㄡ", "mo": "ㄇㄛ", "mou": "ㄇㄡ", "mu": "ㄇㄨ", "na": "ㄋㄚ", "nai": "ㄋㄞ", + "nan": "ㄋㄢ", "nang": "ㄋㄤ", "nao": "ㄋㄠ", "ne": "ㄋㄜ", "nei": "ㄋㄟ", "nen": "ㄋㄣ", "neng": "ㄋㄥ", + "ni": "ㄋㄧ", "nia": "ㄋㄧㄚ", "niang": "ㄋㄧㄤ", "niao": "ㄋㄧㄠ", "nieh": "ㄋㄧㄝ", "nien": "ㄋㄧㄢ", + "nin": "ㄋㄧㄣ", "ning": "ㄋㄧㄥ", "niu": "ㄋㄧㄡ", "no": "ㄋㄨㄛ", "nou": "ㄋㄡ", "nu": "ㄋㄨ", "nuan": "ㄋㄨㄢ", + "nun": "ㄋㄨㄣ", "nung": "ㄋㄨㄥ", "nv": "ㄋㄩ", "nveh": "ㄋㄩㄝ", "ou": "ㄡ", "pa": "ㄅㄚ", "pai": "ㄅㄞ", + "pan": "ㄅㄢ", "pang": "ㄅㄤ", "pao": "ㄅㄠ", "pei": "ㄅㄟ", "pen": "ㄅㄣ", "peng": "ㄅㄥ", "pi": "ㄅㄧ", + "piao": "ㄅㄧㄠ", "pieh": "ㄅㄧㄝ", "pien": "ㄅㄧㄢ", "pin": "ㄅㄧㄣ", "ping": "ㄅㄧㄥ", "po": "ㄅㄛ", "pu": "ㄅㄨ", + "p'a": "ㄆㄚ", "p'ai": "ㄆㄞ", "p'an": "ㄆㄢ", "p'ang": "ㄆㄤ", "p'ao": "ㄆㄠ", "p'ei": "ㄆㄟ", "p'en": "ㄆㄣ", + "p'eng": "ㄆㄥ", "p'i": "ㄆㄧ", "p'iao": "ㄆㄧㄠ", "p'ieh": "ㄆㄧㄝ", "p'ien": "ㄆㄧㄢ", "p'in": "ㄆㄧㄣ", + "p'ing": "ㄆㄧㄥ", "p'o": "ㄆㄛ", "p'ou": "ㄆㄡ", "p'u": "ㄆㄨ", "sa": "ㄙㄚ", "sai": "ㄙㄞ", "san": "ㄙㄢ", + "sang": "ㄙㄤ", "sao": "ㄙㄠ", "se": "ㄙㄜ", "sei": "ㄙㄟ", "sen": "ㄙㄣ", "seng": "ㄙㄥ", "sha": "ㄕㄚ", + "shai": "ㄕㄞ", "shan": "ㄕㄢ", "shang": "ㄕㄤ", "shao": "ㄕㄠ", "she": "ㄕㄜ", "shei": "ㄕㄟ", "shen": "ㄕㄣ", + "sheng": "ㄕㄥ", "shih": "ㄕ", "shou": "ㄕㄡ", "shu": "ㄕㄨ", "shua": "ㄕㄨㄚ", "shuai": "ㄕㄨㄞ", + "shuan": "ㄕㄨㄢ", "shuang": "ㄕㄨㄤ", "shui": "ㄕㄨㄟ", "shun": "ㄕㄨㄣ", "shung": "ㄕㄨㄥ", "shuo": "ㄕㄨㄛ", + "so": "ㄙㄨㄛ", "sou": "ㄙㄡ", "ssu": "ㄙ", "su": "ㄙㄨ", "suan": "ㄙㄨㄢ", "sui": "ㄙㄨㄟ", "sun": "ㄙㄨㄣ", + "sung": "ㄙㄨㄥ", "ta": "ㄉㄚ", "tai": "ㄉㄞ", "tan": "ㄉㄢ", "tang": "ㄉㄤ", "tao": "ㄉㄠ", "te": "ㄉㄜ", + "tei": "ㄉㄟ", "ten": "ㄉㄣ", "teng": "ㄉㄥ", "ti": "ㄉㄧ", "tiang": "ㄉㄧㄤ", "tiao": "ㄉㄧㄠ", "tieh": "ㄉㄧㄝ", + "tien": "ㄉㄧㄢ", "ting": "ㄉㄧㄥ", "tiu": "ㄉㄧㄡ", "to": "ㄉㄨㄛ", "tou": "ㄉㄡ", "tsa": "ㄗㄚ", "tsai": "ㄗㄞ", + "tsan": "ㄗㄢ", "tsang": "ㄗㄤ", "tsao": "ㄗㄠ", "tse": "ㄗㄜ", "tsei": "ㄗㄟ", "tsen": "ㄗㄣ", "tseng": "ㄗㄥ", + "tso": "ㄗㄨㄛ", "tsou": "ㄗㄡ", "tsu": "ㄗㄨ", "tsuan": "ㄗㄨㄢ", "tsui": "ㄗㄨㄟ", "tsun": "ㄗㄨㄣ", + "tsung": "ㄗㄨㄥ", "ts'a": "ㄘㄚ", "ts'ai": "ㄘㄞ", "ts'an": "ㄘㄢ", "ts'ang": "ㄘㄤ", "ts'ao": "ㄘㄠ", + "ts'e": "ㄘㄜ", "ts'en": "ㄘㄣ", "ts'eng": "ㄘㄥ", "ts'o": "ㄘㄨㄛ", "ts'ou": "ㄘㄡ", "ts'u": "ㄘㄨ", + "ts'uan": "ㄘㄨㄢ", "ts'ui": "ㄘㄨㄟ", "ts'un": "ㄘㄨㄣ", "ts'ung": "ㄘㄨㄥ", "tu": "ㄉㄨ", "tuan": "ㄉㄨㄢ", + "tui": "ㄉㄨㄟ", "tun": "ㄉㄨㄣ", "tung": "ㄉㄨㄥ", "tzu": "ㄗ", "tz'u": "ㄘ", "t'a": "ㄊㄚ", "t'ai": "ㄊㄞ", + "t'an": "ㄊㄢ", "t'ang": "ㄊㄤ", "t'ao": "ㄊㄠ", "t'e": "ㄊㄜ", "t'eng": "ㄊㄥ", "t'i": "ㄊㄧ", + "t'iao": "ㄊㄧㄠ", "t'ieh": "ㄊㄧㄝ", "t'ien": "ㄊㄧㄢ", "t'ing": "ㄊㄧㄥ", "t'o": "ㄊㄨㄛ", "t'ou": "ㄊㄡ", + "t'u": "ㄊㄨ", "t'uan": "ㄊㄨㄢ", "t'ui": "ㄊㄨㄟ", "t'un": "ㄊㄨㄣ", "t'ung": "ㄊㄨㄥ", "wa": "ㄨㄚ", + "wai": "ㄨㄞ", "wan": "ㄨㄢ", "wang": "ㄨㄤ", "wei": "ㄨㄟ", "wen": "ㄨㄣ", "weng": "ㄨㄥ", "wo": "ㄨㄛ", + "wu": "ㄨ", "ya": "ㄧㄚ", "yan": "ㄧㄢ", "yang": "ㄧㄤ", "yao": "ㄧㄠ", "yeh": "ㄧㄝ", "yin": "ㄧㄣ", + "ying": "ㄧㄥ", "yu": "ㄧㄡ", "yung": "ㄩㄥ", "yv": "ㄩ", "yvan": "ㄩㄢ", "yveh": "ㄩㄝ", "yvn": "ㄩㄣ", + ] + // MARK: - Maps for Keyboard-to-Phonabet parsers /// 標準大千排列專用處理陣列。 diff --git a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Phonabets.swift b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Phonabets.swift index 4a5513fa..7e288134 100644 --- a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Phonabets.swift +++ b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_Phonabets.swift @@ -37,6 +37,7 @@ public extension Tekkon { case ofYalePinyin = 102 case ofHualuoPinyin = 103 case ofUniversalPinyin = 104 + case ofWadeGilesPinyin = 105 var name: String { switch self { @@ -70,6 +71,8 @@ public extension Tekkon { return "HualuoPinyin" case .ofUniversalPinyin: return "UniversalPinyin" + case .ofWadeGilesPinyin: + return "WadeGilesPinyin" } } } diff --git a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift index 558e2da6..a444650a 100644 --- a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift +++ b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift @@ -67,7 +67,7 @@ public extension Tekkon { /// - isHanyuPinyin: 是否將輸出結果轉成漢語拼音。 public func getInlineCompositionForDisplay(isHanyuPinyin: Bool = false) -> String { switch parser { - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin: + case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: var toneReturned = "" switch intonation.value { case " ": toneReturned = "1" @@ -77,7 +77,7 @@ public extension Tekkon { case "˙": toneReturned = "5" default: break } - return romajiBuffer + toneReturned + return romajiBuffer.replacingOccurrences(of: "v", with: "ü") + toneReturned default: return getComposition(isHanyuPinyin: isHanyuPinyin) } } @@ -85,7 +85,7 @@ public extension Tekkon { /// 注拼槽內容是否為空。 public var isEmpty: Bool { switch parser { - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin: + case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: return intonation.isEmpty && romajiBuffer.isEmpty default: return intonation.isEmpty && vowel.isEmpty && semivowel.isEmpty && consonant.isEmpty } @@ -151,6 +151,8 @@ public extension Tekkon { return Tekkon.mapFakeSeigyou[input] != nil case .ofStarlight: return Tekkon.mapStarlightStaticKeys[input] != nil + case .ofWadeGilesPinyin: + return Tekkon.mapWadeGilesPinyinKeys.contains(input) case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin: return Tekkon.mapArayuruPinyin.contains(input) } @@ -171,14 +173,15 @@ public extension Tekkon { /// - fromString: 傳入的 String 內容。 public mutating func receiveKey(fromString input: String = "") { switch parser { - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin: + case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: if mapArayuruPinyinIntonation.keys.contains(input) { if let theTone = mapArayuruPinyinIntonation[input] { intonation = Phonabet(theTone) } } else { // 為了防止 romajiBuffer 越敲越長帶來算力負擔,這裡讓它在要溢出時自動丟掉最早輸入的音頭。 - if romajiBuffer.count > 5 { + let maxCount: Int = (parser == .ofWadeGilesPinyin) ? 7 : 6 + if romajiBuffer.count > maxCount - 1 { romajiBuffer = String(romajiBuffer.dropFirst()) } let romajiBufferBackup = romajiBuffer + input @@ -261,45 +264,27 @@ public extension Tekkon { /// - isRomaji: 如果輸入的字串是諸如漢語拼音這樣的西文字母拼音的話,請啟用此選項。 public mutating func receiveSequence(_ givenSequence: String = "", isRomaji: Bool = false) { clear() - if isRomaji { - switch parser { - case .ofHanyuPinyin: - if let dictResult = mapHanyuPinyin[givenSequence] { - for phonabet in dictResult { - receiveKey(fromPhonabet: String(phonabet)) - } - } - case .ofSecondaryPinyin: - if let dictResult = mapSecondaryPinyin[givenSequence] { - for phonabet in dictResult { - receiveKey(fromPhonabet: String(phonabet)) - } - } - case .ofYalePinyin: - if let dictResult = mapYalePinyin[givenSequence] { - for phonabet in dictResult { - receiveKey(fromPhonabet: String(phonabet)) - } - } - case .ofHualuoPinyin: - if let dictResult = mapHualuoPinyin[givenSequence] { - for phonabet in dictResult { - receiveKey(fromPhonabet: String(phonabet)) - } - } - case .ofUniversalPinyin: - if let dictResult = mapUniversalPinyin[givenSequence] { - for phonabet in dictResult { - receiveKey(fromPhonabet: String(phonabet)) - } - } - default: break - } - } else { - for key in givenSequence { - receiveKey(fromString: String(key)) - } + guard isRomaji else { + givenSequence.forEach { receiveKey(fromString: $0.description) } + return } + var dictResult: String? + switch parser { + case .ofHanyuPinyin: + dictResult = mapHanyuPinyin[givenSequence] + case .ofSecondaryPinyin: + dictResult = mapSecondaryPinyin[givenSequence] + case .ofYalePinyin: + dictResult = mapYalePinyin[givenSequence] + case .ofHualuoPinyin: + dictResult = mapHualuoPinyin[givenSequence] + case .ofUniversalPinyin: + dictResult = mapUniversalPinyin[givenSequence] + case .ofWadeGilesPinyin: + dictResult = mapWadeGilesPinyin[givenSequence] + default: break + } + dictResult?.forEach { receiveKey(fromPhonabet: $0.description) } } /// 處理一連串的按鍵輸入、且返回被處理之後的注音(陰平為空格)。 @@ -315,7 +300,7 @@ public extension Tekkon { /// /// 基本上就是按順序從游標前方開始往後刪。 public mutating func doBackSpace() { - if [.ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin].contains(parser), + if [.ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin].contains(parser), !romajiBuffer.isEmpty { if !intonation.isEmpty { @@ -382,7 +367,7 @@ public extension Tekkon { return Tekkon.mapFakeSeigyou[key] ?? "" case .ofStarlight: return handleStarlight(key: key) - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin: + case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: break // 漢語拼音單獨用另外的函式處理 } return "" diff --git a/Packages/vChewing_Tekkon/Tests/TekkonTests/BasicTests.swift b/Packages/vChewing_Tekkon/Tests/TekkonTests/BasicTests.swift index 81b4a14f..03754462 100644 --- a/Packages/vChewing_Tekkon/Tests/TekkonTests/BasicTests.swift +++ b/Packages/vChewing_Tekkon/Tests/TekkonTests/BasicTests.swift @@ -454,4 +454,53 @@ final class TekkonTestsPinyin: XCTestCase { toneMarkerIndicator = composer.hasIntonation(withNothingElse: true) XCTAssert(toneMarkerIndicator) } + + func testWadeGilesPinyinKeyReceivingAndCompositions() throws { + var composer = Tekkon.Composer(arrange: .ofWadeGilesPinyin) + var toneMarkerIndicator = true + + // Test Key Receiving + composer.receiveKey(fromCharCode: 99) // c + composer.receiveKey(fromString: "h") + composer.receiveKey(fromString: "'") // 韋氏拼音清濁分辨鍵 + composer.receiveKey(fromString: "i") + composer.receiveKey(fromString: "u") + composer.receiveKey(fromString: "n") + composer.receiveKey(fromString: "g") + + // Testing missing tone markers + toneMarkerIndicator = composer.hasIntonation() + XCTAssert(!toneMarkerIndicator) + + composer.receiveKey(fromString: "2") // 陽平 + XCTAssertEqual(composer.value, "ㄑㄩㄥˊ") + composer.doBackSpace() + composer.receiveKey(fromString: " ") // 陰平 + XCTAssertEqual(composer.value, "ㄑㄩㄥ ") // 這裡回傳的結果的陰平是空格 + + // Test Getting Displayed Composition + XCTAssertEqual(composer.getComposition(), "ㄑㄩㄥ") + XCTAssertEqual(composer.getComposition(isHanyuPinyin: true), "qiong1") + XCTAssertEqual(composer.getComposition(isHanyuPinyin: true, isTextBookStyle: true), "qiōng") + XCTAssertEqual(composer.getInlineCompositionForDisplay(isHanyuPinyin: true), "ch'iung1") + + // Test Tone 5 + composer.receiveKey(fromString: "7") // 輕聲 + XCTAssertEqual(composer.getComposition(), "ㄑㄩㄥ˙") + XCTAssertEqual(composer.getComposition(isTextBookStyle: true), "˙ㄑㄩㄥ") + + // Testing having tone markers + toneMarkerIndicator = composer.hasIntonation() + XCTAssert(toneMarkerIndicator) + + // Testing having not-only tone markers + toneMarkerIndicator = composer.hasIntonation(withNothingElse: true) + XCTAssert(!toneMarkerIndicator) + + // Testing having only tone markers + composer.clear() + composer.receiveKey(fromString: "3") // 上聲 + toneMarkerIndicator = composer.hasIntonation(withNothingElse: true) + XCTAssert(toneMarkerIndicator) + } }