LMCassette // Enhanced support for `%quick` section.
This commit is contained in:
parent
5f2fb57f91
commit
e771654a2f
|
@ -15,6 +15,20 @@ public extension vChewingLM.LMInstantiator {
|
||||||
var cassetteWildcardKey: String { Self.lmCassette.wildcardKey }
|
var cassetteWildcardKey: String { Self.lmCassette.wildcardKey }
|
||||||
/// 當前磁帶規定的最大碼長。
|
/// 當前磁帶規定的最大碼長。
|
||||||
var maxCassetteKeyLength: Int { Self.lmCassette.maxKeyLength }
|
var maxCassetteKeyLength: Int { Self.lmCassette.maxKeyLength }
|
||||||
|
/// 磁帶模式專用函式:指定 `%quick` 快速候選結果當中要過濾掉的無效候選字符號。
|
||||||
|
var nullCandidateInCassette: String { Self.lmCassette.nullCandidate }
|
||||||
|
/// 選字鍵,在威注音輸入法當中僅優先用於快速模式。
|
||||||
|
var cassetteSelectionKey: String? {
|
||||||
|
let result = Self.lmCassette.selectionKeys
|
||||||
|
return result.isEmpty ? nil : result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 磁帶模式專用函式:調取 `%quick` 快速候選結果。
|
||||||
|
/// - Parameter key: 按鍵字元。
|
||||||
|
/// - Returns: 結果。
|
||||||
|
func cassetteQuickSetsFor(key: String) -> String? {
|
||||||
|
Self.lmCassette.quickSetsFor(key: key)
|
||||||
|
}
|
||||||
|
|
||||||
/// 將當前的按鍵轉換成磁帶內定義了的字根。
|
/// 將當前的按鍵轉換成磁帶內定義了的字根。
|
||||||
/// - Parameter char: 按鍵字元。
|
/// - Parameter char: 按鍵字元。
|
||||||
|
|
|
@ -20,12 +20,14 @@ public extension vChewingLM {
|
||||||
public private(set) var nameENG: String = ""
|
public private(set) var nameENG: String = ""
|
||||||
public private(set) var nameCJK: String = ""
|
public private(set) var nameCJK: String = ""
|
||||||
public private(set) var nameIntl: String = ""
|
public private(set) var nameIntl: String = ""
|
||||||
|
public private(set) var nullCandidate: String = ""
|
||||||
/// 一個漢字可能最多要用到多少碼。
|
/// 一個漢字可能最多要用到多少碼。
|
||||||
public private(set) var maxKeyLength: Int = 1
|
public private(set) var maxKeyLength: Int = 1
|
||||||
public private(set) var selectionKeys: [String] = []
|
public private(set) var selectionKeys: String = ""
|
||||||
public private(set) var endKeys: [String] = []
|
public private(set) var endKeys: [String] = []
|
||||||
public private(set) var wildcardKey: String = ""
|
public private(set) var wildcardKey: String = ""
|
||||||
public private(set) var keyNameMap: [String: String] = [:]
|
public private(set) var keyNameMap: [String: String] = [:]
|
||||||
|
public private(set) var quickDefMap: [String: String] = [:]
|
||||||
public private(set) var charDefMap: [String: [String]] = [:]
|
public private(set) var charDefMap: [String: [String]] = [:]
|
||||||
public private(set) var charDefWildcardMap: [String: [String]] = [:]
|
public private(set) var charDefWildcardMap: [String: [String]] = [:]
|
||||||
public private(set) var reverseLookupMap: [String: [String]] = [:]
|
public private(set) var reverseLookupMap: [String: [String]] = [:]
|
||||||
|
@ -40,7 +42,7 @@ public extension vChewingLM {
|
||||||
|
|
||||||
/// 萬用花牌字符,哪怕花牌鍵仍不可用。
|
/// 萬用花牌字符,哪怕花牌鍵仍不可用。
|
||||||
public var wildcard: String { wildcardKey.isEmpty ? "†" : wildcardKey }
|
public var wildcard: String { wildcardKey.isEmpty ? "†" : wildcardKey }
|
||||||
/// 資料陣列內承載的資料筆數。
|
/// 資料陣列內承載的核心 charDef 資料筆數。
|
||||||
public var count: Int { charDefMap.count }
|
public var count: Int { charDefMap.count }
|
||||||
/// 是否已有資料載入。
|
/// 是否已有資料載入。
|
||||||
public var isLoaded: Bool { !charDefMap.isEmpty }
|
public var isLoaded: Bool { !charDefMap.isEmpty }
|
||||||
|
@ -60,6 +62,7 @@ public extension vChewingLM {
|
||||||
/// - `%selkey` 不處理,因為威注音輸入法有自己的選字鍵體系。
|
/// - `%selkey` 不處理,因為威注音輸入法有自己的選字鍵體系。
|
||||||
/// - `%endkey` 是會觸發組字事件的按鍵。
|
/// - `%endkey` 是會觸發組字事件的按鍵。
|
||||||
/// - `%wildcardkey` 決定磁帶的萬能鍵名稱,只有第一個字元會生效。
|
/// - `%wildcardkey` 決定磁帶的萬能鍵名稱,只有第一個字元會生效。
|
||||||
|
/// - `%nullcandidate` 用來指明 `%quick` 字段給出的候選字當中有哪一種是無效的。
|
||||||
/// - `%keyname begin` 至 `%keyname end` 之間是字根翻譯表,先讀取為 Swift 辭典以備用。
|
/// - `%keyname begin` 至 `%keyname end` 之間是字根翻譯表,先讀取為 Swift 辭典以備用。
|
||||||
/// - `%quick begin` 至 `%quick end` 之間則是簡碼資料,對應的 value 得拆成單個漢字。
|
/// - `%quick begin` 至 `%quick end` 之間則是簡碼資料,對應的 value 得拆成單個漢字。
|
||||||
/// - `%chardef begin` 至 `%chardef end` 之間則是詞庫資料。
|
/// - `%chardef begin` 至 `%chardef end` 之間則是詞庫資料。
|
||||||
|
@ -90,7 +93,7 @@ public extension vChewingLM {
|
||||||
}
|
}
|
||||||
if loadingQuickSets, strLine.contains("%quick"), strLine.contains("end") {
|
if loadingQuickSets, strLine.contains("%quick"), strLine.contains("end") {
|
||||||
loadingQuickSets = false
|
loadingQuickSets = false
|
||||||
if charDefMap.keys.contains(wildcardKey) { wildcardKey = "" }
|
if quickDefMap.keys.contains(wildcardKey) { wildcardKey = "" }
|
||||||
}
|
}
|
||||||
if !loadingCharDefinitions, strLine.contains("%chardef"), strLine.contains("begin") {
|
if !loadingCharDefinitions, strLine.contains("%chardef"), strLine.contains("begin") {
|
||||||
loadingCharDefinitions = true
|
loadingCharDefinitions = true
|
||||||
|
@ -114,14 +117,7 @@ public extension vChewingLM {
|
||||||
keyNameMap[strFirstCell] = cells[1].trimmingCharacters(in: .newlines)
|
keyNameMap[strFirstCell] = cells[1].trimmingCharacters(in: .newlines)
|
||||||
} else if loadingQuickSets, !strLine.contains("%quick") {
|
} else if loadingQuickSets, !strLine.contains("%quick") {
|
||||||
theMaxKeyLength = max(theMaxKeyLength, cells[0].count)
|
theMaxKeyLength = max(theMaxKeyLength, cells[0].count)
|
||||||
let arrSecondCell = strSecondCell.map(\.description)
|
quickDefMap[strFirstCell, default: .init()].append(strSecondCell)
|
||||||
charDefMap[strFirstCell, default: []].append(contentsOf: arrSecondCell)
|
|
||||||
reverseLookupMap[strSecondCell, default: []].append(contentsOf: arrSecondCell)
|
|
||||||
var keyComps = strFirstCell.map(\.description)
|
|
||||||
while !keyComps.isEmpty {
|
|
||||||
keyComps.removeLast()
|
|
||||||
charDefWildcardMap[keyComps.joined() + wildcard, default: []].append(contentsOf: arrSecondCell)
|
|
||||||
}
|
|
||||||
} else if loadingCharDefinitions, !strLine.contains("%chardef") {
|
} else if loadingCharDefinitions, !strLine.contains("%chardef") {
|
||||||
theMaxKeyLength = max(theMaxKeyLength, cells[0].count)
|
theMaxKeyLength = max(theMaxKeyLength, cells[0].count)
|
||||||
charDefMap[strFirstCell, default: []].append(strSecondCell)
|
charDefMap[strFirstCell, default: []].append(strSecondCell)
|
||||||
|
@ -156,8 +152,9 @@ public extension vChewingLM {
|
||||||
}
|
}
|
||||||
if nameCJK.isEmpty, strLine.contains("%cname ") { nameCJK = strSecondCell }
|
if nameCJK.isEmpty, strLine.contains("%cname ") { nameCJK = strSecondCell }
|
||||||
if nameShort.isEmpty, strLine.contains("%sname ") { nameShort = strSecondCell }
|
if nameShort.isEmpty, strLine.contains("%sname ") { nameShort = strSecondCell }
|
||||||
|
if nullCandidate.isEmpty, strLine.contains("%nullcandidate ") { nullCandidate = strSecondCell }
|
||||||
if selectionKeys.isEmpty, strLine.contains("%selkey ") {
|
if selectionKeys.isEmpty, strLine.contains("%selkey ") {
|
||||||
selectionKeys = cells[1].map(\.description).deduplicated
|
selectionKeys = cells[1].description
|
||||||
}
|
}
|
||||||
if endKeys.isEmpty, strLine.contains("%endkey ") {
|
if endKeys.isEmpty, strLine.contains("%endkey ") {
|
||||||
endKeys = cells[1].map(\.description).deduplicated
|
endKeys = cells[1].map(\.description).deduplicated
|
||||||
|
@ -182,7 +179,9 @@ public extension vChewingLM {
|
||||||
|
|
||||||
public mutating func clear() {
|
public mutating func clear() {
|
||||||
filePath = nil
|
filePath = nil
|
||||||
|
nullCandidate.removeAll()
|
||||||
keyNameMap.removeAll()
|
keyNameMap.removeAll()
|
||||||
|
quickDefMap.removeAll()
|
||||||
charDefMap.removeAll()
|
charDefMap.removeAll()
|
||||||
charDefWildcardMap.removeAll()
|
charDefWildcardMap.removeAll()
|
||||||
nameShort.removeAll()
|
nameShort.removeAll()
|
||||||
|
@ -199,6 +198,11 @@ public extension vChewingLM {
|
||||||
norm = 0
|
norm = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func quickSetsFor(key: String) -> String? {
|
||||||
|
guard let result = quickDefMap[key] as String? else { return nil }
|
||||||
|
return result.isEmpty ? nil : result
|
||||||
|
}
|
||||||
|
|
||||||
/// 根據給定的字根索引鍵,來獲取資料庫辭典內的對應結果。
|
/// 根據給定的字根索引鍵,來獲取資料庫辭典內的對應結果。
|
||||||
/// - parameters:
|
/// - parameters:
|
||||||
/// - key: 讀音索引鍵。
|
/// - key: 讀音索引鍵。
|
||||||
|
|
|
@ -39,4 +39,26 @@ final class LMCassetteTests: XCTestCase {
|
||||||
XCTAssertEqual(lmCassette.endKeys.count, 0)
|
XCTAssertEqual(lmCassette.endKeys.count, 0)
|
||||||
XCTAssertEqual(lmCassette.selectionKeys.count, 10)
|
XCTAssertEqual(lmCassette.selectionKeys.count, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testCassetteLoadArray30() throws {
|
||||||
|
let pathCINFile = testDataPath + "array30.cin"
|
||||||
|
var lmCassette = vChewingLM.LMCassette()
|
||||||
|
NSLog("LMCassette: Start loading CIN.")
|
||||||
|
lmCassette.open(pathCINFile)
|
||||||
|
NSLog("LMCassette: Finished loading CIN. Entries: \(lmCassette.count)")
|
||||||
|
XCTAssertFalse(lmCassette.quickDefMap.isEmpty)
|
||||||
|
print(lmCassette.quickSetsFor(key: ",.") ?? "")
|
||||||
|
XCTAssertEqual(lmCassette.keyNameMap.count, 41)
|
||||||
|
XCTAssertEqual(lmCassette.charDefMap.count, 29537)
|
||||||
|
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11973)
|
||||||
|
XCTAssertEqual(lmCassette.octagramMap.count, 0)
|
||||||
|
XCTAssertEqual(lmCassette.octagramDividedMap.count, 0)
|
||||||
|
XCTAssertEqual(lmCassette.nameShort, "AR30")
|
||||||
|
XCTAssertEqual(lmCassette.nameENG, "array30")
|
||||||
|
XCTAssertEqual(lmCassette.nameCJK, "行列30")
|
||||||
|
XCTAssertEqual(lmCassette.nameIntl, "Array 30:en;行列30:zh-Hans;行列30:zh-Hant")
|
||||||
|
XCTAssertEqual(lmCassette.maxKeyLength, 5)
|
||||||
|
XCTAssertEqual(lmCassette.endKeys.count, 10)
|
||||||
|
XCTAssertEqual(lmCassette.selectionKeys.count, 10)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue