+typedef map<string, string> AccentsMap;
+static AccentsMap accents = map<string, string>();
+
+static void buildaccent(string n, string param, string values)
+{
+ stringstream s(n);
+ string name;
+ const char delim = '|';
+ while (getline(s, name, delim)) {
+ size_t start = 0;
+ for (size_t i = 0; i < param.size(); i++) {
+ string key = name + "{" + param[i] + "}";
+ // get the corresponding utf8-value
+ if ((values[start] & 0xc0) != 0xc0) {
+ // should not happen, utf8 encoding starts at least with 11xxxxxx
+ // but value for '\dot{i}' is 'i', which is ascii
+ if ((values[start] & 0x80) == 0) {
+ // is ascii
+ accents[key] = values.substr(start, 1);
+ // LYXERR(Debug::INFO, "" << key << "=" << accents[key]);
+ }
+ start++;
+ continue;
+ }
+ for (int j = 1; ;j++) {
+ if (start + j >= values.size()) {
+ accents[key] = values.substr(start, j);
+ start = values.size() - 1;
+ break;
+ }
+ else if ((values[start+j] & 0xc0) != 0x80) {
+ // This is the first byte of following utf8 char
+ accents[key] = values.substr(start, j);
+ start += j;
+ // LYXERR(Debug::INFO, "" << key << "=" << accents[key]);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void buildAccentsMap()
+{
+ accents["imath"] = "ı";
+ accents["i"] = "ı";
+ accents["jmath"] = "ȷ";
+ accents["lyxmathsym{ß}"] = "ß";
+ accents["text{ß}"] = "ß";
+ accents["ddot{\\imath}"] = "ï";
+ buildaccent("ddot", "aAeEhHiIioOtuUwWxXyY",
+ "äÄëËḧḦïÏïöÖẗüÜẅẄẍẌÿŸ"); // umlaut
+ buildaccent("dot|.", "aAbBcCdDeEfFGghHIimMnNoOpPrRsStTwWxXyYzZ",
+ "ȧȦḃḂċĊḋḊėĖḟḞĠġḣḢİİṁṀṅṄȯȮṗṖṙṘṡṠṫṪẇẆẋẊẏẎżŻ"); // dot{i} can only happen if ignoring case, but there is no lowercase of 'İ'
+ accents["acute{\\imath}"] = "í";
+ buildaccent("acute", "aAcCeEgGkKlLmMoOnNpPrRsSuUwWyYzZiI",
+ "áÁćĆéÉǵǴḱḰĺĹḿḾóÓńŃṕṔŕŔśŚúÚẃẂýÝźŹíÍ");
+ buildaccent("dacute|H|h", "oOuU", "őŐűŰ"); // double acute
+ buildaccent("mathring|r", "aAuUwy",
+ "åÅůŮẘẙ"); // ring
+ accents["check{\\imath}"] = "ǐ";
+ accents["check{\\jmath}"] = "ǰ";
+ buildaccent("check|v", "cCdDaAeEiIoOuUgGkKhHlLnNrRsSTtzZ",
+ "čČďĎǎǍěĚǐǏǒǑǔǓǧǦǩǨȟȞľĽňŇřŘšŠŤťžŽ"); // caron
+ accents["hat{\\imath}"] = "î";
+ accents["hat{\\jmath}"] = "ĵ";
+ buildaccent("hat|^", "aAcCeEgGhHiIjJoOsSuUwWyYzZ",
+ "âÂĉĈêÊĝĜĥĤîÎĵĴôÔŝŜûÛŵŴŷŶẑẐ"); // circ
+ accents["bar{\\imath}"] = "ī";
+ buildaccent("bar|=", "aAeEiIoOuUyY",
+ "āĀēĒīĪōŌūŪȳȲ"); // macron
+ accents["tilde{\\imath}"] = "ĩ";
+ buildaccent("tilde", "aAeEiInNoOuUvVyY",
+ "ãÃẽẼĩĨñÑõÕũŨṽṼỹỸ"); // tilde
+ accents["breve{\\imath}"] = "ĭ";
+ buildaccent("breve|u", "aAeEgGiIoOuU",
+ "ăĂĕĔğĞĭĬŏŎŭŬ"); // breve
+ accents["grave{\\imath}"] = "ì";
+ buildaccent("grave|`", "aAeEiIoOuUnNwWyY",
+ "àÀèÈìÌòÒùÙǹǸẁẀỳỲ"); // grave
+ buildaccent("subdot|d", "BbDdHhKkLlMmNnRrSsTtVvWwZzAaEeIiOoUuYy",
+ "ḄḅḌḍḤḥḲḳḶḷṂṃṆṇṚṛṢṣṬṭṾṿẈẉẒẓẠạẸẹỊịỌọỤụỴỵ"); // dot below
+ buildaccent("ogonek|k", "AaEeIiUuOo",
+ "ĄąĘęĮįŲųǪǫ"); // ogonek
+ buildaccent("cedilla|c", "CcGgKkLlNnRrSsTtEeDdHh",
+ "ÇçĢĢĶķĻļŅņŖŗŞşŢţȨȩḐḑḨḩ"); // cedilla
+ buildaccent("subring|textsubring", "Aa",
+ "Ḁḁ"); // subring
+ buildaccent("subhat|textsubcircum", "DdEeLlNnTtUu",
+ "ḒḓḘḙḼḽṊṋṰṱṶṷ"); // subcircum
+ buildaccent("subtilde|textsubtilde", "EeIiUu",
+ "ḚḛḬḭṴṵ"); // subtilde
+ accents["dgrave{\\imath}"] = "ȉ";
+ accents["textdoublegrave{\\i}"] = "ȉ";
+ buildaccent("dgrave|textdoublegrave", "AaEeIiOoRrUu",
+ "ȀȁȄȅȈȉȌȍȐȑȔȕ"); // double grave
+ accents["rcap{\\imath}"] = "ȉ";
+ accents["textroundcap{\\i}"] = "ȉ";
+ buildaccent("rcap|textroundcap", "AaEeIiOoRrUu",
+ "ȂȃȆȇȊȋȎȏȒȓȖȗ"); // inverted breve
+ buildaccent("slashed", "oO",
+ "øØ"); // slashed
+}
+
+/*
+ * Created accents in math or regexp environment
+ * are macros, but we need the utf8 equivalent
+ */
+void Intervall::removeAccents()
+{
+ if (accents.empty())
+ buildAccentsMap();
+ static regex const accre("\\\\(([\\S]|grave|breve|lyxmathsym|text|ddot|dot|acute|dacute|mathring|check|hat|bar|tilde|subdot|ogonek|cedilla|subring|textsubring|subhat|textsubcircum|subtilde|textsubtilde|dgrave|textdoublegrave|rcap|textroundcap|slashed)\\{[^\\{\\}]+\\}|(i|imath|jmath)(?![a-zA-Z]))");
+ smatch sub;
+ for (sregex_iterator itacc(par.begin(), par.end(), accre), end; itacc != end; ++itacc) {
+ sub = *itacc;
+ string key = sub.str(1);
+ if (accents.find(key) != accents.end()) {
+ string val = accents[key];
+ size_t pos = sub.position(size_t(0));
+ for (size_t i = 0; i < val.size(); i++) {
+ par[pos+i] = val[i];
+ }
+ addIntervall(pos+val.size(), pos + sub.str(0).size());
+ for (size_t i = pos+val.size(); i < pos + sub.str(0).size(); i++) {
+ // remove traces of any remaining chars
+ par[i] = ' ';
+ }
+ }
+ else {
+ LYXERR(Debug::INFO, "Not added accent for \"" << key << "\"");
+ }
+ }
+}
+