1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-18 11:00:09 +02:00

Make transliteration configurable per-language

This commit is contained in:
José Rebelo 2022-06-15 00:54:44 +01:00 committed by Gitea
parent 6bea0af9e0
commit 33d433d206
31 changed files with 957 additions and 242 deletions

View File

@ -117,7 +117,7 @@ public class GBApplication extends Application {
private static SharedPreferences sharedPrefs;
private static final String PREFS_VERSION = "shared_preferences_version";
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
private static final int CURRENT_PREFS_VERSION = 15;
private static final int CURRENT_PREFS_VERSION = 16;
private static LimitedQueue mIDSenderLookup = new LimitedQueue(16);
private static Prefs prefs;
@ -1166,6 +1166,30 @@ public class GBApplication extends Application {
}
}
if (oldVersion < 16) {
// If transliteration was enabled for a device, migrate it to the per-language setting
final String defaultLanguagesIfEnabled = "extended_ascii,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean";
try (DBHandler db = acquireDB()) {
final DaoSession daoSession = db.getDaoSession();
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
for (Device dbDevice : activeDevices) {
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
if (deviceSharedPrefs.getBoolean("pref_transliteration_enabled", false)) {
deviceSharedPrefsEdit.putString("pref_transliteration_languages", defaultLanguagesIfEnabled);
}
deviceSharedPrefsEdit.remove("pref_transliteration_enabled");
deviceSharedPrefsEdit.apply();
}
} catch (Exception e) {
Log.w(TAG, "error acquiring DB lock");
}
}
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
editor.apply();
}

View File

