3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
7 * \author Matthias Ettrich
9 * Full author contact details are available in file CREDITS.
15 #include "support/filetools.h"
16 #include "support/lstrings.h"
19 #include "TransState.h"
24 using support::contains;
25 using support::libFileSearch;
51 void Trans::insertException(KmodException & exclist, char_type c,
52 docstring const & data, bool flag, tex_accent accent)
59 exclist.insert(exclist.begin(), p);
61 // exclist.push_back(p);
65 void Trans::freeException(KmodException & exclist)
71 void Trans::freeKeymap()
78 bool Trans::isDefined() const
80 return !name_.empty();
84 string const & Trans::getName() const
99 struct keyword_item kmapTags[K_LAST - 1] = {
107 tex_accent getkeymod(string const &);
110 void Trans::addDeadkey(tex_accent accent, docstring const & keys)
115 kmod_list_[accent] = tmp;
117 for (docstring::size_type i = 0; i < keys.length(); ++i) {
118 // FIXME This is a hack.
119 // tmp is no valid UCS4 string, but misused to store the
123 tmp += char_type(accent);
124 keymap_[keys[i]] = tmp;
129 int Trans::load(Lexer & lex)
133 while (lex.isOK() && !error) {
137 LYXERR(Debug::KBMAP) << "KMOD:\t" << lex.getString() << endl;
139 if (lex.next(true)) {
140 LYXERR(Debug::KBMAP) << "key\t`" << lex.getString()
145 docstring const keys = lex.getDocString();
147 if (lex.next(true)) {
148 LYXERR(Debug::KBMAP) << "accent\t`" << lex.getString()
153 tex_accent accent = getkeymod(lex.getString());
155 if (accent == TEX_NOACCENT)
159 //#warning This code should be removed...
160 // But we need to fix up all the kmap files first
161 // so that this field is not present anymore.
162 if (lex.next(true)) {
163 LYXERR(Debug::KBMAP) << "allowed\t`" << lex.getString()
168 /* string const allowed = lex.getString(); */
169 addDeadkey(accent, keys /*, allowed*/);
171 addDeadkey(accent, keys);
178 LYXERR(Debug::KBMAP) << "KCOMB:" << endl;
179 if (lex.next(true)) {
180 str = lex.getString();
181 LYXERR(Debug::KBMAP) << str << endl;
185 tex_accent accent_1 = getkeymod(str);
186 if (accent_1 == TEX_NOACCENT) return -1;
188 if (lex.next(true)) {
189 str = lex.getString();
190 LYXERR(Debug::KBMAP) << str << endl;
194 tex_accent accent_2= getkeymod(str);
195 if (accent_2 == TEX_NOACCENT) return -1;
197 map<tex_accent, KmodInfo>::iterator it1 =
198 kmod_list_.find(accent_1);
199 map<tex_accent, KmodInfo>::iterator it2 =
200 kmod_list_.find(accent_2);
201 if (it1 == kmod_list_.end()
202 || it2 == kmod_list_.end()) {
206 // Find what key accent_2 is on - should
207 // check about accent_1 also
208 map<char_type, docstring>::iterator it = keymap_.begin();
209 map<char_type, docstring>::iterator end = keymap_.end();
210 for (; it != end; ++it) {
211 if (!it->second.empty()
212 && it->second[0] == 0
213 && it->second[1] == accent_2)
218 allowed = lex.getDocString();
219 LYXERR(Debug::KBMAP) << "allowed: "
220 << to_utf8(allowed) << endl;
225 insertException(kmod_list_[accent_1].exception_list,
231 unsigned char key_from;
233 LYXERR(Debug::KBMAP) << "KMAP:\t" << lex.getString() << endl;
235 if (lex.next(true)) {
236 key_from = lex.getString()[0];
237 LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
242 if (lex.next(true)) {
243 docstring const string_to = lex.getDocString();
244 keymap_[key_from] = string_to;
245 LYXERR(Debug::KBMAP) << "\t`" << to_utf8(string_to) << '\''
257 LYXERR(Debug::KBMAP) << "KXMOD:\t" << lex.getString() << endl;
259 if (lex.next(true)) {
260 LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
262 accent = getkeymod(lex.getString());
266 if (lex.next(true)) {
267 LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
269 key = lex.getDocString()[0];
273 if (lex.next(true)) {
274 LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
276 str = lex.getDocString();
280 insertException(kmod_list_[accent].exception_list,
284 case Lexer::LEX_FEOF:
285 LYXERR(Debug::PARSER) << "End of parsing" << endl;
288 lex.printError("ParseKeymapFile: "
289 "Unknown tag: `$$Token'");
297 bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i) const
299 map<tex_accent, KmodInfo>::const_iterator cit = kmod_list_.find(accent);
300 if (cit != kmod_list_.end()) {
308 docstring const Trans::process(char_type c, TransManager & k)
310 docstring const t = match(c);
312 if (t.empty() && c != 0) {
313 return k.normalkey(c);
314 } else if (!t.empty() && t[0] != 0) {
315 //return k.normalkey(c);
319 kmod_list_[static_cast<tex_accent>(t[1])]);
324 int Trans::load(string const & language)
326 support::FileName const filename = libFileSearch("kbd", language, "kmap");
327 if (filename.empty())
331 Lexer lex(kmapTags, K_LAST - 1);
332 lex.setFile(filename);
334 int const res = load(lex);
345 tex_accent getkeymod(string const & p)
346 /* return modifier - decoded from p and update p */
348 for (int i = 1; i <= TEX_MAX_ACCENT; ++i) {
349 LYXERR(Debug::KBMAP) << "p = " << p
350 << ", lyx_accent_table[" << i
351 << "].name = `" << lyx_accent_table[i].name
354 if (lyx_accent_table[i].name
355 && contains(p, lyx_accent_table[i].name)) {
356 LYXERR(Debug::KBMAP) << "Found it!" << endl;
357 return static_cast<tex_accent>(i);