keyHandler // Dealing with Namespace Pollusion.
This commit is contained in:
parent
e8a6131864
commit
f2eeccfad9
|
@ -17,28 +17,23 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "Mandarin.h"
|
|
||||||
#import "Gramambular.h"
|
#import "Gramambular.h"
|
||||||
#import "LMInstantiator.h"
|
|
||||||
#import "UserOverrideModel.h"
|
|
||||||
#import "mgrLangModel_Privates.h"
|
|
||||||
#import "KeyHandler.h"
|
#import "KeyHandler.h"
|
||||||
|
#import "LMInstantiator.h"
|
||||||
|
#import "Mandarin.h"
|
||||||
|
#import "mgrLangModel_Privates.h"
|
||||||
|
#import "UserOverrideModel.h"
|
||||||
#import "vChewing-Swift.h"
|
#import "vChewing-Swift.h"
|
||||||
#import <string>
|
#import <string>
|
||||||
|
|
||||||
// C++ namespace usages
|
|
||||||
using namespace std;
|
|
||||||
using namespace Taiyan::Mandarin;
|
|
||||||
using namespace Taiyan::Gramambular;
|
|
||||||
using namespace vChewing;
|
|
||||||
|
|
||||||
InputMode imeModeCHT = @"org.atelierInmu.inputmethod.vChewing.IMECHT";
|
InputMode imeModeCHT = @"org.atelierInmu.inputmethod.vChewing.IMECHT";
|
||||||
InputMode imeModeCHS = @"org.atelierInmu.inputmethod.vChewing.IMECHS";
|
InputMode imeModeCHS = @"org.atelierInmu.inputmethod.vChewing.IMECHS";
|
||||||
InputMode imeModeNULL = @"org.atelierInmu.inputmethod.vChewing.IMENULL";
|
InputMode imeModeNULL = @"org.atelierInmu.inputmethod.vChewing.IMENULL";
|
||||||
|
|
||||||
static const double kEpsilon = 0.000001;
|
static const double kEpsilon = 0.000001;
|
||||||
|
|
||||||
static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon) {
|
static double FindHighestScore(const std::vector<Taiyan::Gramambular::NodeAnchor> &nodes, double epsilon) {
|
||||||
double highestScore = 0.0;
|
double highestScore = 0.0;
|
||||||
for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
||||||
double score = ni->node->highestUnigramScore();
|
double score = ni->node->highestUnigramScore();
|
||||||
|
@ -49,16 +44,15 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
|
||||||
return highestScore + epsilon;
|
return highestScore + epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort helper
|
class NodeAnchorDescendingSorter {
|
||||||
class NodeAnchorDescendingSorter
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
bool operator()(const NodeAnchor &a, const NodeAnchor &b) const {
|
bool operator()(const Taiyan::Gramambular::NodeAnchor &a, const Taiyan::Gramambular::NodeAnchor &b) const
|
||||||
|
{
|
||||||
return a.node->key().length() > b.node->key().length();
|
return a.node->key().length() > b.node->key().length();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// if DEBUG is defined, a DOT file (GraphViz format) will be written to the
|
;// if DEBUG is defined, a DOT file (GraphViz format) will be written to the
|
||||||
// specified path every time the grid is walked
|
// specified path every time the grid is walked
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
@ -96,8 +90,8 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
- (void)setInputMode:(NSString *)value
|
- (void)setInputMode:(NSString *)value
|
||||||
{
|
{
|
||||||
NSString *newInputMode;
|
NSString *newInputMode;
|
||||||
LMInstantiator *newLanguageModel;
|
vChewing::LMInstantiator *newLanguageModel;
|
||||||
UserOverrideModel *newUserOverrideModel;
|
vChewing::UserOverrideModel *newUserOverrideModel;
|
||||||
|
|
||||||
if ([value isKindOfClass:[NSString class]] && [value isEqual:imeModeCHS]) {
|
if ([value isKindOfClass:[NSString class]] && [value isEqual:imeModeCHS]) {
|
||||||
newInputMode = imeModeCHS;
|
newInputMode = imeModeCHS;
|
||||||
|
@ -120,7 +114,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
if (_builder) {
|
if (_builder) {
|
||||||
delete _builder;
|
delete _builder;
|
||||||
_builder = new BlockReadingBuilder(_languageModel);
|
_builder = new Taiyan::Gramambular::BlockReadingBuilder(_languageModel);
|
||||||
_builder->setJoinSeparator("-");
|
_builder->setJoinSeparator("-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +140,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_bpmfReadingBuffer = new BopomofoReadingBuffer(BopomofoKeyboardLayout::StandardLayout());
|
_bpmfReadingBuffer = new Taiyan::Mandarin::BopomofoReadingBuffer(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
|
|
||||||
// create the lattice builder
|
// create the lattice builder
|
||||||
_languageModel = [mgrLangModel lmCHT];
|
_languageModel = [mgrLangModel lmCHT];
|
||||||
|
@ -154,7 +148,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
_languageModel->setCNSEnabled(Preferences.cns11643Enabled);
|
_languageModel->setCNSEnabled(Preferences.cns11643Enabled);
|
||||||
_userOverrideModel = [mgrLangModel userOverrideModelCHT];
|
_userOverrideModel = [mgrLangModel userOverrideModelCHT];
|
||||||
|
|
||||||
_builder = new BlockReadingBuilder(_languageModel);
|
_builder = new Taiyan::Gramambular::BlockReadingBuilder(_languageModel);
|
||||||
|
|
||||||
// each Mandarin syllable is separated by a hyphen
|
// each Mandarin syllable is separated by a hyphen
|
||||||
_builder->setJoinSeparator("-");
|
_builder->setJoinSeparator("-");
|
||||||
|
@ -168,31 +162,31 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
NSInteger layout = Preferences.keyboardLayout;
|
NSInteger layout = Preferences.keyboardLayout;
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
case KeyboardLayoutStandard:
|
case KeyboardLayoutStandard:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::StandardLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutEten:
|
case KeyboardLayoutEten:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::ETenLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::ETenLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutHsu:
|
case KeyboardLayoutHsu:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::HsuLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::HsuLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutEten26:
|
case KeyboardLayoutEten26:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::ETen26Layout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::ETen26Layout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutIBM:
|
case KeyboardLayoutIBM:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::IBMLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::IBMLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutMiTAC:
|
case KeyboardLayoutMiTAC:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::MiTACLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::MiTACLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutFakeSeigyou:
|
case KeyboardLayoutFakeSeigyou:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::FakeSeigyouLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::FakeSeigyouLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutHanyuPinyin:
|
case KeyboardLayoutHanyuPinyin:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::HanyuPinyinLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::HanyuPinyinLayout());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::StandardLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
Preferences.keyboardLayout = KeyboardLayoutStandard;
|
Preferences.keyboardLayout = KeyboardLayoutStandard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,8 +194,8 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
- (void)fixNodeWithValue:(NSString *)value
|
- (void)fixNodeWithValue:(NSString *)value
|
||||||
{
|
{
|
||||||
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
||||||
string stringValue = [value UTF8String];
|
std::string stringValue(value.UTF8String);
|
||||||
NodeAnchor selectedNode = _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue);
|
Taiyan::Gramambular::NodeAnchor selectedNode = _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue);
|
||||||
if (!Preferences.useSCPCTypingMode) { // 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
if (!Preferences.useSCPCTypingMode) { // 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
||||||
// If the length of the readings and the characters do not match,
|
// If the length of the readings and the characters do not match,
|
||||||
// it often means it is a special symbol and it should not be stored
|
// it often means it is a special symbol and it should not be stored
|
||||||
|
@ -234,10 +228,10 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
_walkedNodes.clear();
|
_walkedNodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (string)_currentLayout
|
- (std::string)_currentLayout
|
||||||
{
|
{
|
||||||
NSString *keyboardLayoutName = Preferences.keyboardLayoutName;
|
NSString *keyboardLayoutName = Preferences.keyboardLayoutName;
|
||||||
string layout = string(keyboardLayoutName.UTF8String) + string("_");
|
std::string layout = std::string(keyboardLayoutName.UTF8String) + std::string("_");
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +342,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
composeReading |= (!_bpmfReadingBuffer->isEmpty() && ([input isSpace] || [input isEnterCharCode] || [input isEnter]));
|
composeReading |= (!_bpmfReadingBuffer->isEmpty() && ([input isSpace] || [input isEnterCharCode] || [input isEnter]));
|
||||||
if (composeReading) {
|
if (composeReading) {
|
||||||
// combine the reading
|
// combine the reading
|
||||||
string reading = _bpmfReadingBuffer->syllable().composedString();
|
std::string reading = _bpmfReadingBuffer->syllable().composedString();
|
||||||
|
|
||||||
// see if we have a unigram for this
|
// see if we have a unigram for this
|
||||||
if (!_languageModel->hasUnigramsForKey(reading)) {
|
if (!_languageModel->hasUnigramsForKey(reading)) {
|
||||||
|
@ -365,12 +359,12 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
||||||
|
|
||||||
// get user override model suggestion
|
// get user override model suggestion
|
||||||
string overrideValue = (Preferences.useSCPCTypingMode) ? "" :
|
std::string overrideValue = (Preferences.useSCPCTypingMode) ? "" :
|
||||||
_userOverrideModel->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
|
_userOverrideModel->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
|
||||||
|
|
||||||
if (!overrideValue.empty()) {
|
if (!overrideValue.empty()) {
|
||||||
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
||||||
vector<NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
std::vector<Taiyan::Gramambular::NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
||||||
double highestScore = FindHighestScore(nodes, kEpsilon);
|
double highestScore = FindHighestScore(nodes, kEpsilon);
|
||||||
_builder->grid().overrideNodeScoreForSelectedCandidate(cursorIndex, overrideValue, static_cast<float>(highestScore));
|
_builder->grid().overrideNodeScoreForSelectedCandidate(cursorIndex, overrideValue, static_cast<float>(highestScore));
|
||||||
}
|
}
|
||||||
|
@ -521,7 +515,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
InputStateSymbolTable *symbolState = [[InputStateSymbolTable alloc] initWithNode:root useVerticalMode:input.useVerticalMode];
|
InputStateSymbolTable *symbolState = [[InputStateSymbolTable alloc] initWithNode:root useVerticalMode:input.useVerticalMode];
|
||||||
stateCallback(symbolState);
|
stateCallback(symbolState);
|
||||||
return YES;
|
return YES;
|
||||||
// if (_languageModel->hasUnigramsForKey(string("_punctuation_list"))) {
|
// if (_languageModel->hasUnigramsForKey("_punctuation_list"))) {
|
||||||
// if (_bpmfReadingBuffer->isEmpty()) {
|
// if (_bpmfReadingBuffer->isEmpty()) {
|
||||||
// _builder->insertReadingAtCursor(string("_punctuation_list"));
|
// _builder->insertReadingAtCursor(string("_punctuation_list"));
|
||||||
// NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
// NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
||||||
|
@ -540,22 +534,22 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// MARK: Punctuation
|
// MARK: Punctuation
|
||||||
// if nothing is matched, see if it's a punctuation key for current layout.
|
// if nothing is matched, see if it's a punctuation key for current layout.
|
||||||
|
|
||||||
string punctuationNamePrefix;
|
std::string punctuationNamePrefix;
|
||||||
if ([input isControlHold]) {
|
if ([input isControlHold]) {
|
||||||
punctuationNamePrefix = string("_ctrl_punctuation_");
|
punctuationNamePrefix = std::string("_ctrl_punctuation_");
|
||||||
} else if (Preferences.halfWidthPunctuationEnabled) {
|
} else if (Preferences.halfWidthPunctuationEnabled) {
|
||||||
punctuationNamePrefix = string("_half_punctuation_");
|
punctuationNamePrefix = std::string("_half_punctuation_");
|
||||||
} else {
|
} else {
|
||||||
punctuationNamePrefix = string("_punctuation_");
|
punctuationNamePrefix = std::string("_punctuation_");
|
||||||
}
|
}
|
||||||
string layout = [self _currentLayout];
|
std::string layout = [self _currentLayout];
|
||||||
string customPunctuation = punctuationNamePrefix + layout + string(1, (char) charCode);
|
std::string customPunctuation = punctuationNamePrefix + layout + std::string(1, (char) charCode);
|
||||||
if ([self _handlePunctuation:customPunctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
if ([self _handlePunctuation:customPunctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nothing is matched, see if it's a punctuation key.
|
// if nothing is matched, see if it's a punctuation key.
|
||||||
string punctuation = punctuationNamePrefix + string(1, (char) charCode);
|
std::string punctuation = punctuationNamePrefix + std::string(1, (char) charCode);
|
||||||
if ([self _handlePunctuation:punctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
if ([self _handlePunctuation:punctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +557,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// Lukhnos 這裡的處理反而會使得 Apple 倚天注音動態鍵盤佈局「敲不了半形大寫英文」的缺點曝露無疑,所以注釋掉。
|
// Lukhnos 這裡的處理反而會使得 Apple 倚天注音動態鍵盤佈局「敲不了半形大寫英文」的缺點曝露無疑,所以注釋掉。
|
||||||
// 至於他試圖用這種處理來解決的上游 UPR293 的問題,其實針對詞庫檔案的排序做點手腳就可以解決。威注音本來也就是這麼做的。
|
// 至於他試圖用這種處理來解決的上游 UPR293 的問題,其實針對詞庫檔案的排序做點手腳就可以解決。威注音本來也就是這麼做的。
|
||||||
if (/*[state isKindOfClass:[InputStateNotEmpty class]] && */(char) charCode >= 'A' && (char) charCode <= 'Z') {
|
if (/*[state isKindOfClass:[InputStateNotEmpty class]] && */(char) charCode >= 'A' && (char) charCode <= 'Z') {
|
||||||
string letter = string("_letter_") + string(1, (char) charCode);
|
std::string letter = std::string("_letter_") + std::string(1, (char) charCode);
|
||||||
if ([self _handlePunctuation:letter state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
if ([self _handlePunctuation:letter state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -847,7 +841,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_handlePunctuation:(string)customPunctuation state:(InputState *)state usingVerticalMode:(BOOL)useVerticalMode stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback
|
- (BOOL)_handlePunctuation:(std::string)customPunctuation state:(InputState *)state usingVerticalMode:(BOOL)useVerticalMode stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback
|
||||||
{
|
{
|
||||||
if (!_languageModel->hasUnigramsForKey(customPunctuation)) {
|
if (!_languageModel->hasUnigramsForKey(customPunctuation)) {
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -1152,23 +1146,23 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Preferences.useSCPCTypingMode) {
|
if (Preferences.useSCPCTypingMode) {
|
||||||
string layout = [self _currentLayout];
|
std::string layout = [self _currentLayout];
|
||||||
string punctuationNamePrefix;
|
std::string punctuationNamePrefix;
|
||||||
if ([input isControlHold]) {
|
if ([input isControlHold]) {
|
||||||
punctuationNamePrefix = string("_ctrl_punctuation_");
|
punctuationNamePrefix = std::string("_ctrl_punctuation_");
|
||||||
} else if (Preferences.halfWidthPunctuationEnabled) {
|
} else if (Preferences.halfWidthPunctuationEnabled) {
|
||||||
punctuationNamePrefix = string("_half_punctuation_");
|
punctuationNamePrefix = std::string("_half_punctuation_");
|
||||||
} else {
|
} else {
|
||||||
punctuationNamePrefix = string("_punctuation_");
|
punctuationNamePrefix = std::string("_punctuation_");
|
||||||
}
|
}
|
||||||
string customPunctuation = punctuationNamePrefix + layout + string(1, (char) charCode);
|
std::string customPunctuation = punctuationNamePrefix + layout + std::string(1, (char) charCode);
|
||||||
string punctuation = punctuationNamePrefix + string(1, (char) charCode);
|
std::string punctuation = punctuationNamePrefix + std::string(1, (char) charCode);
|
||||||
|
|
||||||
BOOL shouldAutoSelectCandidate = _bpmfReadingBuffer->isValidKey((char) charCode) || _languageModel->hasUnigramsForKey(customPunctuation) ||
|
BOOL shouldAutoSelectCandidate = _bpmfReadingBuffer->isValidKey((char) charCode) || _languageModel->hasUnigramsForKey(customPunctuation) ||
|
||||||
_languageModel->hasUnigramsForKey(punctuation);
|
_languageModel->hasUnigramsForKey(punctuation);
|
||||||
|
|
||||||
if (!shouldAutoSelectCandidate && (char) charCode >= 'A' && (char) charCode <= 'Z') {
|
if (!shouldAutoSelectCandidate && (char) charCode >= 'A' && (char) charCode <= 'Z') {
|
||||||
string letter = string("_letter_") + string(1, (char) charCode);
|
std::string letter = std::string("_letter_") + std::string(1, (char) charCode);
|
||||||
if (_languageModel->hasUnigramsForKey(letter)) {
|
if (_languageModel->hasUnigramsForKey(letter)) {
|
||||||
shouldAutoSelectCandidate = YES;
|
shouldAutoSelectCandidate = YES;
|
||||||
}
|
}
|
||||||
|
@ -1208,9 +1202,9 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// we must do some Unicode codepoint counting to find the actual cursor location for the client
|
// we must do some Unicode codepoint counting to find the actual cursor location for the client
|
||||||
// i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars
|
// i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars
|
||||||
// locations
|
// locations
|
||||||
for (vector<NodeAnchor>::iterator wi = _walkedNodes.begin(), we = _walkedNodes.end(); wi != we; ++wi) {
|
for (std::vector<Taiyan::Gramambular::NodeAnchor>::iterator wi = _walkedNodes.begin(), we = _walkedNodes.end(); wi != we; ++wi) {
|
||||||
if ((*wi).node) {
|
if ((*wi).node) {
|
||||||
string nodeStr = (*wi).node->currentKeyValue().value;
|
std::string nodeStr = (*wi).node->currentKeyValue().value;
|
||||||
NSString *valueString = [NSString stringWithUTF8String:nodeStr.c_str()];
|
NSString *valueString = [NSString stringWithUTF8String:nodeStr.c_str()];
|
||||||
[composingBuffer appendString:valueString];
|
[composingBuffer appendString:valueString];
|
||||||
|
|
||||||
|
@ -1276,7 +1270,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
// retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
||||||
// of the best possible Mandarain characters given the input syllables,
|
// of the best possible Mandarain characters given the input syllables,
|
||||||
// using the Viterbi algorithm implemented in the Gramambular library
|
// using the Viterbi algorithm implemented in the Gramambular library
|
||||||
Walker walker(&_builder->grid());
|
Taiyan::Gramambular::Walker walker(&_builder->grid());
|
||||||
|
|
||||||
// the reverse walk traces the trellis from the end
|
// the reverse walk traces the trellis from the end
|
||||||
_walkedNodes = walker.reverseWalk(_builder->grid().width());
|
_walkedNodes = walker.reverseWalk(_builder->grid().width());
|
||||||
|
@ -1286,7 +1280,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
// if DEBUG is defined, a GraphViz file is written to kGraphVizOutputfile
|
// if DEBUG is defined, a GraphViz file is written to kGraphVizOutputfile
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
string dotDump = _builder->grid().dumpDOT();
|
std::string dotDump = _builder->grid().dumpDOT();
|
||||||
NSString *dotStr = [NSString stringWithUTF8String:dotDump.c_str()];
|
NSString *dotStr = [NSString stringWithUTF8String:dotDump.c_str()];
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
|
|
||||||
|
@ -1309,7 +1303,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
if (_builder->grid().width() > (size_t) composingBufferSize) {
|
if (_builder->grid().width() > (size_t) composingBufferSize) {
|
||||||
if (_walkedNodes.size() > 0) {
|
if (_walkedNodes.size() > 0) {
|
||||||
NodeAnchor &anchor = _walkedNodes[0];
|
Taiyan::Gramambular::NodeAnchor &anchor = _walkedNodes[0];
|
||||||
poppedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()];
|
poppedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()];
|
||||||
_builder->removeHeadReadings(anchor.spanningLength);
|
_builder->removeHeadReadings(anchor.spanningLength);
|
||||||
}
|
}
|
||||||
|
@ -1324,15 +1318,15 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
NSMutableArray *candidatesArray = [[NSMutableArray alloc] init];
|
NSMutableArray *candidatesArray = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
||||||
vector<NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
std::vector<Taiyan::Gramambular::NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
||||||
|
|
||||||
// sort the nodes, so that longer nodes (representing longer phrases) are placed at the top of the candidate list
|
// sort the nodes, so that longer nodes (representing longer phrases) are placed at the top of the candidate list
|
||||||
stable_sort(nodes.begin(), nodes.end(), NodeAnchorDescendingSorter());
|
stable_sort(nodes.begin(), nodes.end(), NodeAnchorDescendingSorter());
|
||||||
|
|
||||||
// then use the C++ trick to retrieve the candidates for each node at/crossing the cursor
|
// then use the C++ trick to retrieve the candidates for each node at/crossing the cursor
|
||||||
for (vector<NodeAnchor>::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
for (std::vector<Taiyan::Gramambular::NodeAnchor>::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
||||||
const vector<KeyValuePair> &candidates = (*ni).node->candidates();
|
const std::vector<Taiyan::Gramambular::KeyValuePair> &candidates = (*ni).node->candidates();
|
||||||
for (vector<KeyValuePair>::const_iterator ci = candidates.begin(), ce = candidates.end(); ci != ce; ++ci) {
|
for (std::vector<Taiyan::Gramambular::KeyValuePair>::const_iterator ci = candidates.begin(), ce = candidates.end(); ci != ce; ++ci) {
|
||||||
[candidatesArray addObject:[NSString stringWithUTF8String:(*ci).value.c_str()]];
|
[candidatesArray addObject:[NSString stringWithUTF8String:(*ci).value.c_str()]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1361,8 +1355,8 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
- (NSArray *)_currentReadings
|
- (NSArray *)_currentReadings
|
||||||
{
|
{
|
||||||
NSMutableArray *readingsArray = [[NSMutableArray alloc] init];
|
NSMutableArray *readingsArray = [[NSMutableArray alloc] init];
|
||||||
vector<std::string> v = _builder->readings();
|
std::vector<std::string> v = _builder->readings();
|
||||||
for (vector<std::string>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
|
for (std::vector<std::string>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
|
||||||
[readingsArray addObject:[NSString stringWithUTF8String:it_i->c_str()]];
|
[readingsArray addObject:[NSString stringWithUTF8String:it_i->c_str()]];
|
||||||
}
|
}
|
||||||
return readingsArray;
|
return readingsArray;
|
||||||
|
@ -1370,9 +1364,9 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
- (nullable InputState *)buildAssociatePhraseStateWithKey:(NSString *)key useVerticalMode:(BOOL)useVerticalMode
|
- (nullable InputState *)buildAssociatePhraseStateWithKey:(NSString *)key useVerticalMode:(BOOL)useVerticalMode
|
||||||
{
|
{
|
||||||
string cppKey = string(key.UTF8String);
|
std::string cppKey = std::string(key.UTF8String);
|
||||||
if (_languageModel->hasAssociatedPhrasesForKey(cppKey)) {
|
if (_languageModel->hasAssociatedPhrasesForKey(cppKey)) {
|
||||||
vector<string> phrases = _languageModel->associatedPhrasesForKey(cppKey);
|
std::vector<std::string> phrases = _languageModel->associatedPhrasesForKey(cppKey);
|
||||||
NSMutableArray <NSString *> *array = [NSMutableArray array];
|
NSMutableArray <NSString *> *array = [NSMutableArray array];
|
||||||
for (auto phrase: phrases) {
|
for (auto phrase: phrases) {
|
||||||
NSString *item = [[NSString alloc] initWithUTF8String:phrase.c_str()];
|
NSString *item = [[NSString alloc] initWithUTF8String:phrase.c_str()];
|
||||||
|
|
Loading…
Reference in New Issue