@ -141,7 +141,7 @@ public class DeviceSettingsPreferenceConst {
public static final String PREF_SONYSWR12_SMART_INTERVAL = "smart_alarm_interval_preference";
public static final String PREF_BT_CONNECTED_ADVERTISEMENT = "bt_connected_advertisement";
public static final String PREF_TRANSLITERATION_ENABLED = "pref_transliteration_enabled";
public static final String PREF_TRANSLITERATION_LANGUAGES = "pref_transliteration_languages";
public static final String PREF_NOTHING_EAR1_INEAR = "pref_nothing_inear_detection";
public static final String PREF_NOTHING_EAR1_AUDIOMODE = "pref_nothing_audiomode";

View File

@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -85,10 +86,11 @@ import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.EmojiConverter;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils;
import nodomain.freeyourgadget.gadgetbridge.util.language.LanguageUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_LANGUAGES;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ADD_CALENDAREVENT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_CONFIGURE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_REORDER;
@ -576,12 +578,13 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
DeviceSupport deviceSupport = getDeviceSupport(device);
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
boolean transliterate = devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false);
if (transliterate) {
final Transliterator transliterator = LanguageUtils.getTransliterator(device);
if (transliterator != null) {
for (String extra : GBDeviceService.transliterationExtras) {
if (intent.hasExtra(extra)) {
intent.putExtra(extra, LanguageUtils.transliterate(intent.getStringExtra(extra)));
intent.putExtra(extra, transliterator.transliterate(intent.getStringExtra(extra)));
}
}
}

View File

@ -1,184 +0,0 @@
/* Copyright (C) 2017-2021 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED;
import android.content.SharedPreferences;
import org.apache.commons.lang3.text.WordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.Normalizer;
import java.util.HashMap;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class LanguageUtils {
private static final Logger LOG = LoggerFactory.getLogger(LanguageUtils.class);
// Transliteration map with english equivalent for unsupported chars
@SuppressWarnings("OverwrittenKey")
private static final Map<Character, String> transliterateMap = new HashMap<Character, String>() {
{
// Extended ASCII characters
put('œ', "oe"); put('ª', "a"); put('º', "o"); put('«',"\""); put('»',"\"");
// Scandinavian characters
put('Æ',"Ae"); put('æ',"ae");
put('Ø',"Oe"); put('ø',"oe");
put('Å',"Aa"); put('å',"aa");
// German characters
put('ä',"ae"); put('ö',"oe"); put('ü',"ue");
put('Ä',"Ae"); put('Ö',"Oe"); put('Ü',"Üe");
put('ß',"ss"); put('ẞ',"SS");
// Russian chars
put('а', "a"); put('б', "b"); put('в', "v"); put('г', "g"); put('д', "d"); put('е', "e"); put('ё', "jo"); put('ж', "zh");
put('з', "z"); put('и', "i"); put('й', "jj"); put('к', "k"); put('л', "l"); put('м', "m"); put('н', "n"); put('о', "o");
put('п', "p"); put('р', "r"); put('с', "s"); put('т', "t"); put('у', "u"); put('ф', "f"); put('х', "kh"); put('ц', "c");
put('ч', "ch");put('ш', "sh");put('щ', "shh");put('ъ', "\"");put('ы', "y"); put('ь', "'"); put('э', "eh"); put('ю', "ju");
put('я', "ja");
// Hebrew chars
put('א', "a"); put('ב', "b"); put('ג', "g"); put('ד', "d"); put('ה', "h"); put('ו', "u"); put('ז', "z"); put('ח', "kh");
put('ט', "t"); put('י', "y"); put('כ', "c"); put('ל', "l"); put('מ', "m"); put('נ', "n"); put('ס', "s"); put('ע', "'");
put('פ', "p"); put('צ', "ts"); put('ק', "k"); put('ר', "r"); put('ש', "sh"); put('ת', "th"); put('ף', "f"); put('ץ', "ts");
put('ך', "ch");put('ם', "m");put('ן', "n");
// Greek chars
put('α',"a");put('ά',"a");put('β',"v");put('γ',"g");put('δ',"d");put('ε',"e");put('έ',"e");put('ζ',"z");put('η',"i");
put('ή',"i");put('θ',"th");put('ι',"i");put('ί',"i");put('ϊ',"i");put('ΐ',"i");put('κ',"k");put('λ',"l");put('μ',"m");
put('ν',"n");put('ξ',"ks");put('ο',"o");put('ό',"o");put('π',"p");put('ρ',"r");put('σ',"s");put('ς',"s");put('τ',"t");
put('υ',"y");put('ύ',"y");put('ϋ',"y");put('ΰ',"y");put('φ',"f");put('χ',"ch");put('ψ',"ps");put('ω',"o");put('ώ',"o");
put('Α',"A");put('Ά',"A");put('Β',"B");put('Γ',"G");put('Δ',"D");put('Ε',"E");put('Έ',"E");put('Ζ',"Z");put('Η',"I");
put('Ή',"I");put('Θ',"TH");put('Ι',"I");put('Ί',"I");put('Ϊ',"I");put('Κ',"K");put('Λ',"L");put('Μ',"M");put('Ν',"N");
put('Ξ',"KS");put('Ο',"O");put('Ό',"O");put('Π',"P");put('Ρ',"R");put('Σ',"S");put('Τ',"T");put('Υ',"Y");put('Ύ',"Y");
put('Ϋ',"Y");put('Φ',"F");put('Χ',"CH");put('Ψ',"PS");put('Ω',"O");put('Ώ',"O");
// Ukrainian characters
put('ґ', "gh"); put('є', "je"); put('і', "i"); put('ї', "ji"); put('Ґ', "GH"); put('Є', "JE"); put('І', "I"); put('Ї', "JI");
// Arabic
put('ا', "a"); put('ب', "b"); put('ت', "t"); put('ث', "th"); put('ج', "j"); put('ح', "7"); put('خ', "5");
put('د', "d"); put('ذ', "th"); put('ر', "r"); put('ز', "z"); put('س', "s"); put('ش', "sh"); put('ص', "9");
put('ض', "9'"); put('ط', "6"); put('ظ', "6'"); put('ع', "3"); put('غ', "3'"); put('ف', "f");
put('ق', "q"); put('ك', "k"); put('ل', "l"); put('م', "m"); put('ن', "n"); put('ه', "h");
put('و', "w"); put('ي', "y"); put('ى', "a"); put('ﺓ', "");
put('آ', "2"); put('ئ', "2"); put('إ', "2"); put('ؤ', "2"); put('أ', "2"); put('ء', "2");
put('٠', "0"); put('١', "1"); put('٢', "2"); put('٣', "3"); put('٤', "4"); put('٥', "5");
put('٦', "6"); put('٧', "7"); put('٨', "8"); put('٩', "9");
// Persian(Farsi)
put('پ', "p"); put('چ', "ch"); put('ژ', "zh"); put('ک', "k"); put('گ', "g"); put('ی', "y"); put('', " ");
put('؟', "?"); put('٪', "%"); put('؛', ";"); put('،', ","); put('۱', "1"); put('۲', "2"); put('۳', "3");
put('۴', "4"); put('۵', "5"); put('۶', "6"); put('۷', "7"); put('۸', "8"); put('۹', "9"); put('۰', "0");
put('»', "<"); put('«', ">"); put('ِ', "e"); put('َ', "a"); put('ُ', "o"); put('ّ', "");
// Polish
put('Ł', "L"); put('ł', "l");
//Lithuanian
put('ą', "a"); put('č', "c"); put('ę', "e"); put('ė', "e"); put('į', "i"); put('š', "s"); put('ų', "u"); put('ū', "u"); put('ž', "z");
// Estonian
put('ä', "a"); put('Ä', "A");
put('ö', "o"); put('õ', "o");
put('Ö', "O"); put('Õ', "O");
put('ü', "u"); put('Ü', "U");
// Icelandic
put('Þ',"Th"); put('þ',"th"); put('Ð',"D"); put('ð',"d");
// Czech
put('ř',"r"); put('ě',"e"); put('ý',"y"); put('á',"a"); put('í',"i"); put('é',"e");
put('ó',"o"); put('ú',"u"); put('ů',"u"); put('ď',"d"); put('ť',"t"); put('ň',"n");
// Turkish
put('ı',"i");
//TODO: these must be configurable. If someone wants to transliterate cyrillic it does not mean his device has no German umlauts
// all or nothing is really bad here
}
};
/**
* Replaces unsupported symbols to english
* @param txt input text
* @return transliterated text
*/
public static String transliterate(String txt){
if (txt == null || txt.isEmpty()) {
return txt;
}
StringBuilder messageBuilder = new StringBuilder();
// Simple, char-by-char transliteration.
char[] chars = txt.toCharArray();
for (char c : chars)
{
messageBuilder.append(transliterate(c));
}
String message = messageBuilder.toString();
// More complex transliteration for specific languages.
message = BengaliLanguageUtils.transliterate(message);
message = KoreanLanguageUtils.transliterate(message);
return flattenToAscii(message);
}
/**
* Replaces unsupported symbol to english by {@code transliterateMap}
* @param c input char
* @return replacement text
*/
private static String transliterate(char c){
char lowerChar = Character.toLowerCase(c);
if (transliterateMap.containsKey(lowerChar)) {
String replace = transliterateMap.get(lowerChar);
if (lowerChar != c)
{
return WordUtils.capitalize(replace);
}
return replace;
}
return String.valueOf(c);
}
/**
* Converts the diacritics
* @param string input text
* @return converted text
*/
private static String flattenToAscii(String string) {
string = Normalizer.normalize(string, Normalizer.Form.NFD);
return string.replaceAll("\\p{M}", "");
}
}

