2003-08-23 00:17:00 +00:00
|
|
|
|
/**
|
|
|
|
|
* \file trans.C
|
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
|
*
|
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
* \author Matthias Ettrich
|
|
|
|
|
*
|
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
|
*/
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include "trans.h"
|
1999-10-02 16:21:10 +00:00
|
|
|
|
#include "support/filetools.h"
|
2001-07-29 17:39:01 +00:00
|
|
|
|
#include "support/lstrings.h"
|
1999-09-27 18:44:28 +00:00
|
|
|
|
#include "lyxlex.h"
|
1999-10-07 18:44:17 +00:00
|
|
|
|
#include "debug.h"
|
1999-09-27 18:44:28 +00:00
|
|
|
|
#include "trans_mgr.h"
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
|
|
using support::contains;
|
|
|
|
|
using support::libFileSearch;
|
2003-06-30 23:56:22 +00:00
|
|
|
|
|
2000-03-28 02:18:55 +00:00
|
|
|
|
using std::endl;
|
2003-10-06 15:43:21 +00:00
|
|
|
|
using std::string;
|
2003-09-09 22:13:45 +00:00
|
|
|
|
using std::map;
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// KmodInfo
|
|
|
|
|
KmodInfo::KmodInfo()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Trans class
|
|
|
|
|
|
|
|
|
|
Trans::Trans()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Trans::~Trans()
|
|
|
|
|
{
|
2006-04-09 00:26:19 +00:00
|
|
|
|
freeKeymap();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-03-31 08:12:08 +00:00
|
|
|
|
void Trans::insertException(KmodException & exclist, char_type c,
|
|
|
|
|
docstring const & data, bool flag, tex_accent accent)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-07-16 15:42:57 +00:00
|
|
|
|
Keyexc p;
|
|
|
|
|
p.c = c;
|
|
|
|
|
p.data = data;
|
|
|
|
|
p.combined = flag;
|
|
|
|
|
p.accent = accent;
|
|
|
|
|
exclist.insert(exclist.begin(), p);
|
|
|
|
|
// or just
|
|
|
|
|
// exclist.push_back(p);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
void Trans::freeException(KmodException & exclist)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-07-16 15:42:57 +00:00
|
|
|
|
exclist.clear();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
void Trans::freeKeymap()
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-07-16 15:42:57 +00:00
|
|
|
|
kmod_list_.clear();
|
|
|
|
|
keymap_.clear();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
bool Trans::isDefined() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
|
|
|
|
return !name_.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
string const & Trans::getName() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
|
|
|
|
return name_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-10-30 21:53:29 +00:00
|
|
|
|
enum kmaptags_ {
|
1999-11-15 12:01:38 +00:00
|
|
|
|
KCOMB = 1,
|
1999-09-27 18:44:28 +00:00
|
|
|
|
KMOD,
|
|
|
|
|
KMAP,
|
|
|
|
|
KXMOD,
|
|
|
|
|
K_LAST
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
1999-12-16 06:43:25 +00:00
|
|
|
|
struct keyword_item kmapTags[K_LAST - 1] = {
|
1999-11-15 12:01:38 +00:00
|
|
|
|
{"\\kcomb", KCOMB },
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{ "\\kmap", KMAP },
|
|
|
|
|
{ "\\kmod", KMOD },
|
|
|
|
|
{ "\\kxmod", KXMOD }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
tex_accent getkeymod(string const &);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
|
2007-03-31 08:12:08 +00:00
|
|
|
|
void Trans::addDeadkey(tex_accent accent, docstring const & keys)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-07-16 15:42:57 +00:00
|
|
|
|
KmodInfo tmp;
|
|
|
|
|
tmp.data = keys;
|
|
|
|
|
tmp.accent = accent;
|
|
|
|
|
kmod_list_[accent] = tmp;
|
|
|
|
|
|
2007-03-31 08:12:08 +00:00
|
|
|
|
for (docstring::size_type i = 0; i < keys.length(); ++i) {
|
|
|
|
|
// FIXME This is a hack.
|
|
|
|
|
// tmp is no valid UCS4 string, but misused to store the
|
|
|
|
|
// accent.
|
|
|
|
|
docstring tmp;
|
|
|
|
|
tmp += char_type(0);
|
|
|
|
|
tmp += char_type(accent);
|
2001-07-16 15:42:57 +00:00
|
|
|
|
keymap_[keys[i]] = tmp;
|
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
int Trans::load(LyXLex & lex)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
|
|
|
|
bool error = false;
|
|
|
|
|
|
2001-08-06 19:12:46 +00:00
|
|
|
|
while (lex.isOK() && !error) {
|
2000-11-04 10:00:12 +00:00
|
|
|
|
switch (lex.lex()) {
|
1999-09-27 18:44:28 +00:00
|
|
|
|
case KMOD:
|
|
|
|
|
{
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "KMOD:\t" << lex.getString() << endl;
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (lex.next(true)) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "key\t`" << lex.getString()
|
|
|
|
|
<< '\'' << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-03-31 08:12:08 +00:00
|
|
|
|
docstring const keys = lex.getDocString();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
if (lex.next(true)) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "accent\t`" << lex.getString()
|
2002-11-27 10:30:28 +00:00
|
|
|
|
<< '\'' << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
2001-08-06 19:12:46 +00:00
|
|
|
|
tex_accent accent = getkeymod(lex.getString());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
if (accent == TEX_NOACCENT)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
return -1;
|
|
|
|
|
|
2001-07-12 11:11:10 +00:00
|
|
|
|
#if 1
|
2001-09-09 22:02:19 +00:00
|
|
|
|
//#warning This code should be removed...
|
2001-07-12 11:11:10 +00:00
|
|
|
|
// But we need to fix up all the kmap files first
|
|
|
|
|
// so that this field is not present anymore.
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (lex.next(true)) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "allowed\t`" << lex.getString()
|
2002-11-27 10:30:28 +00:00
|
|
|
|
<< '\'' << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
2002-01-14 12:56:05 +00:00
|
|
|
|
/* string const allowed = lex.getString(); */
|
2006-04-09 00:26:19 +00:00
|
|
|
|
addDeadkey(accent, keys /*, allowed*/);
|
2001-07-12 11:11:10 +00:00
|
|
|
|
#else
|
2006-04-09 00:26:19 +00:00
|
|
|
|
addDeadkey(accent, keys);
|
2001-07-12 11:11:10 +00:00
|
|
|
|
#endif
|
1999-09-27 18:44:28 +00:00
|
|
|
|
break;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
case KCOMB: {
|
2000-09-14 17:53:12 +00:00
|
|
|
|
string str;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "KCOMB:" << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (lex.next(true)) {
|
2003-04-14 13:12:40 +00:00
|
|
|
|
str = lex.getString();
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << str << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
1999-12-13 00:05:34 +00:00
|
|
|
|
tex_accent accent_1 = getkeymod(str);
|
1999-11-15 12:01:38 +00:00
|
|
|
|
if (accent_1 == TEX_NOACCENT) return -1;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
if (lex.next(true)) {
|
2003-04-14 13:12:40 +00:00
|
|
|
|
str = lex.getString();
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << str << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
tex_accent accent_2= getkeymod(str);
|
|
|
|
|
if (accent_2 == TEX_NOACCENT) return -1;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-03-31 08:12:08 +00:00
|
|
|
|
map<tex_accent, KmodInfo>::iterator it1 =
|
2001-07-16 15:42:57 +00:00
|
|
|
|
kmod_list_.find(accent_1);
|
2007-03-31 08:12:08 +00:00
|
|
|
|
map<tex_accent, KmodInfo>::iterator it2 =
|
2001-07-16 15:42:57 +00:00
|
|
|
|
kmod_list_.find(accent_2);
|
|
|
|
|
if (it1 == kmod_list_.end()
|
|
|
|
|
|| it2 == kmod_list_.end()) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
1999-12-13 00:05:34 +00:00
|
|
|
|
// Find what key accent_2 is on - should
|
|
|
|
|
// check about accent_1 also
|
2007-03-31 08:12:08 +00:00
|
|
|
|
map<char_type, docstring>::iterator it = keymap_.begin();
|
|
|
|
|
map<char_type, docstring>::iterator end = keymap_.end();
|
2001-07-16 15:42:57 +00:00
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
|
if (!it->second.empty()
|
|
|
|
|
&& it->second[0] == 0
|
|
|
|
|
&& it->second[1] == accent_2)
|
|
|
|
|
break;
|
|
|
|
|
}
|
2007-03-31 08:12:08 +00:00
|
|
|
|
docstring allowed;
|
2001-07-16 15:42:57 +00:00
|
|
|
|
if (lex.next()) {
|
2007-03-31 08:12:08 +00:00
|
|
|
|
allowed = lex.getDocString();
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "allowed: "
|
2007-03-31 08:12:08 +00:00
|
|
|
|
<< to_utf8(allowed) << endl;
|
2001-07-16 15:42:57 +00:00
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
insertException(kmod_list_[accent_1].exception_list,
|
2007-03-31 08:12:08 +00:00
|
|
|
|
it->first, allowed,
|
2001-07-16 15:42:57 +00:00
|
|
|
|
true, accent_2);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case KMAP: {
|
1999-12-10 00:07:59 +00:00
|
|
|
|
unsigned char key_from;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "KMAP:\t" << lex.getString() << endl;
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (lex.next(true)) {
|
2003-04-14 13:12:40 +00:00
|
|
|
|
key_from = lex.getString()[0];
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
|
|
|
|
|
<< endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
if (lex.next(true)) {
|
2007-03-31 08:12:08 +00:00
|
|
|
|
docstring const string_to = lex.getDocString();
|
1999-11-15 12:01:38 +00:00
|
|
|
|
keymap_[key_from] = string_to;
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "\t`" << to_utf8(string_to) << '\''
|
|
|
|
|
<< endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case KXMOD: {
|
|
|
|
|
tex_accent accent;
|
2007-03-31 08:12:08 +00:00
|
|
|
|
char_type key;
|
|
|
|
|
docstring str;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "KXMOD:\t" << lex.getString() << endl;
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (lex.next(true)) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
|
|
|
|
|
<< endl;
|
2001-08-06 19:12:46 +00:00
|
|
|
|
accent = getkeymod(lex.getString());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
if (lex.next(true)) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
|
|
|
|
|
<< endl;
|
2007-03-31 08:12:08 +00:00
|
|
|
|
key = lex.getDocString()[0];
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
if (lex.next(true)) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "\t`" << lex.getString() << '\''
|
|
|
|
|
<< endl;
|
2007-03-31 08:12:08 +00:00
|
|
|
|
str = lex.getDocString();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
|
|
|
|
return -1;
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
insertException(kmod_list_[accent].exception_list,
|
1999-12-16 06:43:25 +00:00
|
|
|
|
key, str);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case LyXLex::LEX_FEOF:
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::PARSER) << "End of parsing" << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
lex.printError("ParseKeymapFile: "
|
|
|
|
|
"Unknown tag: `$$Token'");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-09-14 17:53:12 +00:00
|
|
|
|
bool Trans::isAccentDefined(tex_accent accent, KmodInfo & i) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-03-31 08:12:08 +00:00
|
|
|
|
map<tex_accent, KmodInfo>::const_iterator cit = kmod_list_.find(accent);
|
2001-07-16 15:42:57 +00:00
|
|
|
|
if (cit != kmod_list_.end()) {
|
|
|
|
|
i = cit->second;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-03-31 08:12:08 +00:00
|
|
|
|
docstring const Trans::process(char_type c, TransManager & k)
|
2001-07-07 17:52:03 +00:00
|
|
|
|
{
|
2007-03-31 08:12:08 +00:00
|
|
|
|
docstring const t = match(c);
|
2001-07-07 17:52:03 +00:00
|
|
|
|
|
|
|
|
|
if (t.empty() && c != 0) {
|
|
|
|
|
return k.normalkey(c);
|
2007-03-31 08:12:08 +00:00
|
|
|
|
} else if (!t.empty() && t[0] != 0) {
|
2001-07-16 15:42:57 +00:00
|
|
|
|
//return k.normalkey(c);
|
|
|
|
|
return t;
|
2001-07-07 17:52:03 +00:00
|
|
|
|
} else {
|
2001-07-16 15:42:57 +00:00
|
|
|
|
return k.deadkey(c,
|
|
|
|
|
kmod_list_[static_cast<tex_accent>(t[1])]);
|
2001-07-07 17:52:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
int Trans::load(string const & language)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2006-11-26 21:30:39 +00:00
|
|
|
|
support::FileName const filename = libFileSearch("kbd", language, "kmap");
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (filename.empty())
|
|
|
|
|
return -1;
|
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
freeKeymap();
|
2002-08-23 11:47:03 +00:00
|
|
|
|
LyXLex lex(kmapTags, K_LAST - 1);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
lex.setFile(filename);
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2006-04-09 00:26:19 +00:00
|
|
|
|
int const res = load(lex);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
if (res == 0) {
|
|
|
|
|
name_ = language;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else
|
2000-05-04 10:57:00 +00:00
|
|
|
|
name_.erase();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
tex_accent getkeymod(string const & p)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
/* return modifier - decoded from p and update p */
|
|
|
|
|
{
|
1999-11-15 12:01:38 +00:00
|
|
|
|
for (int i = 1; i <= TEX_MAX_ACCENT; ++i) {
|
2007-04-01 14:44:10 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "p = " << p
|
|
|
|
|
<< ", lyx_accent_table[" << i
|
|
|
|
|
<< "].name = `" << lyx_accent_table[i].name
|
|
|
|
|
<< '\'' << endl;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2000-11-04 10:00:12 +00:00
|
|
|
|
if (lyx_accent_table[i].name
|
1999-12-16 06:43:25 +00:00
|
|
|
|
&& contains(p, lyx_accent_table[i].name)) {
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::KBMAP) << "Found it!" << endl;
|
1999-12-13 00:05:34 +00:00
|
|
|
|
return static_cast<tex_accent>(i);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return TEX_NOACCENT;
|
|
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace lyx
|