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