View File

@ -0,0 +1,127 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_LANGUAGES;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.ArabicTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.BengaliTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.CzechTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.EstonianTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.ExtendedAsciiTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.FlattenToAsciiTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.GermanTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.GreekTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.HebrewTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.IcelandicTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.KoreanTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.LithuanianTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.PersianTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.PolishTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.RussianTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.ScandinavianTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.TurkishTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.impl.UkranianTransliterator;
public class LanguageUtils {
private static final Logger LOG = LoggerFactory.getLogger(LanguageUtils.class);
private static final Map<String, Transliterator> TRANSLITERATORS_MAP = new HashMap<String, Transliterator>() {{
put("arabic", new ArabicTransliterator());
put("bengali", new BengaliTransliterator());
put("czech", new CzechTransliterator());
put("estonian", new EstonianTransliterator());
put("extended_ascii", new ExtendedAsciiTransliterator());
put("german", new GermanTransliterator());
put("greek", new GreekTransliterator());
put("hebrew", new HebrewTransliterator());
put("icelandic", new IcelandicTransliterator());
put("korean", new KoreanTransliterator());
put("lithuanian", new LithuanianTransliterator());
put("persian", new PersianTransliterator());
put("polish", new PolishTransliterator());
put("russian", new RussianTransliterator());
put("scandinavian", new ScandinavianTransliterator());
put("turkish", new TurkishTransliterator());
put("ukranian", new UkranianTransliterator());
}};
/**
* Get a {@link Transliterator} for a specific language.
*
* @param language the language
* @return the transliterator, if it exists
* @throws IllegalArgumentException if there is no transliterator for the provided language
*/
public static Transliterator getTransliterator(final String language) {
if (!TRANSLITERATORS_MAP.containsKey(language)) {
throw new IllegalArgumentException(String.format("Transliterator for %s not found", language));
}
return TRANSLITERATORS_MAP.get(language);
}
/**
* Get the configured transliterator for the provided {@link GBDevice}, if any.
*
* @param device the device
* @return the configured transliterator, null if not configured
*/
@Nullable
public static Transliterator getTransliterator(final GBDevice device) {
final Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
final String transliterateLanguagesPref = devicePrefs.getString(PREF_TRANSLITERATION_LANGUAGES, "");
if (transliterateLanguagesPref.isEmpty()) {
return null;
}
final List<String> languages = Arrays.asList(transliterateLanguagesPref.split(","));
final List<Transliterator> transliterators = new ArrayList<>(languages.size());
for (String language : languages) {
if (!TRANSLITERATORS_MAP.containsKey(language)) {
LOG.warn("Transliterator for {} not found", language);
continue;
}
transliterators.add(TRANSLITERATORS_MAP.get(language));
}
transliterators.add(new FlattenToAsciiTransliterator());
return new MultiTransliterator(transliterators);
}
}

View File

