]> git.lyx.org Git - lyx.git/blob - src/trans.C
860bd5755c63dae004b5fe55c8eae74419c5f84e
[lyx.git] / src / trans.C
1 #include <config.h>
2
3 #ifdef __GNUG__
4 #pragma implementation "trans.h"
5 #endif
6
7 #include "LyXView.h"
8 #include "trans.h"
9 #include "support/filetools.h"
10 #include "tex-strings.h"
11 #include "lyxlex.h"
12 #include "debug.h"
13 #include "trans_mgr.h"
14
15
16 // KmodInfo
17 KmodInfo::KmodInfo()
18 {
19         exception_list = 0;
20 }
21
22
23 // Default Trans
24 bool DefaultTrans::init_ = false;
25
26
27 DefaultTrans::DefaultTrans()
28 {
29         if (init_ == false) {
30                 // Do initialization
31                 init_ = true;
32         }
33 }
34
35
36 string DefaultTrans::process(char c, TransManager & k)
37 {
38         char dummy[2] = "?";
39         dummy[0] = c;
40     
41         return k.normalkey(c, dummy);
42 }
43
44
45 // Trans class
46
47 Trans::Trans()
48 {
49         int i;
50
51         for(i = 0; i < 256; ++i)
52                 keymap_[i] = 0;
53
54         for(i = 0; i < TEX_MAX_ACCENT + 1; ++i)
55                 kmod_list_[i] = 0;
56 }
57
58
59 Trans::~Trans()
60 {
61         FreeKeymap();
62 }
63
64
65 void Trans::InsertException(Trans::keyexc & exclist, char c,
66                             string const & data, bool flag, tex_accent accent)
67 {
68         keyexc p;
69
70         p = new Keyexc; 
71         p->next = exclist;
72         p->c = c;
73
74         p->data = data;
75         p->combined = flag;
76         p->accent = accent;
77
78         exclist = p;
79 }
80
81
82 void Trans::FreeException(Trans::keyexc & exclist)
83 {
84         Trans::keyexc p;
85
86         p = exclist;
87         while (p) {
88                 p = exclist->next;
89                 delete exclist;
90                 exclist = p;
91         }
92 }
93
94
95 void Trans::FreeKeymap()
96 {
97         int i;
98
99         for(i = 0; i < 256; ++i)
100                 if (keymap_[i]) {
101                         delete keymap_[i];
102                         keymap_[i] = 0;
103                 }
104         for(i = 0; i < TEX_MAX_ACCENT + 1; ++i)
105                 if (kmod_list_[i]) {
106                         FreeException(kmod_list_[i]->exception_list);
107                         delete kmod_list_[i];
108                         kmod_list_[i] = 0;
109                 }
110 }
111
112
113 bool Trans::IsDefined()
114 {
115         return !name_.empty();
116 }
117
118
119 string const & Trans::GetName()
120 {
121         return name_;
122 }
123
124
125 enum _kmaptags {
126         KCOMB = 1,
127         KMOD,
128         KMAP,
129         KXMOD,
130         K_LAST
131 };
132
133
134 struct keyword_item kmapTags[K_LAST-1] = {
135         {"\\kcomb", KCOMB },
136         { "\\kmap", KMAP },
137         { "\\kmod", KMOD },
138         { "\\kxmod", KXMOD }
139 };
140
141
142 tex_accent getkeymod(string const &);
143
144
145 void Trans::AddDeadkey(tex_accent accent, string const & keys,
146                        string const & allowed)
147 {
148         if (kmod_list_[accent]) {
149                 FreeException(kmod_list_[accent]->exception_list);
150                 
151                 delete kmod_list_[accent];
152         }
153         
154         kmod_list_[accent] = new kmod_list_decl;
155         kmod_list_[accent]->data = keys;
156         kmod_list_[accent]->accent = accent;
157         if (allowed == "all") { 
158                 kmod_list_[accent]->allowed= lyx_accent_table[accent].native;
159         } else { 
160                 kmod_list_[accent]->allowed = allowed;
161         }
162         
163         for(string::size_type i = 0; i < keys.length(); ++i) {
164                 char * temp;
165                 if (keys[i] == char(254))
166                         lyxerr << "check one triggered" << endl;
167                 temp = keymap_[keys[i]] = new char[2];
168                 temp[0] = 0; temp[1] = accent;
169         }
170         kmod_list_[accent]->exception_list = 0;
171 }
172
173
174 int Trans::Load(LyXLex & lex)
175 {
176         bool error = false;
177
178         while (lex.IsOK() && !error) {
179                 switch(lex.lex()) {
180                 case KMOD:
181                 {
182                         if (lyxerr.debugging(Debug::KBMAP))
183                                 lyxerr << "KMOD:\t" << lex.text() << endl;
184                         if (lex.next(true)) {
185                                 if (lyxerr.debugging(Debug::KBMAP))
186                                         lyxerr << "key\t`" << lex.text()
187                                                << "'" << endl;
188                         } else
189                                 return -1;
190                         
191                         string keys = lex.GetString();
192
193                         if (lex.next(true)) {
194                                 if ( lyxerr.debugging(Debug::KBMAP))
195                                         lyxerr << "accent\t`" << lex.text()
196                                                << "'" << endl;
197                         } else
198                                 return -1;
199
200                         tex_accent accent = getkeymod(lex.GetString());
201
202                         if (accent == TEX_NOACCENT)
203                                 return -1;
204
205                         if (lex.next(true)) {
206                                 if (lyxerr.debugging(Debug::KBMAP))
207                                         lyxerr << "allowed\t`" << lex.text()
208                                                << "'" << endl;
209                         } else
210                                 return -1;
211
212                         string allowed = lex.GetString();
213
214                         AddDeadkey(accent, keys, allowed);
215                         break;
216                 }       
217                 case KCOMB: {
218                         char const * str;
219
220                         lyxerr[Debug::KBMAP] << "KCOMB:" << endl;
221                         if (lex.next(true)) {
222                                 str= lex.text();
223                                 lyxerr[Debug::KBMAP] << str << endl;
224                         } else
225                                 return -1;
226                         
227                         tex_accent accent_1= getkeymod(str);
228                         if (accent_1 == TEX_NOACCENT) return -1;
229
230                         if (lex.next(true)) {
231                                 str= lex.text();
232                                 lyxerr[Debug::KBMAP] << str << endl;
233                         } else
234                                 return -1;
235
236                         tex_accent accent_2= getkeymod(str);
237                         if (accent_2 == TEX_NOACCENT) return -1;
238
239                         if (kmod_list_[accent_1] == 0 || kmod_list_[accent_2] == 0)
240                                 return -1;
241
242                         // Find what key accent_2 is on - should check about accent_1 also
243                         int key;
244
245                         for(key = 0; key < 256; ++key) {
246                                 if (keymap_[key] && keymap_[key][0] == 0
247                                     && keymap_[key][1] == accent_2)
248                                         break;
249                         }
250                         string allowed;
251
252                         if (lex.next()) {
253                                 allowed = lex.GetString();
254                                 lyxerr[Debug::KBMAP] << "allowed: "
255                                                      << allowed << endl;
256                         } else
257                                 return -1;
258
259                         InsertException(kmod_list_[accent_1]->exception_list,(char)key, allowed, true, accent_2);
260                 }
261                 break;
262                 case KMAP: {
263                         char key_from;
264                         char * string_to;
265
266                         if (lyxerr.debugging(Debug::KBMAP))
267                                 lyxerr << "KMAP:\t" << lex.text() << endl;
268                         if (lex.next(true)) {
269                                 key_from= lex.text()[0];
270                                 if (lyxerr.debugging(Debug::KBMAP))
271                                         lyxerr << "\t`" << lex.text() << "'"
272                                                << endl;
273                         } else
274                                 return -1;
275
276                         if (lex.next(true)) {
277                                 char const * t = lex.text();
278                                 string_to = strcpy(new char[strlen(t)+1], t);
279                                 if (key_from == char(254))
280                                         lyxerr << "check two triggered"
281                                                << endl;
282                                 keymap_[key_from] = string_to;
283                                 if (lyxerr.debugging(Debug::KBMAP))
284                                         lyxerr << "\t`" << string_to << "'"
285                                                << endl;
286                         } else
287                                 return -1;
288
289                         break;
290                 }
291                 case KXMOD: {
292                         tex_accent accent;
293                         char key;
294                         char const * str;
295
296                         if (lyxerr.debugging(Debug::KBMAP))
297                                 lyxerr << "KXMOD:\t" << lex.text() << endl;
298                         if (lex.next(true)) {
299                                 if (lyxerr.debugging(Debug::KBMAP))
300                                         lyxerr << "\t`" << lex.text() << "'"
301                                                << endl;
302                                 accent = getkeymod(lex.GetString());
303                         } else
304                                 return -1;
305
306                         if (lex.next(true)) {
307                                 if (lyxerr.debugging(Debug::KBMAP))
308                                         lyxerr << "\t`" << lex.text() << "'"
309                                                << endl;
310                                 key = lex.text()[0];
311                         } else
312                                 return -1;
313
314                         if (lex.next(true)) {
315                                 if (lyxerr.debugging(Debug::KBMAP))
316                                         lyxerr << "\t`" << lex.text() << "'"
317                                                << endl;
318                                 str = lex.text();
319                         } else
320                                 return -1;
321
322                         InsertException(kmod_list_[accent]->exception_list, key, str);
323                         break;
324                 }
325                 case LyXLex::LEX_FEOF:
326                         lyxerr[Debug::PARSER] << "End of parsing" << endl;
327                         break;
328                 default:
329                         lex.printError("ParseKeymapFile: "
330                                        "Unknown tag: `$$Token'");
331                         return -1;
332                 }
333         }
334         return 0;
335 }
336
337
338 bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i)
339 {
340         if (kmod_list_[accent]!= 0) {
341                 i = *kmod_list_[accent];
342                 return true;
343         }
344         return false;
345 }
346
347
348 string Trans::process(char c, TransManager & k)
349 {
350         lyxerr << "enter process" << endl;
351         char dummy[2] = "?";
352         char * dt = dummy;
353         char * t = Match(c);
354         lyxerr << "finished variables" << endl;
355     
356         if ((t == 0 && (dt[0] = c)) || (t[0] != 0 && (dt = t)) ){
357                 lyxerr << "normalkey" << endl;
358                 return k.normalkey(c, dt);
359         } else {
360                 lyxerr << "deadkey" << endl;
361                 return k.deadkey(c, *kmod_list_[(tex_accent)t[1]]);
362         }
363 }
364
365
366 int Trans::Load(string const & language)
367 {
368         string filename = LibFileSearch("kbd", language, "kmap");
369         if (filename.empty())
370                 return -1;
371
372         FreeKeymap();
373         LyXLex lex(kmapTags, K_LAST-1);
374         lex.setFile(filename);
375         
376         int res = Load(lex);
377
378         if (res == 0) {
379                 name_ = language;
380         } else
381                 name_.clear();
382
383         return res;
384 }
385
386
387 tex_accent getkeymod(string const & p)
388         /* return modifier - decoded from p and update p */
389 {
390         for (int i = 1; i <= TEX_MAX_ACCENT; ++i) {
391                 if (lyxerr.debugging(Debug::KBMAP))
392                         lyxerr << "p = " << p
393                                << ", lyx_accent_table[" << i
394                                << "].name = `" << lyx_accent_table[i].name
395                                << "'" << endl;
396                 
397                 if ( lyx_accent_table[i].name && contains(p, lyx_accent_table[i].name)) {
398                         lyxerr[Debug::KBMAP] << "Found it!" << endl;
399                         return (tex_accent)i;
400                 }
401         }
402         return TEX_NOACCENT;
403 }