]> git.lyx.org Git - features.git/blob - src/trans.C
6e3d2e586cf0780dba53e9cd521d215fdac00a10
[features.git] / src / trans.C
1 #include <config.h>
2
3 #ifdef __GNUG__
4 #pragma implementation
5 #endif
6
7 #include "LyXView.h"
8 #include "trans.h"
9 #include "support/filetools.h"
10 #include "support/lstrings.h"
11 #include "tex-strings.h"
12 #include "lyxlex.h"
13 #include "debug.h"
14 #include "trans_mgr.h"
15
16 using std::endl;
17
18
19 // KmodInfo
20 KmodInfo::KmodInfo()
21 {
22 #if 0
23         exception_list = 0;
24 #endif
25 }
26
27
28 #if 0
29 // Default Trans
30 bool DefaultTrans::init_ = false;
31
32
33 DefaultTrans::DefaultTrans()
34 {
35         if (init_ == false) {
36                 // Do initialization
37                 init_ = true;
38         }
39 }
40
41
42 #if 0
43 string const DefaultTrans::process(char c, TransManager & k)
44 {
45         char dummy[2] = "?";
46         dummy[0] = c;
47     
48         return k.normalkey(c, dummy);
49 }
50 #else
51 string const DefaultTrans::process(char c, TransManager & k)
52 {
53         return k.normalkey(c);
54 }
55 #endif
56 #endif
57
58 // Trans class
59
60 Trans::Trans()
61 {
62 #if 0
63         for (int i = 0; i < TEX_MAX_ACCENT + 1; ++i)
64                 kmod_list_[i] = 0;
65 #endif
66 }
67
68
69 Trans::~Trans()
70 {
71         FreeKeymap();
72 }
73
74
75 void Trans::InsertException(KmodException & exclist, char c,
76                             string const & data, bool flag, tex_accent accent)
77 {
78 #if 0
79         keyexc p = new Keyexc; 
80         p->next = exclist;
81         p->c = c;
82
83         p->data = data;
84         p->combined = flag;
85         p->accent = accent;
86
87         exclist = p;
88 #else
89         Keyexc p;
90         p.c = c;
91         p.data = data;
92         p.combined = flag;
93         p.accent = accent;
94         exclist.insert(exclist.begin(), p);
95         // or just
96         // exclist.push_back(p);
97 #endif
98 }
99
100
101 void Trans::FreeException(KmodException & exclist)
102 {
103 #if 0
104         Trans::keyexc p = exclist;
105         while (p) {
106                 p = exclist->next;
107                 delete exclist;
108                 exclist = p;
109         }
110 #else
111         exclist.clear();
112 #endif
113 }
114
115
116 void Trans::FreeKeymap()
117 {
118 #if 0
119         for (int i = 0; i < 256; ++i)
120                 if (!keymap_[i].empty()) {
121                         keymap_[i].erase();
122                 }
123         for (int i = 0; i < TEX_MAX_ACCENT + 1; ++i)
124                 if (kmod_list_[i]) {
125                         FreeException(kmod_list_[i]->exception_list);
126                         delete kmod_list_[i];
127                         kmod_list_[i] = 0;
128                 }
129 #else
130         kmod_list_.clear();
131         keymap_.clear();
132 #endif
133 }
134
135
136 bool Trans::IsDefined() const
137 {
138         return !name_.empty();
139 }
140
141
142 string const & Trans::GetName() const
143 {
144         return name_;
145 }
146
147
148 enum kmaptags_ {
149         KCOMB = 1,
150         KMOD,
151         KMAP,
152         KXMOD,
153         K_LAST
154 };
155
156
157 struct keyword_item kmapTags[K_LAST - 1] = {
158         {"\\kcomb", KCOMB },
159         { "\\kmap", KMAP },
160         { "\\kmod", KMOD },
161         { "\\kxmod", KXMOD }
162 };
163
164
165 tex_accent getkeymod(string const &);
166
167
168 #if 0
169 void Trans::AddDeadkey(tex_accent accent, string const & keys,
170                        string const & allowed)
171 #else
172 void Trans::AddDeadkey(tex_accent accent, string const & keys)
173 #endif
174 {
175 #if 0
176         if (kmod_list_[accent]) {
177                 FreeException(kmod_list_[accent]->exception_list);
178                 
179                 delete kmod_list_[accent];
180         }
181         
182         kmod_list_[accent] = new KmodInfo;
183         kmod_list_[accent]->data = keys;
184         kmod_list_[accent]->accent = accent;
185 #else
186         KmodInfo tmp;
187         tmp.data = keys;
188         tmp.accent = accent;
189         kmod_list_[accent] = tmp;
190 #endif
191 #if 0
192         if (allowed == "native") { 
193                 kmod_list_[accent]->allowed= lyx_accent_table[accent].native;
194         } else {
195                 kmod_list_[accent]->allowed = allowed;
196         }
197
198         for (string::size_type i = 0; i < keys.length(); ++i) {
199                 string & temp =
200                         keymap_[static_cast<unsigned char>(keys[i])];
201                 if (!temp.empty())
202                         temp.erase();
203
204                 // But the question remains: "Should we be allowed
205                 // to change bindings, without unbinding first?"
206                 // Lgb
207                 temp += char(0);
208                 temp += char(accent);
209         }
210 #else
211         for (string::size_type i = 0; i < keys.length(); ++i) {
212                 string tmp;
213                 tmp += char(0);
214                 tmp += char(accent);
215                 keymap_[keys[i]] = tmp;
216         }
217 #endif
218 #if 0
219         kmod_list_[accent]->exception_list = 0;
220 #endif
221 }
222
223
224 int Trans::Load(LyXLex & lex)
225 {
226         bool error = false;
227
228         while (lex.IsOK() && !error) {
229                 switch (lex.lex()) {
230                 case KMOD:
231                 {
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()
237                                                << "'" << endl;
238                         } else
239                                 return -1;
240                         
241                         string const keys = lex.GetString();
242
243                         if (lex.next(true)) {
244                                 if (lyxerr.debugging(Debug::KBMAP))
245                                         lyxerr << "accent\t`" << lex.text()
246                                                << "'" << endl;
247                         } else
248                                 return -1;
249
250                         tex_accent accent = getkeymod(lex.GetString());
251
252                         if (accent == TEX_NOACCENT)
253                                 return -1;
254
255 #if 1
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()
262                                                << "'" << endl;
263                         } else
264                                 return -1;
265
266                         string const allowed = lex.GetString();
267                         AddDeadkey(accent, keys /*, allowed*/);
268 #else
269                         AddDeadkey(accent, keys);
270 #endif
271                         break;
272                 }       
273                 case KCOMB: {
274                         string str;
275
276                         lyxerr[Debug::KBMAP] << "KCOMB:" << endl;
277                         if (lex.next(true)) {
278                                 str= lex.text();
279                                 lyxerr[Debug::KBMAP] << str << endl;
280                         } else
281                                 return -1;
282                         
283                         tex_accent accent_1 = getkeymod(str);
284                         if (accent_1 == TEX_NOACCENT) return -1;
285
286                         if (lex.next(true)) {
287                                 str = lex.text();
288                                 lyxerr[Debug::KBMAP] << str << endl;
289                         } else
290                                 return -1;
291
292                         tex_accent accent_2= getkeymod(str);
293                         if (accent_2 == TEX_NOACCENT) return -1;
294
295 #if 0
296                         if (kmod_list_[accent_1] == 0
297                             || kmod_list_[accent_2] == 0)
298                                 return -1;
299 #else
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()) {
306                                 return -1;
307                         }
308 #endif
309
310                         // Find what key accent_2 is on - should
311                         // check about accent_1 also
312 #if 0
313                         int key = 0;
314                         for (; key < 256; ++key) {
315                                 if (!keymap_[key].empty()
316                                     && keymap_[key][0] == 0
317                                     && keymap_[key][1] == accent_2)
318                                         break;
319                         }
320                         string allowed;
321
322                         if (lex.next()) {
323                                 allowed = lex.GetString();
324                                 lyxerr[Debug::KBMAP] << "allowed: "
325                                                      << allowed << endl;
326                         } else
327                                 return -1;
328
329                         InsertException(kmod_list_[accent_1].exception_list,
330                                         static_cast<char>(key), allowed,
331                                         true, accent_2);
332 #else
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)
339                                         break;
340                         }
341                         string allowed;
342                         if (lex.next()) {
343                                 allowed = lex.GetString();
344                                 lyxerr[Debug::KBMAP] << "allowed: "
345                                                      << allowed << endl;
346                         } else {
347                                 return -1;
348                         }
349                         
350                         InsertException(kmod_list_[accent_1].exception_list,
351                                         static_cast<char>(it->first), allowed,
352                                         true, accent_2);
353 #endif
354                 }
355                 break;
356                 case KMAP: {
357                         unsigned char key_from;
358
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() << "'"
365                                                << endl;
366                         } else
367                                 return -1;
368
369                         if (lex.next(true)) {
370                                 string string_to = lex.text();
371 #if 0
372                                 keymap_[key_from] = string_to;
373 #else
374                                 keymap_[key_from] = string_to;
375 #endif
376                                 if (lyxerr.debugging(Debug::KBMAP))
377                                         lyxerr << "\t`" << string_to << "'"
378                                                << endl;
379                         } else
380                                 return -1;
381
382                         break;
383                 }
384                 case KXMOD: {
385                         tex_accent accent;
386                         char key;
387                         string str;
388
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() << "'"
394                                                << endl;
395                                 accent = getkeymod(lex.GetString());
396                         } else
397                                 return -1;
398
399                         if (lex.next(true)) {
400                                 if (lyxerr.debugging(Debug::KBMAP))
401                                         lyxerr << "\t`" << lex.text() << "'"
402                                                << endl;
403                                 key = lex.text()[0];
404                         } else
405                                 return -1;
406
407                         if (lex.next(true)) {
408                                 if (lyxerr.debugging(Debug::KBMAP))
409                                         lyxerr << "\t`" << lex.text() << "'"
410                                                << endl;
411                                 str = lex.text();
412                         } else
413                                 return -1;
414
415                         InsertException(kmod_list_[accent].exception_list,
416                                         key, str);
417                         break;
418                 }
419                 case LyXLex::LEX_FEOF:
420                         lyxerr[Debug::PARSER] << "End of parsing" << endl;
421                         break;
422                 default:
423                         lex.printError("ParseKeymapFile: "
424                                        "Unknown tag: `$$Token'");
425                         return -1;
426                 }
427         }
428         return 0;
429 }
430
431
432 bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i) const
433 {
434 #if 0
435         if (kmod_list_[accent] != 0) {
436                 i = *kmod_list_[accent];
437                 return true;
438         }
439         return false;
440 #else
441         std::map<int, KmodInfo>::const_iterator cit = kmod_list_.find(accent);
442         if (cit != kmod_list_.end()) {
443                 i = cit->second;
444                 return true;
445         }
446         return false;
447 #endif
448 }
449
450
451 #if 0
452 string const Trans::process(char c, TransManager & k)
453 {
454         string dt("?");
455         string const t = Match(static_cast<unsigned char>(c));
456
457         if (t.empty() && c != 0) {
458                 dt[0] = c;
459                 return k.normalkey(c, dt);
460         } else if (!t.empty() && t[0] != char(0)) {
461                 dt = t;
462                 return k.normalkey(c, dt);
463         } else {
464                 return k.deadkey(c,
465                                  *kmod_list_[static_cast<tex_accent>(t[1])]);
466         }
467 }
468 #else
469 string const Trans::process(char c, TransManager & k)
470 {
471         string const t = Match(static_cast<unsigned char>(c));
472
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);
477                 return t;
478         } else {
479 #if 0
480                 return k.deadkey(c,
481                                  *kmod_list_[static_cast<tex_accent>(t[1])]);
482 #else
483                 return k.deadkey(c,
484                                  kmod_list_[static_cast<tex_accent>(t[1])]);
485 #endif
486         }
487 }
488 #endif
489
490
491 int Trans::Load(string const & language)
492 {
493         string const filename = LibFileSearch("kbd", language, "kmap");
494         if (filename.empty())
495                 return -1;
496
497         FreeKeymap();
498         LyXLex lex(kmapTags, K_LAST-1);
499         lex.setFile(filename);
500         
501         int const res = Load(lex);
502
503         if (res == 0) {
504                 name_ = language;
505         } else
506                 name_.erase();
507
508         return res;
509 }
510
511
512 tex_accent getkeymod(string const & p)
513         /* return modifier - decoded from p and update p */
514 {
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
520                                << "'" << endl;
521                 
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);
526                 }
527         }
528         return TEX_NOACCENT;
529 }