00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ktranslit_p.h>
00020 #include <kdebug.h>
00021
00022 #include <config.h>
00023
00024 #include <QHash>
00025
00026
00027
00028
00029 class KTranslitPrivate
00030 {
00031 };
00032
00033 KTranslit::KTranslit ()
00034 : d(NULL)
00035 {
00036 }
00037
00038 KTranslit::~KTranslit ()
00039 {
00040 delete d;
00041 }
00042
00043 KTranslit *KTranslit::create (const QString &lang)
00044 {
00045 if (lang == QString::fromAscii("sr")) {
00046 return new KTranslitSerbian();
00047 }
00048 else {
00049 return NULL;
00050 }
00051 }
00052
00053 QStringList KTranslit::fallbackList (const QString &lang)
00054 {
00055 QStringList fallbacks;
00056
00057 if ( lang == QString::fromAscii("sr@latin")
00058 || lang == QString::fromAscii("sr@Latn")) {
00059 fallbacks += QString::fromAscii("sr");
00060 }
00061
00062 return fallbacks;
00063 }
00064
00065 void splitLangScript (const QString &lang, QString &ln, QString &scr)
00066 {
00067 ln = lang;
00068 scr.clear();
00069 int pos = lang.indexOf('@');
00070 if (pos >= 0) {
00071 ln = lang.left(pos);
00072 scr = lang.mid(pos + 1);
00073 }
00074 }
00075
00076 QString KTranslit::higherPriorityScript (const QString &lang,
00077 const KLocale *locale)
00078 {
00079 if (locale == NULL) {
00080 return QString();
00081 }
00082
00083
00084 QString ln, scr;
00085 splitLangScript(lang, ln, scr);
00086
00087
00088 QString finalScrHi;
00089 if (lang != KLocale::defaultLanguage()) {
00090 foreach (const QString &langHi, locale->languageList()) {
00091
00092 if (langHi == lang)
00093 break;
00094
00095
00096 QString lnHi, scrHi;
00097 splitLangScript(langHi, lnHi, scrHi);
00098
00099
00100 if (lnHi == ln) {
00101 finalScrHi = scrHi;
00102 break;
00103 }
00104 }
00105 }
00106 return finalScrHi;
00107 }
00108
00109 QString KTranslit::transliterate (const QString &str,
00110 const QString &script) const
00111 {
00112 Q_UNUSED(script);
00113 return str;
00114 }
00115
00116
00117 #define ALTINS_HEAD "~@"
QString KTranslit::resolveInserts (const QString &str_, int nins, int ind) const
{
static QString head(ALTINS_HEAD);
static int hlen = head.length();
QString str = str_;
QString rstr;
while (1) {
int p = str.indexOf(head);
if (p < 0) {
break;
}
// Append segment before optional insert to resulting text.
rstr.append(str.left(p));
// Must have at least 2 characters after the head.
if (str.length() < p + hlen + 2) {
kDebug(173) << QString("Malformed optional inserts list in {%1}, "
00118 "starting here: {%2}").arg(str_, str);
00119 return str_;
00120 }
00121
00122
00123 QChar sep = str[p + hlen];
00124 str.remove(0, p + hlen + 1);
00125
00126
00127
00128 for (int i = 0; i < nins; ++i) {
00129
00130 int p = str.indexOf(sep);
00131
00132
00133 if (p < 0) {
00134 kDebug(173) << QString("Not enough inserts listed in {%1}, "
00135 "starting here: {%2}").arg(str_, str);
00136 return str_;
00137 }
00138
00139
00140 if (i == ind) {
00141 rstr.append(str.left(p));
00142 }
00143
00144
00145 str.remove(0, p + 1);
00146 }
00147 }
00148
00149 rstr.append(str);
00150
00151 return rstr;
00152 }
00153
00154
00155
00156
00157 static int skipInsert (const QString &str, int i, int ninserts)
00158 {
00159 static QString head(ALTINS_HEAD);
00160 static int hlen = head.length();
00161
00162 if (str.mid(i, hlen) == head) {
00163 int slen = str.length();
00164 int ia = i + hlen;
00165 if (ia >= slen) return slen;
00166 QChar sep = str[ia];
00167 for (int k = 0; k < ninserts; ++k) {
00168 ia = str.indexOf(sep, ia + 1);
00169 if (ia < 0) return slen;
00170 }
00171 return ia + 1;
00172 }
00173 else {
00174 return i;
00175 }
00176 }
00177
00178
00179
00180
00181 class KTranslitSerbianPrivate
00182 {
00183 public:
00184 QHash<QString, bool> latinNames;
00185 QHash<QChar, QString> dictC2L;
00186 };
00187
00188 KTranslitSerbian::KTranslitSerbian ()
00189 : d(new KTranslitSerbianPrivate())
00190 {
00191 d->latinNames[QString::fromAscii("latin")] = true;
00192 d->latinNames[QString::fromAscii("Latn")] = true;
00193
00194 #define SR_DICTC2L_ENTRY(a, b) do { \
00195 d->dictC2L[QString::fromUtf8(a)[0]] = QString::fromUtf8(b); \
00196 } while (0)
00197 SR_DICTC2L_ENTRY("а", "a");
00198 SR_DICTC2L_ENTRY("б", "b");
00199 SR_DICTC2L_ENTRY("в", "v");
00200 SR_DICTC2L_ENTRY("г", "g");
00201 SR_DICTC2L_ENTRY("д", "d");
00202 SR_DICTC2L_ENTRY("ђ", "đ");
00203 SR_DICTC2L_ENTRY("е", "e");
00204 SR_DICTC2L_ENTRY("ж", "ž");
00205 SR_DICTC2L_ENTRY("з", "z");
00206 SR_DICTC2L_ENTRY("и", "i");
00207 SR_DICTC2L_ENTRY("ј", "j");
00208 SR_DICTC2L_ENTRY("к", "k");
00209 SR_DICTC2L_ENTRY("л", "l");
00210 SR_DICTC2L_ENTRY("љ", "lj");
00211 SR_DICTC2L_ENTRY("м", "m");
00212 SR_DICTC2L_ENTRY("н", "n");
00213 SR_DICTC2L_ENTRY("њ", "nj");
00214 SR_DICTC2L_ENTRY("о", "o");
00215 SR_DICTC2L_ENTRY("п", "p");
00216 SR_DICTC2L_ENTRY("р", "r");
00217 SR_DICTC2L_ENTRY("с", "s");
00218 SR_DICTC2L_ENTRY("т", "t");
00219 SR_DICTC2L_ENTRY("ћ", "ć");
00220 SR_DICTC2L_ENTRY("у", "u");
00221 SR_DICTC2L_ENTRY("ф", "f");
00222 SR_DICTC2L_ENTRY("х", "h");
00223 SR_DICTC2L_ENTRY("ц", "c");
00224 SR_DICTC2L_ENTRY("ч", "č");
00225 SR_DICTC2L_ENTRY("џ", "dž");
00226 SR_DICTC2L_ENTRY("ш", "š");
00227 SR_DICTC2L_ENTRY("А", "A");
00228 SR_DICTC2L_ENTRY("Б", "B");
00229 SR_DICTC2L_ENTRY("В", "V");
00230 SR_DICTC2L_ENTRY("Г", "G");
00231 SR_DICTC2L_ENTRY("Д", "D");
00232 SR_DICTC2L_ENTRY("Ђ", "Đ");
00233 SR_DICTC2L_ENTRY("Е", "E");
00234 SR_DICTC2L_ENTRY("Ж", "Ž");
00235 SR_DICTC2L_ENTRY("З", "Z");
00236 SR_DICTC2L_ENTRY("И", "I");
00237 SR_DICTC2L_ENTRY("Ј", "J");
00238 SR_DICTC2L_ENTRY("К", "K");
00239 SR_DICTC2L_ENTRY("Л", "L");
00240 SR_DICTC2L_ENTRY("Љ", "Lj");
00241 SR_DICTC2L_ENTRY("М", "M");
00242 SR_DICTC2L_ENTRY("Н", "N");
00243 SR_DICTC2L_ENTRY("Њ", "Nj");
00244 SR_DICTC2L_ENTRY("О", "O");
00245 SR_DICTC2L_ENTRY("П", "P");
00246 SR_DICTC2L_ENTRY("Р", "R");
00247 SR_DICTC2L_ENTRY("С", "S");
00248 SR_DICTC2L_ENTRY("Т", "T");
00249 SR_DICTC2L_ENTRY("Ћ", "Ć");
00250 SR_DICTC2L_ENTRY("У", "U");
00251 SR_DICTC2L_ENTRY("Ф", "F");
00252 SR_DICTC2L_ENTRY("Х", "H");
00253 SR_DICTC2L_ENTRY("Ц", "C");
00254 SR_DICTC2L_ENTRY("Ч", "Č");
00255 SR_DICTC2L_ENTRY("Џ", "Dž");
00256 SR_DICTC2L_ENTRY("Ш", "Š");
00257 }
00258
00259 KTranslitSerbian::~KTranslitSerbian ()
00260 {
00261 delete d;
00262 }
00263
00264 QString KTranslitSerbian::transliterate (const QString &str,
00265 const QString &script) const
00266 {
00267 static QString insHead(ALTINS_HEAD);
00268
00269 if (d->latinNames.contains(script)) {
00270
00271 int slen = str.length();
00272 bool anyInserts = str.indexOf(insHead) >= 0;
00273 QString nstr;
00274 nstr.reserve(slen + 5);
00275 for (int i = 0; i < slen; ++i) {
00276
00277
00278 if (anyInserts) {
00279 int to = skipInsert(str, i, 2);
00280 if (to > i) {
00281 nstr.append(str.mid(i, to - i));
00282 if (to >= slen) break;
00283 i = to;
00284 }
00285 }
00286
00287 QChar c = str[i];
00288 QString r = d->dictC2L[c];
00289 if (!r.isEmpty()) {
00290 if ( r.length() > 1 && c.isUpper()
00291 && ( (i + 1 < slen && str[i + 1].isUpper())
00292 || (i > 0 && str[i - 1].isUpper()))) {
00293 nstr.append(r.toUpper());
00294 }
00295 else {
00296 nstr.append(r);
00297 }
00298 }
00299 else {
00300 nstr.append(c);
00301 }
00302 }
00303 nstr = resolveInserts(nstr, 2, 1);
00304 return nstr;
00305 }
00306 else {
00307 QString nstr = resolveInserts(str, 2, 0);
00308 return nstr;
00309 }
00310 }
00311