diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java index f3d66b511..79167d66d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java @@ -57,6 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.language.impl.PersianTransliter 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.SerbianTransliterator; import nodomain.freeyourgadget.gadgetbridge.util.language.impl.TurkishTransliterator; import nodomain.freeyourgadget.gadgetbridge.util.language.impl.UkranianTransliterator; @@ -85,6 +86,7 @@ public class LanguageUtils { put("polish", new PolishTransliterator()); put("russian", new RussianTransliterator()); put("scandinavian", new ScandinavianTransliterator()); + put("serbian", new SerbianTransliterator()); put("turkish", new TurkishTransliterator()); put("ukranian", new UkranianTransliterator()); put("armenian", new ArmenianTransliterator()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java index b18cbb71c..a16513595 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java @@ -18,14 +18,19 @@ 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 transliterateMap; + private final boolean convertToLowercase; + + public SimpleTransliterator(final Map transliterateMap, final boolean convertToLowercase) { + this.transliterateMap = transliterateMap; + this.convertToLowercase = convertToLowercase; + } public SimpleTransliterator(final Map transliterateMap) { - this.transliterateMap = transliterateMap; + this(transliterateMap, true); } @Override @@ -46,14 +51,14 @@ public class SimpleTransliterator implements Transliterator { return message; } - private String transliterate(char c) { - final char lowerChar = Character.toLowerCase(c); + private String transliterate(final char c) { + final char sourceChar = convertToLowercase ? Character.toLowerCase(c) : c; - if (transliterateMap.containsKey(lowerChar)) { - final String replace = transliterateMap.get(lowerChar); + if (transliterateMap.containsKey(sourceChar)) { + final String replace = transliterateMap.get(sourceChar); - if (lowerChar != c) { - return WordUtils.capitalize(replace); + if (sourceChar != c) { + return convertToLowercase ? WordUtils.capitalize(replace) : replace; } return replace; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/SerbianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/SerbianTransliterator.java new file mode 100644 index 000000000..a82a350c0 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/SerbianTransliterator.java @@ -0,0 +1,65 @@ +/* Copyright (C) 2024 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 . */ + package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class SerbianTransliterator extends SimpleTransliterator { + public SerbianTransliterator() { + super(new HashMap() {{ + // As per https://en.wikipedia.org/wiki/Serbian_Cyrillic_alphabet#Modern_alphabet + put('А', "A"); put('а', "a"); + put('Б', "B"); put('б', "b"); + put('В', "V"); put('в', "v"); + put('Г', "G"); put('г', "g"); + put('Д', "D"); put('д', "d"); + put('Ђ', "Dj"); put('ђ', "dj"); // from Đ / đ - from suggestion in #3727 + put('Е', "E"); put('е', "e"); + put('Ж', "Z"); put('ж', "z"); // from Ž / ž + put('З', "Z"); put('з', "z"); + put('И', "I"); put('и', "i"); + put('Ј', "J"); put('ј', "j"); + put('К', "K"); put('к', "k"); + put('Л', "L"); put('л', "l"); + put('Љ', "Lj"); put('љ', "lj"); + put('М', "M"); put('м', "m"); + put('Н', "N"); put('н', "n"); + put('Њ', "Nj"); put('њ', "nj"); + put('О', "O"); put('о', "o"); + put('П', "P"); put('п', "p"); + put('Р', "R"); put('р', "r"); + put('С', "S"); put('с', "s"); + put('Т', "T"); put('т', "t"); + put('Ћ', "C"); put('ћ', "c"); // from Ć / ć + put('У', "U"); put('у', "u"); + put('Ф', "F"); put('ф', "f"); + put('Х', "H"); put('х', "h"); + put('Ц', "C"); put('ц', "c"); + put('Ч', "C"); put('ч', "c"); // from Č / č + put('Џ', "Dz"); put('џ', "dz"); // from Dž / dž + put('Ш', "S"); put('ш', "s"); // From Š / š + + // Not in the table, pulled from Croatian + put('Ć', "C"); put('ć', "c"); + put('Đ', "D"); put('đ', "d"); + put('Š', "S"); put('š', "s"); + put('Ž', "z"); put('ž', "z"); + }}, false); + } +} diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 95ba80293..aa0fcb056 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -3492,6 +3492,7 @@ @string/polish @string/russian @string/scandinavian + @string/serbian @string/turkish @string/ukranian @string/hungarian @@ -3519,6 +3520,7 @@ polish russian scandinavian + serbian turkish ukranian hungarian diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 745d006a3..3752981ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1060,6 +1060,7 @@ Lithuanian Persian Scandinavian + Serbian Ukranian Armenian Italian diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java index 08a359860..552f1450d 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java @@ -5,6 +5,8 @@ import android.content.SharedPreferences; import org.junit.Test; import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -44,6 +46,34 @@ public class LanguageUtilsTest extends TestBase { assertEquals("Transliteration failed", result, output); } + @Test + public void testStringTransliterateSerbian() throws Exception { + final Transliterator transliterator = LanguageUtils.getTransliterator("serbian"); + + final Map tests = new LinkedHashMap() {{ + put("Тхе qицк брон фоx јумпед овер тхе лаз* дог", "The qick bron fox jumped over the laz* dog"); + put("Српска ћирилица", "Srpska cirilica"); + put("Novak Đoković", "Novak Dokovic"); + put("Џ, Њ and Љ", "Dz, Nj and Lj"); + put("Љуљачка", "Ljuljacka"); + put("Наковањ", "Nakovanj"); + put("Качкаваљ", "Kackavalj"); + put("Чачак", "Cacak"); + put("Ч, ч", "C, c"); + put("Ћ, ћ", "C, c"); + put("Ж, ж", "Z, z"); + put("Ш, ш", "S, s"); + put("Ђ, ђ", "D, d"); + put("Џ, џ", "Dz, dz"); + put("Њ, њ", "Nj, nj"); + put("Љ, љ", "Lj, lj"); + }}; + + for (final Map.Entry e : tests.entrySet()) { + assertEquals("Transliteration failed for " + e.getKey(), e.getValue(), transliterator.transliterate(e.getKey())); + } + } + @Test public void testStringTransliterateHebrew() throws Exception { final Transliterator transliterator = LanguageUtils.getTransliterator("hebrew");