1 //
2 // Copyright RIME Developers
3 // Distributed under the BSD License
4 //
5 // 2012-04-22 GONG Chen <chen.sst@gmail.com>
6 //
7 #include <algorithm>
8 #include <boost/range/adaptor/reversed.hpp>
9 #include <rime/config.h>
10 #include <rime/schema.h>
11 #include <rime/ticket.h>
12 #include <rime/gear/grammar.h>
13 #include <rime/gear/translator_commons.h>
14
15 namespace rime {
16
17 // Patterns
18
Load(an<ConfigList> patterns)19 bool Patterns::Load(an<ConfigList> patterns) {
20 clear();
21 if (!patterns)
22 return false;
23 for (auto it = patterns->begin(); it != patterns->end(); ++it) {
24 if (auto value = As<ConfigValue>(*it)) {
25 push_back(boost::regex(value->str()));
26 }
27 }
28 return true;
29 }
30
31 // Spans
32
AddVertex(size_t vertex)33 void Spans::AddVertex(size_t vertex) {
34 if (vertices_.empty() || vertices_.back() < vertex) {
35 vertices_.push_back(vertex);
36 return;
37 }
38 auto lb = std::lower_bound(vertices_.begin(), vertices_.end(), vertex);
39 if (*lb != vertex) {
40 vertices_.insert(lb, vertex);
41 }
42 }
43
AddSpan(size_t start,size_t end)44 void Spans::AddSpan(size_t start, size_t end) {
45 AddVertex(start);
46 AddVertex(end);
47 }
48
AddSpans(const Spans & spans)49 void Spans::AddSpans(const Spans& spans) {
50 for (auto vertex : spans.vertices_) {
51 AddVertex(vertex);
52 }
53 }
54
Clear()55 void Spans::Clear() {
56 vertices_.clear();
57 }
58
PreviousStop(size_t caret_pos) const59 size_t Spans::PreviousStop(size_t caret_pos) const {
60 for (auto x : boost::adaptors::reverse(vertices_)) {
61 if (x < caret_pos)
62 return x;
63 }
64 return caret_pos;
65 }
66
NextStop(size_t caret_pos) const67 size_t Spans::NextStop(size_t caret_pos) const {
68 for (auto x : vertices_) {
69 if (x > caret_pos)
70 return x;
71 }
72 return caret_pos;
73 }
74
Count(size_t start_pos,size_t end_pos) const75 size_t Spans::Count(size_t start_pos, size_t end_pos) const {
76 size_t count = 0;
77 for (auto v : vertices_) {
78 if (v <= start_pos) continue;
79 else if (v > end_pos) break;
80 else ++count;
81 }
82 return count;
83 }
84
HasVertex(size_t vertex) const85 bool Spans::HasVertex(size_t vertex) const {
86 return std::binary_search(vertices_.begin(), vertices_.end(), vertex);
87 }
88
89 // Sentence
90
Extend(const DictEntry & another,size_t end_pos,double new_weight)91 void Sentence::Extend(const DictEntry& another,
92 size_t end_pos,
93 double new_weight) {
94 entry_->weight = new_weight;
95 entry_->text.append(another.text);
96 entry_->code.insert(entry_->code.end(),
97 another.code.begin(),
98 another.code.end());
99 components_.push_back(another);
100 word_lengths_.push_back(end_pos - end());
101 set_end(end_pos);
102 DLOG(INFO) << "extend sentence " << end_pos << ") "
103 << text() << " weight: " << weight();
104 }
105
Offset(size_t offset)106 void Sentence::Offset(size_t offset) {
107 set_start(start() + offset);
108 set_end(end() + offset);
109 }
110
111 // TranslatorOptions
112
TranslatorOptions(const Ticket & ticket)113 TranslatorOptions::TranslatorOptions(const Ticket& ticket) {
114 if (!ticket.schema)
115 return;
116 if (Config *config = ticket.schema->config()) {
117 config->GetString(ticket.name_space + "/delimiter", &delimiters_) ||
118 config->GetString("speller/delimiter", &delimiters_);
119 config->GetString(ticket.name_space + "/tag", &tag_);
120 config->GetBool(ticket.name_space + "/contextual_suggestions",
121 &contextual_suggestions_);
122 config->GetBool(ticket.name_space + "/enable_completion",
123 &enable_completion_);
124 config->GetBool(ticket.name_space + "/strict_spelling",
125 &strict_spelling_);
126 config->GetDouble(ticket.name_space + "/initial_quality",
127 &initial_quality_);
128 preedit_formatter_.Load(
129 config->GetList(ticket.name_space + "/preedit_format"));
130 comment_formatter_.Load(
131 config->GetList(ticket.name_space + "/comment_format"));
132 user_dict_disabling_patterns_.Load(
133 config->GetList(
134 ticket.name_space + "/disable_user_dict_for_patterns"));
135 }
136 if (delimiters_.empty()) {
137 delimiters_ = " ";
138 }
139 }
140
IsUserDictDisabledFor(const string & input) const141 bool TranslatorOptions::IsUserDictDisabledFor(const string& input) const {
142 if (user_dict_disabling_patterns_.empty())
143 return false;
144 for (const auto& pattern : user_dict_disabling_patterns_) {
145 if (boost::regex_match(input, pattern))
146 return true;
147 }
148 return false;
149 }
150
151 } // namespace rime
152