9 #include "support/filetools.h"
10 #include "support/lstrings.h"
11 #include "tex-strings.h"
14 #include "trans_mgr.h"
30 bool DefaultTrans::init_ = false;
33 DefaultTrans::DefaultTrans()
43 string const DefaultTrans::process(char c, TransManager & k)
48 return k.normalkey(c, dummy);
51 string const DefaultTrans::process(char c, TransManager & k)
53 return k.normalkey(c);
63 for (int i = 0; i < TEX_MAX_ACCENT + 1; ++i)
75 void Trans::InsertException(KmodException & exclist, char c,
76 string const & data, bool flag, tex_accent accent)
79 keyexc p = new Keyexc;
94 exclist.insert(exclist.begin(), p);
96 // exclist.push_back(p);
101 void Trans::FreeException(KmodException & exclist)
104 Trans::keyexc p = exclist;
116 void Trans::FreeKeymap()
119 for (int i = 0; i < 256; ++i)
120 if (!keymap_[i].empty()) {
123 for (int i = 0; i < TEX_MAX_ACCENT + 1; ++i)
125 FreeException(kmod_list_[i]->exception_list);
126 delete kmod_list_[i];
136 bool Trans::IsDefined() const
138 return !name_.empty();
142 string const & Trans::GetName() const
157 struct keyword_item kmapTags[K_LAST - 1] = {
165 tex_accent getkeymod(string const &);
169 void Trans::AddDeadkey(tex_accent accent, string const & keys,
170 string const & allowed)
172 void Trans::AddDeadkey(tex_accent accent, string const & keys)
176 if (kmod_list_[accent]) {
177 FreeException(kmod_list_[accent]->exception_list);
179 delete kmod_list_[accent];
182 kmod_list_[accent] = new KmodInfo;
183 kmod_list_[accent]->data = keys;
184 kmod_list_[accent]->accent = accent;
189 kmod_list_[accent] = tmp;
192 if (allowed == "native") {
193 kmod_list_[accent]->allowed= lyx_accent_table[accent].native;
195 kmod_list_[accent]->allowed = allowed;
198 for (string::size_type i = 0; i < keys.length(); ++i) {
200 keymap_[static_cast<unsigned char>(keys[i])];
204 // But the question remains: "Should we be allowed
205 // to change bindings, without unbinding first?"
208 temp += char(accent);
211 for (string::size_type i = 0; i < keys.length(); ++i) {
215 keymap_[keys[i]] = tmp;
219 kmod_list_[accent]->exception_list = 0;
224 int Trans::Load(LyXLex & lex)
228 while (lex.IsOK() && !error) {
232 if (lyxerr.debugging(Debug::KBMAP))
233 lyxerr << "KMOD:\t" << lex.text() << endl;
234 if (lex.next(true)) {
235 if (lyxerr.debugging(Debug::KBMAP))
236 lyxerr << "key\t`" << lex.text()
241 string const keys = lex.GetString();
243 if (lex.next(true)) {
244 if (lyxerr.debugging(Debug::KBMAP))
245 lyxerr << "accent\t`" << lex.text()
250 tex_accent accent = getkeymod(lex.GetString());
252 if (accent == TEX_NOACCENT)
256 #warning This code should be removed...
257 // But we need to fix up all the kmap files first
258 // so that this field is not present anymore.
259 if (lex.next(true)) {
260 if (lyxerr.debugging(Debug::KBMAP))
261 lyxerr << "allowed\t`" << lex.text()
266 string const allowed = lex.GetString();
267 AddDeadkey(accent, keys /*, allowed*/);
269 AddDeadkey(accent, keys);
276 lyxerr[Debug::KBMAP] << "KCOMB:" << endl;
277 if (lex.next(true)) {
279 lyxerr[Debug::KBMAP] << str << endl;
283 tex_accent accent_1 = getkeymod(str);
284 if (accent_1 == TEX_NOACCENT) return -1;
286 if (lex.next(true)) {
288 lyxerr[Debug::KBMAP] << str << endl;
292 tex_accent accent_2= getkeymod(str);
293 if (accent_2 == TEX_NOACCENT) return -1;
296 if (kmod_list_[accent_1] == 0
297 || kmod_list_[accent_2] == 0)
300 std::map<int, KmodInfo>::iterator it1 =
301 kmod_list_.find(accent_1);
302 std::map<int, KmodInfo>::iterator it2 =
303 kmod_list_.find(accent_2);
304 if (it1 == kmod_list_.end()
305 || it2 == kmod_list_.end()) {
310 // Find what key accent_2 is on - should
311 // check about accent_1 also
314 for (; key < 256; ++key) {
315 if (!keymap_[key].empty()
316 && keymap_[key][0] == 0
317 && keymap_[key][1] == accent_2)
323 allowed = lex.GetString();
324 lyxerr[Debug::KBMAP] << "allowed: "
329 InsertException(kmod_list_[accent_1].exception_list,
330 static_cast<char>(key), allowed,
333 std::map<int, string>::iterator it = keymap_.begin();
334 std::map<int, string>::iterator end = keymap_.end();
335 for (; it != end; ++it) {
336 if (!it->second.empty()
337 && it->second[0] == 0
338 && it->second[1] == accent_2)
343 allowed = lex.GetString();
344 lyxerr[Debug::KBMAP] << "allowed: "
350 InsertException(kmod_list_[accent_1].exception_list,
351 static_cast<char>(it->first), allowed,
357 unsigned char key_from;
359 if (lyxerr.debugging(Debug::KBMAP))
360 lyxerr << "KMAP:\t" << lex.text() << endl;
361 if (lex.next(true)) {
362 key_from = lex.text()[0];
363 if (lyxerr.debugging(Debug::KBMAP))
364 lyxerr << "\t`" << lex.text() << "'"
369 if (lex.next(true)) {
370 string string_to = lex.text();
372 keymap_[key_from] = string_to;
374 keymap_[key_from] = string_to;
376 if (lyxerr.debugging(Debug::KBMAP))
377 lyxerr << "\t`" << string_to << "'"
389 if (lyxerr.debugging(Debug::KBMAP))
390 lyxerr << "KXMOD:\t" << lex.text() << endl;
391 if (lex.next(true)) {
392 if (lyxerr.debugging(Debug::KBMAP))
393 lyxerr << "\t`" << lex.text() << "'"
395 accent = getkeymod(lex.GetString());
399 if (lex.next(true)) {
400 if (lyxerr.debugging(Debug::KBMAP))
401 lyxerr << "\t`" << lex.text() << "'"
407 if (lex.next(true)) {
408 if (lyxerr.debugging(Debug::KBMAP))
409 lyxerr << "\t`" << lex.text() << "'"
415 InsertException(kmod_list_[accent].exception_list,
419 case LyXLex::LEX_FEOF:
420 lyxerr[Debug::PARSER] << "End of parsing" << endl;
423 lex.printError("ParseKeymapFile: "
424 "Unknown tag: `$$Token'");
432 bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i) const
435 if (kmod_list_[accent] != 0) {
436 i = *kmod_list_[accent];
441 std::map<int, KmodInfo>::const_iterator cit = kmod_list_.find(accent);
442 if (cit != kmod_list_.end()) {
452 string const Trans::process(char c, TransManager & k)
455 string const t = Match(static_cast<unsigned char>(c));
457 if (t.empty() && c != 0) {
459 return k.normalkey(c, dt);
460 } else if (!t.empty() && t[0] != char(0)) {
462 return k.normalkey(c, dt);
465 *kmod_list_[static_cast<tex_accent>(t[1])]);
469 string const Trans::process(char c, TransManager & k)
471 string const t = Match(static_cast<unsigned char>(c));
473 if (t.empty() && c != 0) {
474 return k.normalkey(c);
475 } else if (!t.empty() && t[0] != char(0)) {
476 //return k.normalkey(c);
481 *kmod_list_[static_cast<tex_accent>(t[1])]);
484 kmod_list_[static_cast<tex_accent>(t[1])]);
491 int Trans::Load(string const & language)
493 string const filename = LibFileSearch("kbd", language, "kmap");
494 if (filename.empty())
498 LyXLex lex(kmapTags, K_LAST-1);
499 lex.setFile(filename);
501 int const res = Load(lex);
512 tex_accent getkeymod(string const & p)
513 /* return modifier - decoded from p and update p */
515 for (int i = 1; i <= TEX_MAX_ACCENT; ++i) {
516 if (lyxerr.debugging(Debug::KBMAP))
517 lyxerr << "p = " << p
518 << ", lyx_accent_table[" << i
519 << "].name = `" << lyx_accent_table[i].name
522 if (lyx_accent_table[i].name
523 && contains(p, lyx_accent_table[i].name)) {
524 lyxerr[Debug::KBMAP] << "Found it!" << endl;
525 return static_cast<tex_accent>(i);