Adds an example for a symbol table in tree structure.

This commit is contained in:
zonble 2022-12-17 14:03:10 +08:00
parent ddbe363134
commit 8de659f50b
3 changed files with 71 additions and 15 deletions

View File

@ -575,6 +575,17 @@ extension McBopomofoInputMethodController: CandidateControllerDelegate {
func candidateController(_ controller: CandidateController, didSelectCandidateAtIndex index: UInt) {
let client = currentCandidateClient
if let state = state as? InputState.SymbolTable,
let node = state.node.children?[Int(index)] {
if let children = node.children, !children.isEmpty {
self.handle(state: .SymbolTable(node: node, useVerticalMode: state.useVerticalMode), client: currentCandidateClient)
} else {
self.handle(state: .Committing(poppedText: node.title), client: client)
self.handle(state: .Empty(), client: client)
}
return
}
if let state = state as? InputState.ChoosingCandidate {
let selectedValue = state.candidates[Int(index)]
keyHandler.fixNode(value: selectedValue)
@ -596,7 +607,10 @@ extension McBopomofoInputMethodController: CandidateControllerDelegate {
} else {
handle(state: inputting, client: client)
}
} else if let state = state as? InputState.AssociatedPhrases {
return
}
if let state = state as? InputState.AssociatedPhrases {
let selectedValue = state.candidates[Int(index)]
handle(state: .Committing(poppedText: selectedValue), client: currentCandidateClient)
if Preferences.associatedPhrasesEnabled,

View File

@ -317,4 +317,53 @@ class InputState: NSObject {
"<InputState.AssociatedPhrases, candidates:\(candidates), useVerticalMode:\(useVerticalMode)>"
}
}
@objc (InputStateSymbolTable)
class SymbolTable: ChoosingCandidate {
@objc var node: SymbolNode
@objc init(node: SymbolNode, useVerticalMode: Bool) {
self.node = node
let candidates = node.children?.map { $0.title } ?? [String]()
super.init(composingBuffer: "", cursorIndex: 0, candidates: candidates, useVerticalMode: useVerticalMode)
}
override var description: String {
"<InputState.SymbolTable, candidates:\(candidates), useVerticalMode:\(useVerticalMode), composingBuffer:\(composingBuffer), cursorIndex:\(cursorIndex)>"
}
}
}
@objc class SymbolNode: NSObject {
@objc var title: String
@objc var children: [SymbolNode]?
@objc init(_ title: String, _ children: [SymbolNode]? = nil) {
self.title = title
self.children = children
super.init()
}
@objc init(_ title: String, symbols: String) {
self.title = title
self.children = Array(symbols).map { SymbolNode(String($0), nil) }
super.init()
}
@objc static let root: SymbolNode = SymbolNode("/", [
SymbolNode(""),
SymbolNode(""),
SymbolNode("常用符號", symbols:",、。.?!;:‧‥﹐﹒˙·‘’“”〝〞‵′〃~$%@&#*"),
SymbolNode("左右括號", symbols:"()「」〔〕{}〈〉『』《》【】﹙﹚﹝﹞﹛﹜"),
SymbolNode("上下括號", symbols:"︵︶﹁﹂︹︺︷︸︿﹀﹃﹄︽︾︻︼"),
SymbolNode("希臘字母", symbols:"αβγδεζηθικλμνξοπρστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ"),
SymbolNode("數學符號", symbols:"+-×÷=≠≒∞±√<>﹤﹥≦≧∩∪ˇ⊥∠∟⊿㏒㏑∫∮∵∴╳﹢"),
SymbolNode("特殊圖形", symbols:"↑↓←→↖↗↙↘㊣◎○●⊕⊙○●△▲☆★◇◆□■▽▼§¥〒¢£※♀♂"),
SymbolNode("Unicode", symbols:"♨☀☁☂☃♠♥♣♦♩♪♫♬☺☻"),
SymbolNode("單線框", symbols:"├─┼┴┬┤┌┐╞═╪╡│▕└┘╭╮╰╯"),
SymbolNode("雙線框", symbols:"╔╦╗╠═╬╣╓╥╖╒╤╕║╚╩╝╟╫╢╙╨╜╞╪╡╘╧╛"),
SymbolNode("填色方塊", symbols:"_ˍ▁▂▃▄▅▆▇█▏▎▍▌▋▊▉◢◣◥◤"),
SymbolNode("線段", symbols:"﹣﹦≡|∣∥–︱—︳╴¯ ̄﹉﹊﹍﹎﹋﹌﹏︴∕﹨╱╲/\"),
])
}

View File

@ -489,20 +489,13 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot
// MARK: Punctuation list
if ((char)charCode == '`') {
if (_languageModel->hasUnigramsForKey("_punctuation_list")) {
if (_bpmfReadingBuffer->isEmpty()) {
_builder->insertReadingAtCursor("_punctuation_list");
NSString *poppedText = [self _popOverflowComposingTextAndWalk];
InputStateInputting *inputting = (InputStateInputting *)[self buildInputtingState];
inputting.poppedText = poppedText;
stateCallback(inputting);
InputStateChoosingCandidate *choosingCandidate = [self _buildCandidateState:inputting useVerticalMode:input.useVerticalMode];
stateCallback(choosingCandidate);
} else { // If there is still unfinished bpmf reading, ignore the punctuation
errorCallback();
}
return YES;
}
InputStateEmpty *empty = [[InputStateEmpty alloc] init];
stateCallback(empty);
SymbolNode *root = [SymbolNode root];
InputStateSymbolTable *symbolState = [[InputStateSymbolTable alloc] initWithNode:root useVerticalMode:input.useVerticalMode];
stateCallback(symbolState);
return YES;
}
// MARK: Punctuation