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