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