From c9460643857ee86ee13c841bab7d70371e7a365c Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Fri, 5 May 2023 12:54:07 +0800 Subject: [PATCH] Tekkon // (v1.4.2) Integrate phonabetKeyForQuery(). --- .../Tekkon/Tekkon_SyllableComposer.swift | 99 +++++++++++-------- .../InputHandler_HandleComposition.swift | 34 +------ 2 files changed, 60 insertions(+), 73 deletions(-) diff --git a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift index 72577ae9..76e789b9 100644 --- a/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift +++ b/Packages/vChewing_Tekkon/Sources/Tekkon/Tekkon_SyllableComposer.swift @@ -46,6 +46,9 @@ public extension Tekkon { consonant.value + semivowel.value + vowel.value + intonation.value } + /// 當前注拼槽是否處於拼音模式。 + public var isPinyinMode: Bool { parser.rawValue >= 100 } + /// 與 value 類似,這個函式就是用來決定輸入法組字區內顯示的注音/拼音內容, /// 但可以指定是否輸出教科書格式(拼音的調號在字母上方、注音的輕聲寫在左側)。 /// - Parameters: @@ -66,29 +69,23 @@ public extension Tekkon { /// - Parameters: /// - isHanyuPinyin: 是否將輸出結果轉成漢語拼音。 public func getInlineCompositionForDisplay(isHanyuPinyin: Bool = false) -> String { - switch parser { - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: - var toneReturned = "" - switch intonation.value { - case " ": toneReturned = "1" - case "ˊ": toneReturned = "2" - case "ˇ": toneReturned = "3" - case "ˋ": toneReturned = "4" - case "˙": toneReturned = "5" - default: break - } - return romajiBuffer.replacingOccurrences(of: "v", with: "ü") + toneReturned - default: return getComposition(isHanyuPinyin: isHanyuPinyin) + guard isPinyinMode else { return getComposition(isHanyuPinyin: isHanyuPinyin) } + var toneReturned = "" + switch intonation.value { + case " ": toneReturned = "1" + case "ˊ": toneReturned = "2" + case "ˇ": toneReturned = "3" + case "ˋ": toneReturned = "4" + case "˙": toneReturned = "5" + default: break } + return romajiBuffer.replacingOccurrences(of: "v", with: "ü") + toneReturned } /// 注拼槽內容是否為空。 public var isEmpty: Bool { - switch parser { - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: - return intonation.isEmpty && romajiBuffer.isEmpty - default: return intonation.isEmpty && vowel.isEmpty && semivowel.isEmpty && consonant.isEmpty - } + guard !isPinyinMode else { return intonation.isEmpty && romajiBuffer.isEmpty } + return intonation.isEmpty && vowel.isEmpty && semivowel.isEmpty && consonant.isEmpty } /// 注拼槽內容是否可唸。 @@ -197,23 +194,23 @@ public extension Tekkon { /// - Parameters: /// - fromString: 傳入的 String 內容。 public mutating func receiveKey(fromString input: String = "") { - switch parser { - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: - if mapArayuruPinyinIntonation.keys.contains(input) { - if let theTone = mapArayuruPinyinIntonation[input] { - intonation = Phonabet(theTone) - } - } else { - // 為了防止 romajiBuffer 越敲越長帶來算力負擔,這裡讓它在要溢出時自動丟掉最早輸入的音頭。 - let maxCount: Int = (parser == .ofWadeGilesPinyin) ? 7 : 6 - if romajiBuffer.count > maxCount - 1 { - romajiBuffer = String(romajiBuffer.dropFirst()) - } - let romajiBufferBackup = romajiBuffer + input - receiveSequence(romajiBufferBackup, isRomaji: true) - romajiBuffer = romajiBufferBackup + guard isPinyinMode else { + receiveKey(fromPhonabet: translate(key: input)) + return + } + if mapArayuruPinyinIntonation.keys.contains(input) { + if let theTone = mapArayuruPinyinIntonation[input] { + intonation = Phonabet(theTone) } - default: receiveKey(fromPhonabet: translate(key: input)) + } else { + // 為了防止 romajiBuffer 越敲越長帶來算力負擔,這裡讓它在要溢出時自動丟掉最早輸入的音頭。 + let maxCount: Int = (parser == .ofWadeGilesPinyin) ? 7 : 6 + if romajiBuffer.count > maxCount - 1 { + romajiBuffer = String(romajiBuffer.dropFirst()) + } + let romajiBufferBackup = romajiBuffer + input + receiveSequence(romajiBufferBackup, isRomaji: true) + romajiBuffer = romajiBufferBackup } } @@ -325,9 +322,7 @@ public extension Tekkon { /// /// 基本上就是按順序從游標前方開始往後刪。 public mutating func doBackSpace() { - if [.ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin].contains(parser), - !romajiBuffer.isEmpty - { + if isPinyinMode, !romajiBuffer.isEmpty { if !intonation.isEmpty { intonation.clear() } else { @@ -361,7 +356,29 @@ public extension Tekkon { parser = arrange } - // MARK: - Parser Processings + /// 拿取用來進行索引檢索用的注音字串。 + /// + /// 如果輸入法的辭典索引是漢語拼音的話,你可能用不上這個函式。 + /// - Remark: 該字串結果不能為空,否則組字引擎會炸。 + /// - Parameter pronouncable: 是否可以唸出。 + /// - Returns: 可用的查詢用注音字串,或者 nil。 + public func phonabetKeyForQuery(pronouncable: Bool) -> String? { + let readingKey = getComposition() + var validKeyGeneratable = false + switch isPinyinMode { + case false: + switch pronouncable { + case false: + validKeyGeneratable = !readingKey.isEmpty + case true: + validKeyGeneratable = isPronouncable + } + case true: validKeyGeneratable = isPronouncable + } + return validKeyGeneratable ? readingKey : nil + } + + // MARK: - Parser Processing // 注拼槽對內處理用函式都在這一小節。 @@ -371,6 +388,7 @@ public extension Tekkon { /// - Parameters: /// - key: 傳入的 String 訊號。 public mutating func translate(key: String = "") -> String { + guard !isPinyinMode else { return "" } switch parser { case .ofDachen: return Tekkon.mapQwertyDachen[key] ?? "" @@ -392,10 +410,9 @@ public extension Tekkon { return Tekkon.mapFakeSeigyou[key] ?? "" case .ofStarlight: return handleStarlight(key: key) - case .ofHanyuPinyin, .ofSecondaryPinyin, .ofYalePinyin, .ofHualuoPinyin, .ofUniversalPinyin, .ofWadeGilesPinyin: - break // 漢語拼音單獨用另外的函式處理 + default: + return "" } - return "" } /// 所有動態注音鍵盤佈局都會用到的共用糾錯處理步驟。 diff --git a/Source/Modules/InputHandler_HandleComposition.swift b/Source/Modules/InputHandler_HandleComposition.swift index a54312ef..6c4cdea8 100644 --- a/Source/Modules/InputHandler_HandleComposition.swift +++ b/Source/Modules/InputHandler_HandleComposition.swift @@ -94,7 +94,7 @@ extension InputHandler { return handleEnter(input: input, readingOnly: true) } // 拿取用來進行索引檢索用的注音。這裡先不急著處理「僅有注音符號輸入」的情況。 - guard let readingKey = composer.keyForQuery(pronouncable: true) else { break ifComposeReading } + guard let readingKey = composer.phonabetKeyForQuery(pronouncable: true) else { break ifComposeReading } // 向語言模型詢問是否有對應的記錄。 if !currentLM.hasUnigramsFor(keyArray: [readingKey]) { delegate.callError("B49C0979:語彙庫內無「\(readingKey)」的匹配記錄。") @@ -167,7 +167,7 @@ extension InputHandler { /// 但這裡不處理陰平聲調。 if keyConsumedByReading { // 此處將 strict 設為 false,以應對「僅有注音符號輸入」的情況。 - if composer.keyForQuery(pronouncable: false) == nil { + if composer.phonabetKeyForQuery(pronouncable: false) == nil { // 將被空格鍵覆蓋掉的既有聲調塞入組字器。 if !composer.isPinyinMode, input.isSpace, compositor.insertKey(existedIntonation.value) @@ -379,33 +379,3 @@ extension InputHandler { } } } - -// MARK: - Private Extensions for Tekkon Composer - -// 此處的功能擴充大概只會在威注音輸入法當中用到。 - -extension Tekkon.Composer { - /// 闡明當前注拼槽是否處於拼音模式。 - var isPinyinMode: Bool { parser.rawValue >= 100 } - - /// 拿取用來進行索引檢索用的注音。 - /// 如果輸入法的辭典索引是漢語拼音的話,要注意改這裡、使其拿到的內容是漢語拼音。 - /// - Remark: 該字串不能為空,否則組字引擎會炸。 - /// - Parameter pronouncable: 是否可以唸出。 - /// - Returns: 可用的查詢用注音字串,或者 nil。 - func keyForQuery(pronouncable: Bool) -> String? { - let readingKey = getComposition() - var validKeyGeneratable = false - switch isPinyinMode { - case false: - switch pronouncable { - case false: - validKeyGeneratable = !readingKey.isEmpty - case true: - validKeyGeneratable = isPronouncable - } - case true: validKeyGeneratable = isPronouncable - } - return validKeyGeneratable ? readingKey : nil - } -}