This commit was manufactured by cvs2svn to create tag
[lyx.git] / src / trans.C
blobd189884938055bfce1f08e312411316a84362372
1 #include <config.h>
3 //#include <cstdio>
5 #ifdef __GNUG__
6 #pragma implementation "trans.h"
7 #endif
9 #include "LyXView.h"
10 #include "trans.h"
11 #include "support/filetools.h"
12 #include "tex-strings.h"
13 #include "lyxlex.h"
14 #include "debug.h"
15 #include "trans_mgr.h"
18 // KmodInfo
19 KmodInfo::KmodInfo()
21         exception_list=0;
25 KmodInfo::KmodInfo(const KmodInfo& o)
27         (*this)=o;
31 KmodInfo& KmodInfo::operator=(const KmodInfo& o)
33         if (this!=&o) {
34                 allowed=o.allowed;
35                 accent=o.accent;
36                 data=o.data;
37                 exception_list=o.exception_list;
38         }
40         return *this;
43     
44 // Default Trans
45 bool DefaultTrans::init_=false;
48 DefaultTrans::DefaultTrans()
50         if (init_==false) {
51                 // Do initialization
52                 init_=true;
53         }
57 string DefaultTrans::process(char c,TransManager& k)
59         char dummy[2]="?";
60         dummy[0]=c;
61     
62         return k.normalkey(c,dummy);
66 // Trans class
68 Trans::Trans()
70         int i;
72         for(i=0; i<256; i++)
73                 keymap_[i]=0;
75         for(i=0; i<TEX_MAX_ACCENT+1; i++)
76                 kmod_list_[i]=0;
80 Trans::~Trans()
82         FreeKeymap();
86 void Trans::InsertException(Trans::keyexc& exclist, char c,
87                             const string& data,bool flag,tex_accent accent)
89         keyexc p;
91         p = new Keyexc; 
92         p -> next = exclist;
93         p -> c = c;
95         p->data = data;
96         p->combined=flag;
97         p->accent=accent;
99         exclist = p;
103 void Trans::FreeException(Trans::keyexc& exclist)
105         Trans::keyexc p;
107         p = exclist;
108         while (p) {
109                 p = exclist->next;
110                 delete exclist;
111                 exclist = p;
112         }
116 void Trans::FreeKeymap()
118         int i;
120         for(i=0; i<256; i++)
121                 if (keymap_[i]) {
122                         delete keymap_[i];
123                         keymap_[i]=0;
124                 }
125         for(i=0; i<TEX_MAX_ACCENT+1; i++)
126                 if (kmod_list_[i]) {
127                         FreeException(kmod_list_[i]->exception_list);
128                         delete kmod_list_[i];
129                         kmod_list_[i]=0;
130                 }
134 bool Trans::IsDefined()
136         return !name_.empty();
140 const string& Trans::GetName()
142         return name_;
146 enum _kmaptags {
147         KCOMB=1,
148         KMOD,
149         KMAP,
150         KXMOD,
151         K_LAST
155 struct keyword_item kmapTags[K_LAST-1] = {
156         {"\\kcomb",KCOMB },
157         { "\\kmap", KMAP },
158         { "\\kmod", KMOD },
159         { "\\kxmod", KXMOD }
163 tex_accent getkeymod(const string&);
166 void Trans::AddDeadkey(tex_accent accent,const string& keys,
167                        const string& allowed)
169         if (kmod_list_[accent]) {
170                 FreeException(kmod_list_[accent]->exception_list);
171                 
172                 delete kmod_list_[accent];
173         }
174         
175         kmod_list_[accent] = new kmod_list_decl;
176         kmod_list_[accent]->data = keys;
177         kmod_list_[accent]->accent = accent;
178         if (allowed=="all") { 
179                 kmod_list_[accent]->allowed=lyx_accent_table[accent].native;
180         } else { 
181                 kmod_list_[accent]->allowed = allowed;
182         }
183         
184         for(string::size_type i = 0; i < keys.length(); ++i) {
185                 char * temp;
186                 temp = keymap_[keys[i]] = new char[2];
187                 temp[0] = 0; temp[1] = accent;
188         }
189         kmod_list_[accent]->exception_list=0;
193 int Trans::Load(LyXLex &lex)
195         bool error = false;
197         while (lex.IsOK() && !error) {
198                 switch(lex.lex()) {
199                 case KMOD:
200                 {
201                         if (lyxerr.debugging(Debug::KBMAP))
202                                 lyxerr << "KMOD:\t" << lex.text() << endl;
203                         if (lex.next(true)) {
204                                 if (lyxerr.debugging(Debug::KBMAP))
205                                         lyxerr << "key\t`" << lex.text()
206                                                << "'" << endl;
207                         } else
208                                 return -1;
209                         
210                         string keys = lex.GetString();
212                         if (lex.next(true)) {
213                                 if ( lyxerr.debugging(Debug::KBMAP))
214                                         lyxerr << "accent\t`" << lex.text()
215                                                << "'" << endl;
216                         } else
217                                 return -1;
219                         tex_accent accent = getkeymod(lex.GetString());
221                         if (accent==TEX_NOACCENT)
222                                 return -1;
224                         if (lex.next(true)) {
225                                 if (lyxerr.debugging(Debug::KBMAP))
226                                         lyxerr << "allowed\t`" << lex.text()
227                                                << "'" << endl;
228                         } else
229                                 return -1;
231                         string allowed = lex.GetString();
233                         AddDeadkey(accent, keys, allowed);
234                         break;
235                 }       
236                 case KCOMB: {
237                         const char *str;
239                         lyxerr[Debug::KBMAP] << "KCOMB:" << endl;
240                         if (lex.next(true)) {
241                                 str=lex.text();
242                                 lyxerr[Debug::KBMAP] << str << endl;
243                         } else
244                                 return -1;
245                         
246                         tex_accent accent_1=getkeymod(str);
247                         if (accent_1==TEX_NOACCENT) return -1;
249                         if (lex.next(true)) {
250                                 str=lex.text();
251                                 lyxerr[Debug::KBMAP] << str << endl;
252                         } else
253                                 return -1;
255                         tex_accent accent_2=getkeymod(str);
256                         if (accent_2==TEX_NOACCENT) return -1;
258                         if (kmod_list_[accent_1]==0 || kmod_list_[accent_2]==0)
259                                 return -1;
261                         // Find what key accent_2 is on - should check about accent_1 also
262                         int key;
264                         for(key=0;key<256;key++) 
265                                 if (keymap_[key] && keymap_[key][0]==0 && keymap_[key][1]==accent_2)
266                                         break;
267                         
268                         string allowed;
270                         if (lex.next()) {
271                                 allowed=lex.GetString();
272                                 lyxerr[Debug::KBMAP] << "allowed: "
273                                                      << allowed << endl;
274                         } else
275                                 return -1;
277                         InsertException(kmod_list_[accent_1]->exception_list,(char)key,allowed,true,accent_2);
278                 }
279                 break;
280                 case KMAP: {
281                         char key_from;
282                         char *string_to;
284                         if (lyxerr.debugging(Debug::KBMAP))
285                                 lyxerr << "KMAP:\t" << lex.text() << endl;
286                         if (lex.next(true)) {
287                                 key_from=lex.text()[0];
288                                 if (lyxerr.debugging(Debug::KBMAP))
289                                         lyxerr << "\t`" << lex.text() << "'"
290                                                << endl;
291                         } else
292                                 return -1;
294                         if (lex.next(true)) {
295                                 char const *t = lex.text();
296                                 string_to = strcpy(new char[strlen(t)+1],t);
297                                 keymap_[key_from]=string_to;
298                                 if (lyxerr.debugging(Debug::KBMAP))
299                                         lyxerr << "\t`" << string_to << "'"
300                                                << endl;
301                         } else
302                                 return -1;
304                         break;
305                 }
306                 case KXMOD: {
307                         tex_accent accent;
308                         char key;
309                         const char *str;
311                         if (lyxerr.debugging(Debug::KBMAP))
312                                 lyxerr << "KXMOD:\t" << lex.text() << endl;
313                         if (lex.next(true)) {
314                                 if (lyxerr.debugging(Debug::KBMAP))
315                                         lyxerr << "\t`" << lex.text() << "'"
316                                                << endl;
317                                 accent = getkeymod(lex.GetString());
318                         } else
319                                 return -1;
321                         if (lex.next(true)) {
322                                 if (lyxerr.debugging(Debug::KBMAP))
323                                         lyxerr << "\t`" << lex.text() << "'"
324                                                << endl;
325                                 key=lex.text()[0];
326                         } else
327                                 return -1;
329                         if (lex.next(true)) {
330                                 if (lyxerr.debugging(Debug::KBMAP))
331                                         lyxerr << "\t`" << lex.text() << "'"
332                                                << endl;
333                                 str=lex.text();
334                         } else
335                                 return -1;
337                         InsertException(kmod_list_[accent]->exception_list,key,str);
338                         break;
339                 }
340                 case LyXLex::LEX_FEOF:
341                         lyxerr[Debug::PARSER] << "End of parsing" << endl;
342                         break;
343                 default:
344                         lex.printError("ParseKeymapFile: "
345                                        "Unknown tag: `$$Token'");
346                         return -1;
347                 }
348         }
349         return 0;
353 bool Trans::isAccentDefined(tex_accent accent,KmodInfo& i)
355         if (kmod_list_[accent]!=0) {
356                 i=*kmod_list_[accent];
357                 return true;
358         }
359         return false;
363 string Trans::process(char c,TransManager& k)
365         char dummy[2]="?";
366         char *dt=dummy;
367         char *t=Match(c);
368         
369     
370         if ((t==0 && (*dt=c)) || (t[0]!=0 && (dt=t)) ){
371                 return k.normalkey(c,dt);
372         } else {
373                 return k.deadkey(c,*kmod_list_[(tex_accent)t[1]]);
374         }
378 int Trans::Load(string const &language)
380         string filename = LibFileSearch("kbd", language, "kmap");
381         if (filename.empty())
382                 return -1;
384         FreeKeymap();
385         LyXLex lex(kmapTags, K_LAST-1);
386         lex.setFile(filename);
387         
388         int res=Load(lex);
390         if (res==0) {
391                 name_=language;
392         } else
393                 name_.clear();
395         return res;
399 tex_accent getkeymod(string const &p)
400         /* return modifier - decoded from p and update p */
402         for (int i = 1; i <= TEX_MAX_ACCENT; i++) {
403                 if (lyxerr.debugging(Debug::KBMAP))
404                         lyxerr << "p = " << p
405                                << ", lyx_accent_table[" << i
406                                <<"].name = `" << lyx_accent_table[i].name
407                                << "'" << endl;
408                 
409                 if ( lyx_accent_table[i].name && contains(p, lyx_accent_table[i].name)) {
410                         lyxerr[Debug::KBMAP] << "Found it!" << endl;
411                         return (tex_accent)i;
412                 }
413         }
414         return TEX_NOACCENT;