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