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