From ae619e1f0f15a0e7ff2df6c4ad6de8c6090f2e60 Mon Sep 17 00:00:00 2001 From: sspanak Date: Sat, 15 Feb 2025 12:18:04 +0200 Subject: [PATCH] added support for a currency character in the language definitions and added some more local currencies --- CONTRIBUTING.md | 1 + app/languages/definitions/Arabic.yml | 1 + app/languages/definitions/Gujarati.yml | 1 + app/languages/definitions/Hebrew.yml | 1 + app/languages/definitions/Hindi.yml | 1 + app/languages/definitions/Korean.yml | 1 + app/languages/definitions/Russian.yml | 1 + app/languages/definitions/Thai.yml | 1 + app/languages/definitions/Turkish.yml | 1 + app/languages/definitions/Ukrainian.yml | 1 + app/languages/definitions/Vietnamese.yml | 1 + .../sspanak/tt9/ime/modes/helpers/AutoSpace.java | 16 +++++++++++----- .../sspanak/tt9/languages/EmojiLanguage.java | 1 + .../github/sspanak/tt9/languages/Language.java | 5 +++++ .../tt9/languages/LanguageDefinition.java | 4 ++-- .../sspanak/tt9/languages/NaturalLanguage.java | 2 ++ .../sspanak/tt9/languages/NullLanguage.java | 5 +++-- .../sspanak/tt9/util/chars/Characters.java | 8 +++++++- app/validate-languages.gradle | 1 + 19 files changed, 43 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 802565af..5c0e64bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,6 +56,7 @@ To support a new language one needs to: - For 1-key, you could use `[PUNCTUATION]` and have standard English/computer punctuation; or `[PUNCTUATION_FR]` that includes the French quotation marks: `«`, `»`; or `[PUNCTUATION_DE]` that includes the German quotation marks: `„`, `“`. And if the language has extra punctuation marks, like Spanish, you could complement the list like this: `[PUNCTUATION, ¡, ¿]`. Or you could define your own list, like for 0-key. - Keys 2 through 9, just contain the possible letters. - `abcString` _(optional)_. A custom string to display in ABC mode. By default, the first three letters on 2-key are used (e.g. "ABC" or "АБВ"). Set this if the first letters of the alphabet are _not_ on 2-key, like in Hebrew, or if a different string makes more sense. + - `currency` _(optional)_. A string representing the currency related to that language, for example: `₪`, `₩`, `﷼`, etc. The character will be displayed in position 3 between the factory currency characters. - `hasSpaceBetweenWords` _(optional)_ set to `no` when the language does not use spaces between words. For example: Thai, Chinese, Japanese, Korean, and so on. The default is `yes`. - `hasUpperCase` _(optional)_ set to `no` when the language has no upper- and lowercase letters. For example: Arabic, Hebrew, East Asian languages, and so on. The default is `yes`. - `name` _(optional)_ is automatically generated and equals the native name of the language (e.g. "English", "Deutsch", "Українська"). However, sometimes, the automatically selected name may be ambiguous. For example, both Portuguese in Portugal and Brazil will default to "Português", so assigning "Português brasileiro" would make it clear it's the language used in Brazil. diff --git a/app/languages/definitions/Arabic.yml b/app/languages/definitions/Arabic.yml index 414f9dff..7b73563a 100644 --- a/app/languages/definitions/Arabic.yml +++ b/app/languages/definitions/Arabic.yml @@ -1,4 +1,5 @@ locale: ar-JO +currency: ﷼ dictionaryFile: ar-utf8.csv abcString: أﺏﺕ hasUpperCase: no diff --git a/app/languages/definitions/Gujarati.yml b/app/languages/definitions/Gujarati.yml index 2fe119ee..5402ad81 100644 --- a/app/languages/definitions/Gujarati.yml +++ b/app/languages/definitions/Gujarati.yml @@ -1,4 +1,5 @@ locale: gu-IN +currency: ૱ dictionaryFile: gu-utf8.csv abcString: કખગ hasUpperCase: no diff --git a/app/languages/definitions/Hebrew.yml b/app/languages/definitions/Hebrew.yml index 9b0d126d..0cc7b604 100644 --- a/app/languages/definitions/Hebrew.yml +++ b/app/languages/definitions/Hebrew.yml @@ -1,4 +1,5 @@ locale: iw-IL +currency: ₪ dictionaryFile: he-utf8.csv abcString: אבג hasUpperCase: no diff --git a/app/languages/definitions/Hindi.yml b/app/languages/definitions/Hindi.yml index 387419f3..dac0144a 100644 --- a/app/languages/definitions/Hindi.yml +++ b/app/languages/definitions/Hindi.yml @@ -1,4 +1,5 @@ locale: hi-IN +currency: ₹ dictionaryFile: hi-utf8.csv abcString: कखग hasUpperCase: no diff --git a/app/languages/definitions/Korean.yml b/app/languages/definitions/Korean.yml index 2a3bcc9a..6977c8fa 100644 --- a/app/languages/definitions/Korean.yml +++ b/app/languages/definitions/Korean.yml @@ -1,4 +1,5 @@ locale: ko-KR +currency: ₩ dictionaryFile: ko-utf8.csv hasUpperCase: no layout: # only used for the virtual key labels diff --git a/app/languages/definitions/Russian.yml b/app/languages/definitions/Russian.yml index cbf32c9a..911ea204 100644 --- a/app/languages/definitions/Russian.yml +++ b/app/languages/definitions/Russian.yml @@ -1,4 +1,5 @@ locale: ru-RU +currency: ₽ dictionaryFile: ru-utf8.csv layout: - [SPECIAL] # 0 diff --git a/app/languages/definitions/Thai.yml b/app/languages/definitions/Thai.yml index b4bdc4e9..cbeb79fe 100644 --- a/app/languages/definitions/Thai.yml +++ b/app/languages/definitions/Thai.yml @@ -1,4 +1,5 @@ locale: th-TH +currency: ฿ dictionaryFile: th-utf8.csv abcString: กขค hasSpaceBetweenWords: no diff --git a/app/languages/definitions/Turkish.yml b/app/languages/definitions/Turkish.yml index 40a1894f..6410d4f1 100644 --- a/app/languages/definitions/Turkish.yml +++ b/app/languages/definitions/Turkish.yml @@ -1,4 +1,5 @@ locale: tr-TR +currency: ₺ dictionaryFile: tr-utf8.csv layout: - [SPECIAL] # 0 diff --git a/app/languages/definitions/Ukrainian.yml b/app/languages/definitions/Ukrainian.yml index f66131ee..4eb44644 100644 --- a/app/languages/definitions/Ukrainian.yml +++ b/app/languages/definitions/Ukrainian.yml @@ -1,4 +1,5 @@ locale: uk-UA +currency: ₴ dictionaryFile: uk-utf8.csv layout: - [SPECIAL] # 0 diff --git a/app/languages/definitions/Vietnamese.yml b/app/languages/definitions/Vietnamese.yml index 28d3cb55..ec7eb1ef 100644 --- a/app/languages/definitions/Vietnamese.yml +++ b/app/languages/definitions/Vietnamese.yml @@ -1,4 +1,5 @@ locale: vi-VN +currency: ₫ dictionaryFile: vi-utf8.csv layout: - [SPECIAL] # 0 diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java index a4e56da0..d1f3f2ca 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java @@ -6,6 +6,7 @@ import io.github.sspanak.tt9.hacks.InputType; import io.github.sspanak.tt9.ime.helpers.TextField; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageKind; +import io.github.sspanak.tt9.languages.NullLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.util.Text; import io.github.sspanak.tt9.util.chars.Characters; @@ -18,6 +19,7 @@ public class AutoSpace { private static final Set NO_PRECEDING_SPACE_PUNCTUATION = Set.of('.', ',', ')', '\'', '@', '“', '؟', Characters.GR_QUESTION_MARK.charAt(0)); private static final Set NOT_FRENCH_NO_PRECEDING_SPACE_PUNCTUATION = Set.of(';', ':', '!', '?', '»'); + private Language language; private final SettingsStore settings; private boolean isLanguageFrench; @@ -26,6 +28,7 @@ public class AutoSpace { public AutoSpace(SettingsStore settingsStore) { + language = new NullLanguage(); settings = settingsStore; isLanguageWithAlphabet = false; isLanguageFrench = false; @@ -33,10 +36,11 @@ public class AutoSpace { } - public AutoSpace setLanguage(Language language) { - isLanguageFrench = LanguageKind.isFrench(language); - isLanguageWithAlphabet = language != null && !language.isSyllabary(); - isLanguageWithSpaceBetweenWords = language != null && language.hasSpaceBetweenWords(); + public AutoSpace setLanguage(Language lang) { + language = language == null ? new NullLanguage() : lang; + isLanguageFrench = LanguageKind.isFrench(lang); + isLanguageWithAlphabet = !language.isSyllabary(); + isLanguageWithSpaceBetweenWords = language.hasSpaceBetweenWords(); return this; } @@ -112,7 +116,9 @@ public class AutoSpace { || (!Character.isDigit(penultimateChar) && previousChar == ':') || (!Character.isDigit(penultimateChar) && previousChar == '.') || (!Character.isDigit(penultimateChar) && previousChar == ',') - || (Character.isDigit(penultimateChar) && Characters.Currency.contains(String.valueOf(previousChar))) + || ( + Character.isDigit(penultimateChar) && Characters.isCurrency(language, String.valueOf(previousChar)) + ) ); } diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java b/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java index 6cc9bd67..c65d4697 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java @@ -18,6 +18,7 @@ public class EmojiLanguage extends Language { locale = Locale.ROOT; abcString = "emoji"; code = "emj"; + currency = ""; name = "Emoji"; } diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/Language.java b/app/src/main/java/io/github/sspanak/tt9/languages/Language.java index 700a503e..a0a4b8fa 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/Language.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/Language.java @@ -11,6 +11,7 @@ abstract public class Language { protected int id; protected String abcString; protected String code; + protected String currency; protected String dictionaryFile; protected Locale locale = Locale.ROOT; protected String name; @@ -31,6 +32,10 @@ abstract public class Language { return code; } + @NonNull public String getCurrency() { + return currency; + } + @NonNull final public String getDictionaryFile() { return dictionaryFile; } diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/LanguageDefinition.java b/app/src/main/java/io/github/sspanak/tt9/languages/LanguageDefinition.java index f5ac5eb6..5b6f354c 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/LanguageDefinition.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/LanguageDefinition.java @@ -21,6 +21,7 @@ public class LanguageDefinition extends AssetFile { private static final String definitionsDir = languagesDir + "/definitions"; public String abcString = ""; + public String currency = ""; public String dictionaryFile = ""; public boolean hasSpaceBetweenWords = true; public boolean hasUpperCase = true; @@ -90,6 +91,7 @@ public class LanguageDefinition extends AssetFile { private void parse(ArrayList yaml) { abcString = getPropertyFromYaml(yaml, "abcString", abcString); + currency = getPropertyFromYaml(yaml, "currency", currency); dictionaryFile = getPropertyFromYaml(yaml, "dictionaryFile", dictionaryFile); if (dictionaryFile != null) { @@ -102,8 +104,6 @@ public class LanguageDefinition extends AssetFile { layout = getLayoutFromYaml(yaml); locale = getPropertyFromYaml(yaml, "locale", locale); name = getPropertyFromYaml(yaml, "name", name); - - } diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java b/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java index 18a2e5f3..a83597d3 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java @@ -31,6 +31,7 @@ public class NaturalLanguage extends Language implements Comparable(); } else if (characterGroup == 1) { chars = new ArrayList<>(Characters.Currency); + if (!currency.isEmpty()) chars.add(2, currency); } } diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/NullLanguage.java b/app/src/main/java/io/github/sspanak/tt9/languages/NullLanguage.java index 2b1419a4..39208fc9 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/NullLanguage.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/NullLanguage.java @@ -7,12 +7,13 @@ import java.util.Locale; public class NullLanguage extends Language { public NullLanguage() { - locale = Locale.ROOT; - name = "Nulla Lingua"; abcString = "ABC"; code = ""; + currency = ""; dictionaryFile = ""; hasUpperCase = false; + locale = Locale.ROOT; + name = "Nulla Lingua"; } @NonNull diff --git a/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java b/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java index e71519ea..c11dbbc3 100644 --- a/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java +++ b/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java @@ -3,9 +3,11 @@ package io.github.sspanak.tt9.util.chars; import java.util.ArrayList; import java.util.Arrays; +import io.github.sspanak.tt9.languages.Language; + public class Characters extends Emoji { final public static ArrayList Currency = new ArrayList<>(Arrays.asList( - "$", "€", "₹", "₿", "₩", "¢", "¤", "₺", "₱", "¥", "₽", "£" + "$", "€", "₿", "¢", "¤", "₱", "¥", "£" )); final public static ArrayList Special = new ArrayList<>(Arrays.asList( @@ -40,4 +42,8 @@ public class Characters extends Emoji { } return keyCharacters; } + + public static boolean isCurrency(Language language, String c) { + return Currency.contains(c) || (language != null && language.getCurrency().equals(c)); + } } diff --git a/app/validate-languages.gradle b/app/validate-languages.gradle index b6ea3aaf..cd2200cd 100644 --- a/app/validate-languages.gradle +++ b/app/validate-languages.gradle @@ -62,6 +62,7 @@ ext.parseLanguageDefintion = { File languageFile, String dictionariesDir -> if ( rawLine.matches("^[a-zA-Z].*") && !rawLine.startsWith("abcString") + && !rawLine.startsWith("currency") && !rawLine.startsWith("dictionaryFile") && !rawLine.startsWith("hasSpaceBetweenWords") && !rawLine.startsWith("hasUpperCase")