@ -0,0 +1,42 @@
/* Copyright (C) 2022 José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language;
import java.text.Normalizer;
import java.util.List;
import java.util.Map;
public class MultiTransliterator implements Transliterator {
private final List<Transliterator> transliterators;
public MultiTransliterator(final List<Transliterator> transliterators) {
this.transliterators = transliterators;
}
@Override
public String transliterate(String txt) {
if (txt == null || txt.isEmpty()) {
return txt;
}
for (Transliterator transliterator : transliterators) {
txt = transliterator.transliterate(txt);
}
return txt;
}
}

View File

@ -0,0 +1,64 @@
/* Copyright (C) 2022 José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language;
import org.apache.commons.lang3.text.WordUtils;
import java.text.Normalizer;
import java.util.Map;
public class SimpleTransliterator implements Transliterator {
private final Map<Character, String> transliterateMap;
public SimpleTransliterator(final Map<Character, String> transliterateMap) {
this.transliterateMap = transliterateMap;
}
@Override
public String transliterate(String txt) {
if (txt == null || txt.isEmpty()) {
return txt;
}
final StringBuilder messageBuilder = new StringBuilder();
// Simple, char-by-char transliteration.
final char[] chars = txt.toCharArray();
for (char c : chars) {
messageBuilder.append(transliterate(c));
}
final String message = messageBuilder.toString();
return message;
}
private String transliterate(char c) {
final char lowerChar = Character.toLowerCase(c);
if (transliterateMap.containsKey(lowerChar)) {
final String replace = transliterateMap.get(lowerChar);
if (lowerChar != c) {
return WordUtils.capitalize(replace);
}
return replace;
}
return String.valueOf(c);
}
}

View File

@ -0,0 +1,21 @@
/* Copyright (C) 2022 José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language;
public interface Transliterator {
String transliterate(String txt);
}

View File

@ -0,0 +1,39 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class ArabicTransliterator extends SimpleTransliterator {
public ArabicTransliterator() {
super(new HashMap<Character, String>() {{
put('ا', "a"); put('ب', "b"); put('ت', "t"); put('ث', "th"); put('ج', "j"); put('ح', "7"); put('خ', "5");
put('د', "d"); put('ذ', "th"); put('ر', "r"); put('ز', "z"); put('س', "s"); put('ش', "sh"); put('ص', "9");
put('ض', "9'"); put('ط', "6"); put('ظ', "6'"); put('ع', "3"); put('غ', "3'"); put('ف', "f");
put('ق', "q"); put('ك', "k"); put('ل', "l"); put('م', "m"); put('ن', "n"); put('ه', "h");
put('و', "w"); put('ي', "y"); put('ى', "a"); put('ﺓ', "");
put('آ', "2"); put('ئ', "2"); put('إ', "2"); put('ؤ', "2"); put('أ', "2"); put('ء', "2");
put('٠', "0"); put('١', "1"); put('٢', "2"); put('٣', "3"); put('٤', "4"); put('٥', "5");
put('٦', "6"); put('٧', "7"); put('٨', "8"); put('٩', "9");
}});
}
}

View File

@ -15,15 +15,17 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util;
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator;
// What's the reason to extending LanguageUtils?
// Just doing it because already done in the previous code.
public class BengaliLanguageUtils extends LanguageUtils {
public class BengaliTransliterator implements Transliterator {
// Composite Letters.
private final static HashMap<String, String> composites = new HashMap<String, String>() {
{
@ -187,8 +189,9 @@ public class BengaliLanguageUtils extends LanguageUtils {
return null;
}
public static String transliterate(String txt) {
if (txt.isEmpty()) {
@Override
public String transliterate(String txt) {
if (txt == null || txt.isEmpty()) {
return txt;
}

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class CzechTransliterator extends SimpleTransliterator {
public CzechTransliterator() {
super(new HashMap<Character, String>() {{
put('ř',"r"); put('ě',"e"); put('ý',"y"); put('á',"a"); put('í',"i"); put('é',"e");
put('ó',"o"); put('ú',"u"); put('ů',"u"); put('ď',"d"); put('ť',"t"); put('ň',"n");
}});
}
}

View File

@ -0,0 +1,34 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class EstonianTransliterator extends SimpleTransliterator {
public EstonianTransliterator() {
super(new HashMap<Character, String>() {{
put('ä', "a"); put('Ä', "A");
put('ö', "o"); put('õ', "o");
put('Ö', "O"); put('Õ', "O");
put('ü', "u"); put('Ü', "U");
}});
}
}

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class ExtendedAsciiTransliterator extends SimpleTransliterator {
public ExtendedAsciiTransliterator() {
super(new HashMap<Character, String>() {{
put('œ', "oe"); put('ª', "a"); put('º', "o"); put('«',"\""); put('»',"\"");
}});
}
}

View File

@ -0,0 +1,37 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.text.Normalizer;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator;
public class FlattenToAsciiTransliterator implements Transliterator {
@Override
public String transliterate(String txt) {
if (txt == null || txt.isEmpty()) {
return txt;
}
txt = Normalizer.normalize(txt, Normalizer.Form.NFD);
return txt.replaceAll("\\p{M}", "");
}
}

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class GermanTransliterator extends SimpleTransliterator {
public GermanTransliterator() {
super(new HashMap<Character, String>() {{
put('ä',"ae"); put('ö',"oe"); put('ü',"ue");
put('Ä',"Ae"); put('Ö',"Oe"); put('Ü',"Üe");
put('ß',"ss"); put('ẞ',"SS");
}});
}
}

View File

@ -0,0 +1,38 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class GreekTransliterator extends SimpleTransliterator {
public GreekTransliterator() {
super(new HashMap<Character, String>() {{
put('α',"a");put('ά',"a");put('β',"v");put('γ',"g");put('δ',"d");put('ε',"e");put('έ',"e");put('ζ',"z");put('η',"i");
put('ή',"i");put('θ',"th");put('ι',"i");put('ί',"i");put('ϊ',"i");put('ΐ',"i");put('κ',"k");put('λ',"l");put('μ',"m");
put('ν',"n");put('ξ',"ks");put('ο',"o");put('ό',"o");put('π',"p");put('ρ',"r");put('σ',"s");put('ς',"s");put('τ',"t");
put('υ',"y");put('ύ',"y");put('ϋ',"y");put('ΰ',"y");put('φ',"f");put('χ',"ch");put('ψ',"ps");put('ω',"o");put('ώ',"o");
put('Α',"A");put('Ά',"A");put('Β',"B");put('Γ',"G");put('Δ',"D");put('Ε',"E");put('Έ',"E");put('Ζ',"Z");put('Η',"I");
put('Ή',"I");put('Θ',"TH");put('Ι',"I");put('Ί',"I");put('Ϊ',"I");put('Κ',"K");put('Λ',"L");put('Μ',"M");put('Ν',"N");
put('Ξ',"KS");put('Ο',"O");put('Ό',"O");put('Π',"P");put('Ρ',"R");put('Σ',"S");put('Τ',"T");put('Υ',"Y");put('Ύ',"Y");
put('Ϋ',"Y");put('Φ',"F");put('Χ',"CH");put('Ψ',"PS");put('Ω',"O");put('Ώ',"O");
}});
}
}

View File

@ -0,0 +1,34 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class HebrewTransliterator extends SimpleTransliterator {
public HebrewTransliterator() {
super(new HashMap<Character, String>() {{
put('א', "a"); put('ב', "b"); put('ג', "g"); put('ד', "d"); put('ה', "h"); put('ו', "u"); put('ז', "z"); put('ח', "kh");
put('ט', "t"); put('י', "y"); put('כ', "c"); put('ל', "l"); put('מ', "m"); put('נ', "n"); put('ס', "s"); put('ע', "'");
put('פ', "p"); put('צ', "ts"); put('ק', "k"); put('ר', "r"); put('ש', "sh"); put('ת', "th"); put('ף', "f"); put('ץ', "ts");
put('ך', "ch");put('ם', "m");put('ן', "n");
}});
}
}

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class IcelandicTransliterator extends SimpleTransliterator {
public IcelandicTransliterator() {
super(new HashMap<Character, String>() {{
put('Þ',"Th"); put('þ',"th"); put('Ð',"D"); put('ð',"d");
}});
}
}

View File

@ -14,16 +14,18 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util;
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.Optional;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator;
// Implements Revised Romanization of Korean as well as we can without understanding any grammar.
//
// https://en.wikipedia.org/wiki/Revised_Romanization_of_Korean
public class KoreanLanguageUtils {
public class KoreanTransliterator implements Transliterator {
// https://en.wikipedia.org/wiki/Hangul_Jamo_%28Unicode_block%29
private static final char JAMO_BLOCK_START = 0x1100;
private static final char JAMO_BLOCK_END = 0x11FF;
@ -282,7 +284,8 @@ public class KoreanLanguageUtils {
}
// Transliterate any Hangul in the given string. Leaves any non-Hangul characters unmodified.
public static String transliterate(String txt) {
@Override
public String transliterate(String txt) {
if (txt == null || txt.isEmpty()) {
return txt;
}

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class LithuanianTransliterator extends SimpleTransliterator {
public LithuanianTransliterator() {
super(new HashMap<Character, String>() {{
put('ą', "a"); put('č', "c"); put('ę', "e"); put('ė', "e"); put('į', "i"); put('š', "s"); put('ų', "u"); put('ū', "u"); put('ž', "z");
}});
}
}

View File

@ -0,0 +1,35 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class PersianTransliterator extends SimpleTransliterator {
public PersianTransliterator() {
super(new HashMap<Character, String>() {{
// Persian (Farsi)
put('پ', "p"); put('چ', "ch"); put('ژ', "zh"); put('ک', "k"); put('گ', "g"); put('ی', "y"); put('', " ");
put('؟', "?"); put('٪', "%"); put('؛', ";"); put('،', ","); put('۱', "1"); put('۲', "2"); put('۳', "3");
put('۴', "4"); put('۵', "5"); put('۶', "6"); put('۷', "7"); put('۸', "8"); put('۹', "9"); put('۰', "0");
put('»', "<"); put('«', ">"); put('ِ', "e"); put('َ', "a"); put('ُ', "o"); put('ّ', "");
}});
}
}

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class PolishTransliterator extends SimpleTransliterator {
public PolishTransliterator() {
super(new HashMap<Character, String>() {{
// Polish
put('Ł', "L"); put('ł', "l");
}});
}
}

View File

@ -0,0 +1,37 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class RussianTransliterator extends SimpleTransliterator {
public RussianTransliterator() {
super(new HashMap<Character, String>() {{
put('а', "a"); put('б', "b"); put('в', "v"); put('г', "g"); put('д', "d"); put('е', "e"); put('ё', "jo"); put('ж', "zh");
put('з', "z"); put('и', "i"); put('й', "jj"); put('к', "k"); put('л', "l"); put('м', "m"); put('н', "n"); put('о', "o");
put('п', "p"); put('р', "r"); put('с', "s"); put('т', "t"); put('у', "u"); put('ф', "f"); put('х', "kh"); put('ц', "c");
put('ч', "ch");put('ш', "sh");put('щ', "shh");put('ъ', "\"");put('ы', "y"); put('ь', "'"); put('э', "eh"); put('ю', "ju");
put('я', "ja");
put('õ', "o"); put('č', "c");
}});
}
}

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class ScandinavianTransliterator extends SimpleTransliterator {
public ScandinavianTransliterator() {
super(new HashMap<Character, String>() {{
put('Æ',"Ae"); put('æ',"ae");
put('Ø',"Oe"); put('ø',"oe");
put('Å',"Aa"); put('å',"aa");
}});
}
}

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class TurkishTransliterator extends SimpleTransliterator {
public TurkishTransliterator() {
super(new HashMap<Character, String>() {{
put('ı',"i");
}});
}
}

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele
Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg,
Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.language.impl;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator;
public class UkranianTransliterator extends SimpleTransliterator {
public UkranianTransliterator() {
super(new HashMap<Character, String>() {{
put('ґ', "gh"); put('є', "je"); put('і', "i"); put('ї', "ji"); put('Ґ', "GH"); put('Є', "JE"); put('І', "I"); put('Ї', "JI");
}});
}
}

View File

@ -2278,5 +2278,47 @@
<item>de.dennisguse.opentracks.nightly</item>
</string-array>
</resources>
<string-array name="pref_transliteration_languages">
<item>@string/arabic</item>
<item>@string/bengali</item>
<item>@string/czech</item>
<item>@string/estonian</item>
<item>@string/extended_ascii</item>
<item>@string/german</item>
<item>@string/greek</item>
<item>@string/hebrew</item>
<item>@string/icelandic</item>
<item>@string/korean</item>
<item>@string/lithuanian</item>
<item>@string/persian</item>
<item>@string/polish</item>
<item>@string/russian</item>
<item>@string/scandinavian</item>
<item>@string/turkish</item>
<item>@string/ukranian</item>
</string-array>
<string-array name="pref_transliteration_languages_values">
<item>arabic</item>
<item>bengali</item>
<item>czech</item>
<item>estonian</item>
<item>extended_ascii</item>
<item>german</item>
<item>greek</item>
<item>hebrew</item>
<item>icelandic</item>
<item>korean</item>
<item>lithuanian</item>
<item>persian</item>
<item>polish</item>
<item>russian</item>
<item>scandinavian</item>
<item>turkish</item>
<item>ukranian</item>
</string-array>
<string-array name="pref_transliteration_languages_default">
<!-- transliteration disabled by default -->
</string-array>
</resources>

View File

@ -746,6 +746,15 @@
<string name="spanish">Spanish</string>
<string name="russian">Russian</string>
<string name="german">German</string>
<string name="bengali">Bengali</string>
<string name="czech">Czech</string>
<string name="estonian">Estonian</string>
<string name="extended_ascii">Extended ASCII</string>
<string name="icelandic">Icelandic</string>
<string name="lithuanian">Lithuanian</string>
<string name="persian">Persian</string>
<string name="scandinavian">Scandinavian</string>
<string name="ukranian">Ukranian</string>
<string name="italian">Italian</string>
<string name="french">French</string>
<string name="polish">Polish</string>

View File

@ -1,9 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="false"
android:key="pref_transliteration_enabled"
<com.mobeta.android.dslv.DragSortListPreference
android:defaultValue="@array/pref_transliteration_languages_default"
android:dialogTitle="@string/pref_title_transliteration"
android:entries="@array/pref_transliteration_languages"
android:entryValues="@array/pref_transliteration_languages_values"
android:icon="@drawable/ic_translate"
android:key="pref_transliteration_languages"
android:persistent="true"
android:summary="@string/pref_summary_transliteration"
android:title="@string/pref_title_transliteration" />
</androidx.preference.PreferenceScreen>
</androidx.preference.PreferenceScreen>

View File

@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.service;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.location.Location;
import android.net.Uri;
import java.util.ArrayList;
@ -225,4 +226,8 @@ class TestDeviceSupport extends AbstractDeviceSupport {
public void onPowerOff() {
}
@Override public void onSetGpsLocation(Location location) {
}
}

View File

@ -1,4 +1,4 @@
package nodomain.freeyourgadget.gadgetbridge.test;
package nodomain.freeyourgadget.gadgetbridge.util.language;
import android.content.SharedPreferences;
@ -6,14 +6,12 @@ import org.junit.Test;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils;
import nodomain.freeyourgadget.gadgetbridge.util.KoreanLanguageUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.test.TestBase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_LANGUAGES;
/**
* Tests LanguageUtils
@ -31,9 +29,11 @@ public class LanguageUtilsTest extends TestBase {
@Test
public void testStringTransliterateCyrillic() throws Exception {
final Transliterator transliterator = LanguageUtils.getTransliterator("russian");
// input with cyrillic and diacritic letters
String input = "Прõсто текčт";
String output = LanguageUtils.transliterate(input);
String output = transliterator.transliterate(input);
String result = "Prosto tekct";
assertEquals("Transliteration failed", result, output);
@ -41,8 +41,10 @@ public class LanguageUtilsTest extends TestBase {
@Test
public void testStringTransliterateHebrew() throws Exception {
final Transliterator transliterator = LanguageUtils.getTransliterator("hebrew");
String input = "בדיקה עברית";
String output = LanguageUtils.transliterate(input);
String output = transliterator.transliterate(input);
String result = "bdykh 'bryth";
assertEquals("Transliteration failed", result, output);
@ -50,37 +52,48 @@ public class LanguageUtilsTest extends TestBase {
@Test
public void testStringTransliterateArabic() {
final Transliterator transliterator = LanguageUtils.getTransliterator("arabic");
String pangram = "نص حكيم له سر قاطع وذو شأن عظيم مكتوب على ثوب أخضر ومغلف بجلد أزرق";
String pangramExpected = "n9 7kym lh sr qa63 wthw sh2n 36'ym mktwb 3la thwb 259'r wm3'lf bjld 2zrq";
String pangramActual = LanguageUtils.transliterate(pangram);
String pangramActual = transliterator.transliterate(pangram);
assertEquals("Arabic pangram transliteration failed", pangramExpected, pangramActual);
String taMarbutah = "";
String taMarbutahExpected = "";
String taMarbutahActual = LanguageUtils.transliterate(taMarbutah);
String taMarbutahActual = transliterator.transliterate(taMarbutah);
assertEquals("ta marbutah transliteration failed", taMarbutahExpected, taMarbutahActual);
String hamza = "ءأؤإئآ";
String hamzaExpected = "222222";
String hamzaActual = LanguageUtils.transliterate(hamza);
String hamzaActual = transliterator.transliterate(hamza);
assertEquals("hamza transliteration failed", hamzaExpected, hamzaActual);
String easternArabicNumeralsArabic = "٠١٢٣٤٥٦٧٨٩";
String easternArabicNumeralsFarsi = "۰۱۲۳۴۵۶۷۸۹";
String easternArabicNumeralsExpected = "0123456789";
assertEquals("Eastern Arabic numerals (Arabic) failed", easternArabicNumeralsExpected,
LanguageUtils.transliterate(easternArabicNumeralsArabic));
assertEquals("Eastern Arabic numerals (Farsi) failed", easternArabicNumeralsExpected,
LanguageUtils.transliterate(easternArabicNumeralsFarsi));
transliterator.transliterate(easternArabicNumeralsArabic));
}
public void testStringTransliteratePersian() {
final Transliterator transliterator = LanguageUtils.getTransliterator("persian");
String farsi = "گچپژ";
String farsiExpected = "gchpzh";
String farsiActual = LanguageUtils.transliterate(farsi);
String farsiActual = transliterator.transliterate(farsi);
assertEquals("Farsi transiteration failed", farsiExpected, farsiActual);
String easternArabicNumeralsFarsi = "۰۱۲۳۴۵۶۷۸۹";
String easternArabicNumeralsExpected = "0123456789";
assertEquals("Eastern Arabic numerals (Farsi) failed", easternArabicNumeralsExpected,
transliterator.transliterate(easternArabicNumeralsFarsi));
}
@Test
public void testStringTransliterateBengali() throws Exception {
final Transliterator transliterator = LanguageUtils.getTransliterator("bengali");
// input with cyrillic and diacritic letters
String[] inputs = { "অনিরুদ্ধ", "বিজ্ঞানযাত্রা চলছে চলবে।", "আমি সব দেখেশুনে ক্ষেপে গিয়ে করি বাঙলায় চিৎকার!",
"আমার জাভা কোড is so bad! কী আর বলবো!" };
@ -91,17 +104,19 @@ public class LanguageUtilsTest extends TestBase {
String result;
for (int i = 0; i < inputs.length; i++) {
result = LanguageUtils.transliterate(inputs[i]);
result = transliterator.transliterate(inputs[i]);
assertEquals("Transliteration failed", outputs[i], result);
}
}
@Test
public void testStringTransliterateKorean() {
final Transliterator transliterator = LanguageUtils.getTransliterator("korean");
// A familiar phrase with no special provisions.
String hello = "안녕하세요";
String helloExpected = "annyeonghaseyo";
String helloActual = LanguageUtils.transliterate(hello);
String helloActual = transliterator.transliterate(hello);
assertEquals("Korean hello transliteration failed", helloExpected, helloActual);
// Korean pangram. Includes some ASCII punctuation which should not be changed by
@ -111,67 +126,65 @@ public class LanguageUtilsTest extends TestBase {
// you complaining again?"
String pangram = "\"웬 초콜릿? 제가 원했던 건 뻥튀기 쬐끔과 의류예요.\" \"얘야, 왜 또 불평?\"";
String pangramExpected = "\"wen chokollit? jega wonhaetdeon geon ppeongtwigi jjoekkeumgwa uiryuyeyo.\" \"yaeya, wae tto bulpyeong?\"";
String pangramActual = LanguageUtils.transliterate(pangram);
String pangramActual = transliterator.transliterate(pangram);
assertEquals("Korean pangram transliteration failed", pangramExpected, pangramActual);
// Several words excercising special provisions, from Wikipedia.
String special = "좋고, 놓다, 잡혀, 낳지";
String specialExpected = "joko, nota, japhyeo, nachi";
String specialActual = LanguageUtils.transliterate(special);
String specialActual = transliterator.transliterate(special);
assertEquals("Korean special provisions transliteration failed", specialExpected, specialActual);
// Isolated jamo.
String isolatedJamo = "ㅋㅋㅋ";
String isolatedJamoExpected = "kkk";
String isolatedJamoActual = LanguageUtils.transliterate(isolatedJamo);
String isolatedJamoActual = transliterator.transliterate(isolatedJamo);
assertEquals("Korean isolated jamo transliteration failed", isolatedJamoExpected, isolatedJamoActual);
// Korean transliteration shouldn't touch non-Hangul composites.
String german = "schön";
String germanExpected = german;
String germanActual = KoreanLanguageUtils.transliterate(german);
String germanActual = transliterator.transliterate(german);
assertEquals("Korean transliteration modified a non-Hangul composite", germanExpected, germanActual);
}
@Test
public void testStringTransliterateLithuanian() {
final Transliterator transliterator = LanguageUtils.getTransliterator("lithuanian");
String input = "ą č ę ė į š ų ū ž";
String output = LanguageUtils.transliterate(input);
String output = transliterator.transliterate(input);
String expected = "a c e e i s u u z";
assertEquals("lithuanian translation failed", expected, output);
input = "aąa cčc eęe eėe iįi sšs uųu uūu zžz";
output = LanguageUtils.transliterate(input);
output = transliterator.transliterate(input);
expected = "aaa ccc eee eee iii sss uuu uuu zzz";
assertEquals("lithuanian translation failed", expected, output);
}
@Test
public void testTransliterateOption() throws Exception {
setDefaultTransliteration();
assertFalse("Transliteration option fail! Expected 'Off' by default, but result is 'On'",
enableTransliteration(false);
assertNull("Transliteration option fail! Expected 'Off' by default, but result is 'On'",
getTransliteration());
enableTransliteration(true);
assertTrue("Transliteration option fail! Expected 'On', but result is 'Off'", getTransliteration());
}
private void setDefaultTransliteration() {
SharedPreferences devicePrefs = GBApplication.getDeviceSpecificSharedPrefs(dummyGBDevice.getAddress());
SharedPreferences.Editor editor = devicePrefs.edit();
editor.remove(PREF_TRANSLITERATION_ENABLED);
editor.apply();
assertNotNull("Transliteration option fail! Expected 'On', but result is 'Off'", getTransliteration());
}
private void enableTransliteration(boolean enable) {
SharedPreferences devicePrefs = GBApplication.getDeviceSpecificSharedPrefs(dummyGBDevice.getAddress());
SharedPreferences.Editor editor = devicePrefs.edit();
editor.putBoolean(PREF_TRANSLITERATION_ENABLED, enable);
if (enable) {
editor.putString(PREF_TRANSLITERATION_LANGUAGES, "extended_ascii,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean");
} else {
editor.remove(PREF_TRANSLITERATION_LANGUAGES);
}
editor.apply();
}
private boolean getTransliteration(){
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(dummyGBDevice.getAddress()));
return devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false);
private Transliterator getTransliteration() {
return LanguageUtils.getTransliterator(dummyGBDevice);
}
}