📄 speller_impl.cpp
字号:
// This file is part of The New Aspell// Copyright (C) 2000-2001 by Kevin Atkinson under the GNU LGPL// license version 2.0 or 2.1. You should have received a copy of the// LGPL license along with this library if you did not you can find it// at http://www.gnu.org/.#include <stdlib.h>#include "aspeller.hpp"#include "clone_ptr-t.hpp"#include "config.hpp"#include "copy_ptr-t.hpp"#include "data.hpp"#include "data_id.hpp"#include "errors.hpp"#include "language.hpp"#include "speller_impl.hpp"#include "string_list.hpp"#include "suggest.hpp"#include "tokenizer.hpp"#include "convert.hpp"#include "stack_ptr.hpp"#include "iostream.hpp"namespace aspeller { // // data_access functions // const char * SpellerImpl::lang_name() const { return lang_->name(); } // // to lower // char * SpellerImpl::to_lower(char * str) { for (char * i = str; *i; ++i) *i = lang_->to_lower(*i); return str; } ////////////////////////////////////////////////////////////////////// // // Spell check methods // PosibErr<void> SpellerImpl::add_to_personal(MutableString word) { DataSetCollection::Iterator i = wls_->locate(personal_id); if (i == wls_->end()) return no_err; return static_cast<WritableWordSet *>(i->data_set)->add(word.str()); } PosibErr<void> SpellerImpl::add_to_session(MutableString word) { DataSetCollection::Iterator i = wls_->locate(session_id); if (i == wls_->end()) return no_err; return static_cast<WritableWordSet *>(i->data_set)->add(word.str()); } PosibErr<void> SpellerImpl::clear_session() { DataSetCollection::Iterator i = wls_->locate(session_id); if (i == wls_->end()) return no_err; return static_cast<WritableWordSet *>(i->data_set)->clear(); } PosibErr<void> SpellerImpl::store_replacement(MutableString mis, MutableString cor) { return store_replacement(mis.str(),cor.str(), true); } PosibErr<void> SpellerImpl::store_replacement(const String & mis, const String & cor, bool memory) { if (ignore_repl) return no_err; DataSetCollection::Iterator i = wls_->locate(personal_repl_id); if (i == wls_->end()) return no_err; String::size_type pos; Enumeration<StringEnumeration> sugels = intr_suggest_->suggest(mis.c_str()).elements(); const char * first_word = sugels.next(); const char * w1; const char * w2 = 0; if (pos = cor.find(' '), pos == String::npos ? (w1 =check_simple(cor).word) != 0 : ((w1 = check_simple((String)cor.substr(0,pos)).word) != 0 && (w2 = check_simple((String)cor.substr(pos+1)).word) != 0) ) { // cor is a correct spelling String cor_orignal_casing(w1); if (w2 != 0) { cor_orignal_casing += cor[pos]; cor_orignal_casing += w2; } if (first_word == 0 || cor != first_word) { static_cast<WritableReplacementSet *>(i->data_set) ->add(aspeller::to_lower(lang(), mis), cor_orignal_casing); } if (memory && prev_cor_repl_ == mis) store_replacement(prev_mis_repl_, cor, false); } else { // cor is not a correct spelling if (memory) { if (prev_cor_repl_ != mis) prev_mis_repl_ = mis; prev_cor_repl_ = cor; } } return no_err; } // // simple functions // PosibErr<const WordList *> SpellerImpl::suggest(MutableString word) { return &suggest_->suggest(word.str()); } SpellerImpl::SpecialId SpellerImpl::check_id(const DataSet::Id & wl) const { return wls_->locate(wl)->special_id; } bool SpellerImpl::use_to_check(const DataSet::Id & wl) const { return wls_->locate(wl)->use_to_check; } void SpellerImpl::use_to_check(const DataSet::Id & wl, bool v) { wls_->locate(wl)->use_to_check = v; } bool SpellerImpl::use_to_suggest(const DataSet::Id & wl) const { return wls_->locate(wl)->use_to_suggest; } void SpellerImpl::use_to_suggest(const DataSet::Id & wl, bool v) { wls_->locate(wl)->use_to_suggest = v; } bool SpellerImpl::save_on_saveall(const DataSet::Id & wl) const { return wls_->locate(wl)->save_on_saveall; } void SpellerImpl::save_on_saveall(const DataSet::Id & wl, bool v) { wls_->locate(wl)->save_on_saveall = v; } bool SpellerImpl::own(const DataSet::Id & wl) const { return wls_->locate(wl)->own; } void SpellerImpl::own(const DataSet::Id & wl, bool v) { wls_->locate(wl)->own = v; } BasicWordInfo SpellerImpl::check_simple (ParmString w) { const char * x = w; BasicWordInfo w0; while (*x != '\0' && (x-w) < static_cast<int>(ignore_count)) ++x; if (*x == '\0') return w.str(); DataSetCollection::ConstIterator i = wls_->begin(); DataSetCollection::ConstIterator end = wls_->end(); for (; i != end; ++i) { if (i->use_to_check && i->data_set->basic_type == DataSet::basic_word_set && (w0 = static_cast<const BasicWordSet *>(i->data_set) ->lookup(w,i->local_info.compare)) ) return w0; } return 0; }; PosibErr<bool> SpellerImpl::check(char * word, char * word_end, /* it WILL modify word */ unsigned int run_together_limit, CompoundInfo::Position pos, SingleWordInfo * words) { assert(run_together_limit <= 8); // otherwise it will go above the // bounds of the word array words[0].clear(); BasicWordInfo w = check_simple(word); if (w) { if (pos == CompoundInfo::Orig) { words[0] = w.word; words[1].clear(); return true; } bool check_if_valid = !(unconditional_run_together_ && strlen(word) >= run_together_min_); if (!check_if_valid || w.compound.compatible(pos)) { words[0] = w.word; words[1].clear(); return true; } else { return false; } } if (run_together_limit <= 1 || (!unconditional_run_together_ && !run_together_specified_)) return false; for (char * i = word + run_together_start_len_; i <= word_end - run_together_start_len_; ++i) { char t = *i; *i = '\0'; BasicWordInfo s = check_simple(word); *i = t; if (!s) continue; CompoundInfo c = s.compound; CompoundInfo::Position end_pos = new_position(pos, CompoundInfo::End); char m = run_together_middle_[c.mid_char()]; // // FIXME: Deal with casing of the middle character properly // if case insentate than it can be anything // otherwise it should match the case of previous // letter // bool check_if_valid = !(unconditional_run_together_ && i - word >= static_cast<int>(run_together_min_)); if (check_if_valid) { CompoundInfo::Position beg_pos = new_position(pos, CompoundInfo::Beg); if (!c.compatible(beg_pos)) continue; if (c.mid_required() && *i != m) continue; } words[0].set(s.word, *i == m ? m : '\0'); words[1].clear(); if ((!check_if_valid || !c.mid_required()) // if check then !s.mid_required() && check(i, word_end, run_together_limit - 1, end_pos, words + 1)) return true; if ((check_if_valid ? *i == m : strchr(run_together_middle_, *i) != 0) && word_end - (i + 1) >= static_cast<int>(run_together_min_)) { if (check(i+1, word_end, run_together_limit - 1, end_pos, words + 1)) return true; else // already checked word (i+1) so no need to check it again ++i; } } words[0].clear(); return false; } ////////////////////////////////////////////////////////////////////// // // Word list managment methods // PosibErr<void> SpellerImpl::save_all_word_lists() { DataSetCollection::Iterator i = wls_->begin(); DataSetCollection::Iterator end = wls_->end(); WritableDataSet * wl; for (; i != end; ++i) { if (i->save_on_saveall && (wl = dynamic_cast<WritableDataSet *>(i->data_set))) RET_ON_ERR(wl->synchronize()); } return no_err; } int SpellerImpl::num_wordlists() const { return wls_->wordlists_.size(); } SpellerImpl::WordLists SpellerImpl::wordlists() const { return WordLists(MakeVirEnumeration<DataSetCollection::Parms> (wls_->begin(), DataSetCollection::Parms(wls_->end()))); } bool SpellerImpl::have(const DataSet::Id &to_find) const { return wls_->locate(to_find) != wls_->end(); } LocalWordSet SpellerImpl::locate(const DataSet::Id &to_find) { DataSetCollection::Iterator i = wls_->locate(to_find); LocalWordSet ws; if (i == wls_->end()) { return LocalWordSet(); } else { return LocalWordSet(static_cast<LoadableDataSet *>(i->data_set), i->local_info); } return ws; } bool SpellerImpl::have(SpellerImpl::SpecialId to_find) const { return wls_->locate(to_find) != wls_->end(); } PosibErr<const WordList *> SpellerImpl::personal_word_list() const { return static_cast<const WordList *> (static_cast<const BasicWordSet *> (wls_->locate(personal_id)->data_set)); } PosibErr<const WordList *> SpellerImpl::session_word_list() const { return static_cast<const WordList *> (static_cast<const BasicWordSet *> (wls_->locate(session_id)->data_set)); } PosibErr<const WordList *> SpellerImpl::main_word_list() const { return static_cast<const WordList *> (static_cast<const BasicWordSet *> (wls_->locate(main_id)->data_set)); } bool SpellerImpl::attach(DataSet * w, const LocalWordSetInfo * li) { DataSetCollection::Iterator i = wls_->locate(w); if (i != wls_->end()) { return false; } else { if (!lang_) { lang_.reset(new Language(*w->lang())); config_->replace("lang", lang_name()); config_->replace("language-tag", lang_name()); } w->attach(*lang_); DataSetCollection::Item wc(w); wc.set_sensible_defaults(); if (li == 0) { wc.local_info.set(lang_, config_); } else { wc.local_info = *li; wc.local_info.set_language(lang_); } wls_->wordlists_.push_back(wc); return true; } } bool SpellerImpl::steal(DataSet * w, const LocalWordSetInfo * li) { bool ret = attach(w,li); own(w, true); return ret; } bool SpellerImpl::detach(const DataSet::Id &w) { DataSetCollection::Iterator to_del = wls_->locate(w); if (to_del == wls_->wordlists_.end()) return false; to_del->data_set->detach(); wls_->wordlists_.erase(to_del); return true; } bool SpellerImpl::destroy(const DataSet::Id & w) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -