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