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 "trans_mgr.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(LyXLex & lex)
133 while (lex.isOK() && !error) {
137 if (lyxerr.debugging(Debug::KBMAP))
138 lyxerr << "KMOD:\t" << lex.getString() << endl;
139 if (lex.next(true)) {
140 if (lyxerr.debugging(Debug::KBMAP))
141 lyxerr << "key\t`" << lex.getString()
146 docstring const keys = lex.getDocString();
148 if (lex.next(true)) {
149 if (lyxerr.debugging(Debug::KBMAP))
150 lyxerr << "accent\t`" << lex.getString()
155 tex_accent accent = getkeymod(lex.getString());
157 if (accent == TEX_NOACCENT)
161 //#warning This code should be removed...
162 // But we need to fix up all the kmap files first
163 // so that this field is not present anymore.
164 if (lex.next(true)) {
165 if (lyxerr.debugging(Debug::KBMAP))
166 lyxerr << "allowed\t`" << lex.getString()
171 /* string const allowed = lex.getString(); */
172 addDeadkey(accent, keys /*, allowed*/);
174 addDeadkey(accent, keys);
181 lyxerr[Debug::KBMAP] << "KCOMB:" << endl;
182 if (lex.next(true)) {
183 str = lex.getString();
184 lyxerr[Debug::KBMAP] << str << endl;
188 tex_accent accent_1 = getkeymod(str);
189 if (accent_1 == TEX_NOACCENT) return -1;
191 if (lex.next(true)) {
192 str = lex.getString();
193 lyxerr[Debug::KBMAP] << str << endl;
197 tex_accent accent_2= getkeymod(str);
198 if (accent_2 == TEX_NOACCENT) return -1;
200 map<tex_accent, KmodInfo>::iterator it1 =
201 kmod_list_.find(accent_1);
202 map<tex_accent, KmodInfo>::iterator it2 =
203 kmod_list_.find(accent_2);
204 if (it1 == kmod_list_.end()
205 || it2 == kmod_list_.end()) {
209 // Find what key accent_2 is on - should
210 // check about accent_1 also
211 map<char_type, docstring>::iterator it = keymap_.begin();
212 map<char_type, docstring>::iterator end = keymap_.end();
213 for (; it != end; ++it) {
214 if (!it->second.empty()
215 && it->second[0] == 0
216 && it->second[1] == accent_2)
221 allowed = lex.getDocString();
222 lyxerr[Debug::KBMAP] << "allowed: "
223 << to_utf8(allowed) << endl;
228 insertException(kmod_list_[accent_1].exception_list,
234 unsigned char key_from;
236 if (lyxerr.debugging(Debug::KBMAP))
237 lyxerr << "KMAP:\t" << lex.getString() << endl;
238 if (lex.next(true)) {
239 key_from = lex.getString()[0];
240 if (lyxerr.debugging(Debug::KBMAP))
241 lyxerr << "\t`" << lex.getString() << '\''
246 if (lex.next(true)) {
247 docstring const string_to = lex.getDocString();
248 keymap_[key_from] = string_to;
249 if (lyxerr.debugging(Debug::KBMAP))
250 lyxerr << "\t`" << to_utf8(string_to) << '\''
262 if (lyxerr.debugging(Debug::KBMAP))
263 lyxerr << "KXMOD:\t" << lex.getString() << endl;
264 if (lex.next(true)) {
265 if (lyxerr.debugging(Debug::KBMAP))
266 lyxerr << "\t`" << lex.getString() << '\''
268 accent = getkeymod(lex.getString());
272 if (lex.next(true)) {
273 if (lyxerr.debugging(Debug::KBMAP))
274 lyxerr << "\t`" << lex.getString() << '\''
276 key = lex.getDocString()[0];
280 if (lex.next(true)) {
281 if (lyxerr.debugging(Debug::KBMAP))
282 lyxerr << "\t`" << lex.getString() << '\''
284 str = lex.getDocString();
288 insertException(kmod_list_[accent].exception_list,
292 case LyXLex::LEX_FEOF:
293 lyxerr[Debug::PARSER] << "End of parsing" << endl;
296 lex.printError("ParseKeymapFile: "
297 "Unknown tag: `$$Token'");
305 bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i) const
307 map<tex_accent, KmodInfo>::const_iterator cit = kmod_list_.find(accent);
308 if (cit != kmod_list_.end()) {
316 docstring const Trans::process(char_type c, TransManager & k)
318 docstring const t = match(c);
320 if (t.empty() && c != 0) {
321 return k.normalkey(c);
322 } else if (!t.empty() && t[0] != 0) {
323 //return k.normalkey(c);
327 kmod_list_[static_cast<tex_accent>(t[1])]);
332 int Trans::load(string const & language)
334 support::FileName const filename = libFileSearch("kbd", language, "kmap");
335 if (filename.empty())
339 LyXLex lex(kmapTags, K_LAST - 1);
340 lex.setFile(filename);
342 int const res = load(lex);
353 tex_accent getkeymod(string const & p)
354 /* return modifier - decoded from p and update p */
356 for (int i = 1; i <= TEX_MAX_ACCENT; ++i) {
357 if (lyxerr.debugging(Debug::KBMAP))
358 lyxerr << "p = " << p
359 << ", lyx_accent_table[" << i
360 << "].name = `" << lyx_accent_table[i].name
363 if (lyx_accent_table[i].name
364 && contains(p, lyx_accent_table[i].name)) {
365 lyxerr[Debug::KBMAP] << "Found it!" << endl;
366 return static_cast<tex_accent>(i);