9 #include "support/filetools.h"
10 #include "tex-strings.h"
13 #include "trans_mgr.h"
26 bool DefaultTrans::init_ = false;
29 DefaultTrans::DefaultTrans()
39 string const DefaultTrans::process(char c, TransManager & k)
44 return k.normalkey(c, dummy);
47 string const DefaultTrans::process(char c, TransManager & k)
49 return k.normalkey(c);
58 for (int i = 0; i < TEX_MAX_ACCENT + 1; ++i)
69 void Trans::InsertException(Trans::keyexc & exclist, char c,
70 string const & data, bool flag, tex_accent accent)
72 keyexc p = new Keyexc;
84 void Trans::FreeException(Trans::keyexc & exclist)
86 Trans::keyexc p = exclist;
95 void Trans::FreeKeymap()
97 for (int i = 0; i < 256; ++i)
98 if (!keymap_[i].empty()) {
101 for (int i = 0; i < TEX_MAX_ACCENT + 1; ++i)
103 FreeException(kmod_list_[i]->exception_list);
104 delete kmod_list_[i];
110 bool Trans::IsDefined() const
112 return !name_.empty();
116 string const & Trans::GetName() const
131 struct keyword_item kmapTags[K_LAST - 1] = {
139 tex_accent getkeymod(string const &);
143 void Trans::AddDeadkey(tex_accent accent, string const & keys,
144 string const & allowed)
146 void Trans::AddDeadkey(tex_accent accent, string const & keys)
149 if (kmod_list_[accent]) {
150 FreeException(kmod_list_[accent]->exception_list);
152 delete kmod_list_[accent];
155 kmod_list_[accent] = new kmod_list_decl;
156 kmod_list_[accent]->data = keys;
157 kmod_list_[accent]->accent = accent;
159 if (allowed == "native") {
160 kmod_list_[accent]->allowed= lyx_accent_table[accent].native;
164 kmod_list_[accent]->allowed = allowed;
170 for (string::size_type i = 0; i < keys.length(); ++i) {
172 keymap_[static_cast<unsigned char>(keys[i])];
176 // But the question remains: "Should we be allowed
177 // to change bindings, without unbinding first?"
180 temp += char(accent);
182 kmod_list_[accent]->exception_list = 0;
186 int Trans::Load(LyXLex & lex)
190 while (lex.IsOK() && !error) {
194 if (lyxerr.debugging(Debug::KBMAP))
195 lyxerr << "KMOD:\t" << lex.text() << endl;
196 if (lex.next(true)) {
197 if (lyxerr.debugging(Debug::KBMAP))
198 lyxerr << "key\t`" << lex.text()
203 string const keys = lex.GetString();
205 if (lex.next(true)) {
206 if (lyxerr.debugging(Debug::KBMAP))
207 lyxerr << "accent\t`" << lex.text()
212 tex_accent accent = getkeymod(lex.GetString());
214 if (accent == TEX_NOACCENT)
218 #warning This code should be removed...
219 // But we need to fix up all the kmap files first
220 // so that this field is not present anymore.
221 if (lex.next(true)) {
222 if (lyxerr.debugging(Debug::KBMAP))
223 lyxerr << "allowed\t`" << lex.text()
228 string const allowed = lex.GetString();
229 AddDeadkey(accent, keys /*, allowed*/);
231 AddDeadkey(accent, keys);
238 lyxerr[Debug::KBMAP] << "KCOMB:" << endl;
239 if (lex.next(true)) {
241 lyxerr[Debug::KBMAP] << str << endl;
245 tex_accent accent_1 = getkeymod(str);
246 if (accent_1 == TEX_NOACCENT) return -1;
248 if (lex.next(true)) {
250 lyxerr[Debug::KBMAP] << str << endl;
254 tex_accent accent_2= getkeymod(str);
255 if (accent_2 == TEX_NOACCENT) return -1;
257 if (kmod_list_[accent_1] == 0
258 || kmod_list_[accent_2] == 0)
261 // Find what key accent_2 is on - should
262 // check about accent_1 also
264 for (; key < 256; ++key) {
265 if (!keymap_[key].empty()
266 && keymap_[key][0] == 0
267 && keymap_[key][1] == accent_2)
273 allowed = lex.GetString();
274 lyxerr[Debug::KBMAP] << "allowed: "
279 InsertException(kmod_list_[accent_1]->exception_list,
280 static_cast<char>(key), allowed,
285 unsigned char key_from;
287 if (lyxerr.debugging(Debug::KBMAP))
288 lyxerr << "KMAP:\t" << lex.text() << endl;
289 if (lex.next(true)) {
290 key_from = lex.text()[0];
291 if (lyxerr.debugging(Debug::KBMAP))
292 lyxerr << "\t`" << lex.text() << "'"
297 if (lex.next(true)) {
298 string string_to = lex.text();
300 // strcpy(new char[strlen(t)+1], t);
301 keymap_[key_from] = string_to;
302 if (lyxerr.debugging(Debug::KBMAP))
303 lyxerr << "\t`" << string_to << "'"
315 if (lyxerr.debugging(Debug::KBMAP))
316 lyxerr << "KXMOD:\t" << lex.text() << endl;
317 if (lex.next(true)) {
318 if (lyxerr.debugging(Debug::KBMAP))
319 lyxerr << "\t`" << lex.text() << "'"
321 accent = getkeymod(lex.GetString());
325 if (lex.next(true)) {
326 if (lyxerr.debugging(Debug::KBMAP))
327 lyxerr << "\t`" << lex.text() << "'"
333 if (lex.next(true)) {
334 if (lyxerr.debugging(Debug::KBMAP))
335 lyxerr << "\t`" << lex.text() << "'"
341 InsertException(kmod_list_[accent]->exception_list,
345 case LyXLex::LEX_FEOF:
346 lyxerr[Debug::PARSER] << "End of parsing" << endl;
349 lex.printError("ParseKeymapFile: "
350 "Unknown tag: `$$Token'");
358 bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i) const
360 if (kmod_list_[accent] != 0) {
361 i = *kmod_list_[accent];
369 string const Trans::process(char c, TransManager & k)
372 string const t = Match(static_cast<unsigned char>(c));
374 if (t.empty() && c != 0) {
376 return k.normalkey(c, dt);
377 } else if (!t.empty() && t[0] != char(0)) {
379 return k.normalkey(c, dt);
382 *kmod_list_[static_cast<tex_accent>(t[1])]);
386 string const Trans::process(char c, TransManager & k)
388 string const t = Match(static_cast<unsigned char>(c));
390 if (t.empty() && c != 0) {
391 return k.normalkey(c);
392 } else if (!t.empty() && t[0] != char(0)) {
393 return k.normalkey(c);
396 *kmod_list_[static_cast<tex_accent>(t[1])]);
402 int Trans::Load(string const & language)
404 string const filename = LibFileSearch("kbd", language, "kmap");
405 if (filename.empty())
409 LyXLex lex(kmapTags, K_LAST-1);
410 lex.setFile(filename);
412 int const res = Load(lex);
423 tex_accent getkeymod(string const & p)
424 /* return modifier - decoded from p and update p */
426 for (int i = 1; i <= TEX_MAX_ACCENT; ++i) {
427 if (lyxerr.debugging(Debug::KBMAP))
428 lyxerr << "p = " << p
429 << ", lyx_accent_table[" << i
430 << "].name = `" << lyx_accent_table[i].name
433 if (lyx_accent_table[i].name
434 && contains(p, lyx_accent_table[i].name)) {
435 lyxerr[Debug::KBMAP] << "Found it!" << endl;
436 return static_cast<tex_accent>(i);