added support for custom numerals in the language definitions
This commit is contained in:
parent
afa509cee0
commit
c28c9f053e
11 changed files with 56 additions and 34 deletions
|
|
@ -3,6 +3,7 @@ currency: ﷼
|
|||
dictionaryFile: ar-utf8.csv
|
||||
abcString: أﺏﺕ
|
||||
hasUpperCase: no
|
||||
numerals: [٠,١,٢,٣,٤,٥,٦,٧,٨,٩]
|
||||
layout:
|
||||
- [SPECIAL] # 0
|
||||
- [PUNCTUATION_AR] # 1
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class ModeABC extends InputMode {
|
|||
autoAcceptTimeout = 0;
|
||||
digitSequence = String.valueOf(number);
|
||||
shouldSelectNextLetter = false;
|
||||
suggestions.add(language.getKeyNumber(number));
|
||||
suggestions.add(language.getKeyNumeral(number));
|
||||
} else if (repeat > 0) {
|
||||
autoAcceptTimeout = settings.getAbcAutoAcceptTimeout();
|
||||
shouldSelectNextLetter = true;
|
||||
|
|
@ -56,7 +56,7 @@ class ModeABC extends InputMode {
|
|||
digitSequence = String.valueOf(number);
|
||||
shouldSelectNextLetter = false;
|
||||
suggestions.addAll(KEY_CHARACTERS.size() > number ? KEY_CHARACTERS.get(number) : settings.getOrderedKeyChars(language, number));
|
||||
suggestions.add(language.getKeyNumber(number));
|
||||
suggestions.add(language.getKeyNumeral(number));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -86,7 +86,7 @@ class ModeABC extends InputMode {
|
|||
return false;
|
||||
}
|
||||
|
||||
suggestions.add(language.getKeyNumber(digitSequence.charAt(0) - '0'));
|
||||
suggestions.add(language.getKeyNumeral(digitSequence.charAt(0) - '0'));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class ModeCheonjiin extends InputMode {
|
|||
digitSequence = PUNCTUATION_SEQUENCE;
|
||||
} else {
|
||||
autoAcceptTimeout = 0;
|
||||
suggestions.add(language.getKeyNumber(number));
|
||||
suggestions.add(language.getKeyNumeral(number));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class ModeWords extends ModeCheonjiin {
|
|||
@Override
|
||||
protected void onNumberHold(int number) {
|
||||
autoAcceptTimeout = 0;
|
||||
suggestions.add(language.getKeyNumber(number));
|
||||
suggestions.add(language.getKeyNumeral(number));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ abstract public class Language {
|
|||
return getKeyCharacters(key, 0);
|
||||
}
|
||||
|
||||
@NonNull public String getKeyNumber(int key) {
|
||||
@NonNull public String getKeyNumeral(int key) {
|
||||
return String.valueOf(key);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
|
|||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.github.sspanak.tt9.BuildConfig;
|
||||
import io.github.sspanak.tt9.util.AssetFile;
|
||||
|
|
@ -29,6 +30,7 @@ public class LanguageDefinition {
|
|||
public ArrayList<ArrayList<String>> layout = new ArrayList<>();
|
||||
public String locale = "";
|
||||
public String name = "";
|
||||
@NonNull public HashMap<Integer, String> numerals = new HashMap<>();
|
||||
|
||||
private boolean inLayout = false;
|
||||
|
||||
|
|
@ -125,28 +127,31 @@ public class LanguageDefinition {
|
|||
switch (key) {
|
||||
case "abcString":
|
||||
abcString = value;
|
||||
break;
|
||||
return;
|
||||
case "currency":
|
||||
currency = value;
|
||||
break;
|
||||
return;
|
||||
case "dictionaryFile":
|
||||
dictionaryFile = value.replaceFirst("\\.\\w+$", "." + BuildConfig.DICTIONARY_EXTENSION);
|
||||
break;
|
||||
return;
|
||||
case "hasSpaceBetweenWords":
|
||||
hasSpaceBetweenWords = parseYamlBoolean(value);
|
||||
break;
|
||||
return;
|
||||
case "hasUpperCase":
|
||||
hasUpperCase = parseYamlBoolean(value);
|
||||
break;
|
||||
return;
|
||||
case "sounds":
|
||||
isSyllabary = true;
|
||||
break;
|
||||
return;
|
||||
case "locale":
|
||||
locale = value;
|
||||
break;
|
||||
return;
|
||||
case "name":
|
||||
name = value;
|
||||
break;
|
||||
return;
|
||||
case "numerals":
|
||||
setNumerals(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +164,7 @@ public class LanguageDefinition {
|
|||
return inLayout = "layout:".equals(line);
|
||||
}
|
||||
|
||||
ArrayList<String> layoutEntry = getLayoutEntryFromYamlLine(line);
|
||||
ArrayList<String> layoutEntry = parseList(line);
|
||||
if (layoutEntry == null) {
|
||||
inLayout = false;
|
||||
} else {
|
||||
|
|
@ -171,13 +176,25 @@ public class LanguageDefinition {
|
|||
}
|
||||
|
||||
|
||||
private void setNumerals(@NonNull String yamlList) {
|
||||
ArrayList<String> numberList = parseList(yamlList);
|
||||
if (numberList == null || numberList.size() != 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
numerals.put(i, numberList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* getLayoutEntryFromYamlLine
|
||||
* Validates a YAML line as an array and returns the character list to be assigned to a given key (a layout entry).
|
||||
* If the YAML line is invalid, NULL will be returned.
|
||||
*/
|
||||
@Nullable
|
||||
private ArrayList<String> getLayoutEntryFromYamlLine(@NonNull String yamlLine) {
|
||||
private ArrayList<String> parseList(@NonNull String yamlLine) {
|
||||
int start = yamlLine.indexOf('[');
|
||||
int end = yamlLine.indexOf(']');
|
||||
if (start == -1 || end == -1 || start >= end) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public class NaturalLanguage extends Language implements Comparable<NaturalLangu
|
|||
|
||||
protected final ArrayList<ArrayList<String>> layout = new ArrayList<>();
|
||||
private final HashMap<Character, String> characterKeyMap = new HashMap<>();
|
||||
@NonNull private HashMap<Integer, String> numerals = new HashMap<>();
|
||||
|
||||
|
||||
public static NaturalLanguage fromDefinition(LanguageDefinition definition) throws Exception {
|
||||
|
|
@ -37,6 +38,7 @@ public class NaturalLanguage extends Language implements Comparable<NaturalLangu
|
|||
lang.hasUpperCase = definition.hasUpperCase;
|
||||
lang.isSyllabary = definition.isSyllabary;
|
||||
lang.name = definition.name.isEmpty() ? lang.name : definition.name;
|
||||
lang.numerals = definition.numerals;
|
||||
lang.setLocale(definition);
|
||||
lang.setLayout(definition);
|
||||
|
||||
|
|
@ -195,7 +197,7 @@ public class NaturalLanguage extends Language implements Comparable<NaturalLangu
|
|||
private void generateCharacterKeyMap() {
|
||||
characterKeyMap.clear();
|
||||
for (int digit = 0; digit <= 9; digit++) {
|
||||
characterKeyMap.put(getKeyNumber(digit).charAt(0), String.valueOf(digit));
|
||||
characterKeyMap.put(getKeyNumeral(digit).charAt(0), String.valueOf(digit));
|
||||
for (String keyChar : getKeyCharacters(digit)) {
|
||||
characterKeyMap.put(keyChar.charAt(0), String.valueOf(digit));
|
||||
}
|
||||
|
|
@ -224,8 +226,9 @@ public class NaturalLanguage extends Language implements Comparable<NaturalLangu
|
|||
|
||||
|
||||
@NonNull
|
||||
public String getKeyNumber(int key) {
|
||||
return key >= 0 && key < 10 && LanguageKind.isArabic(this) ? Characters.ArabicNumbers.get(key) : super.getKeyNumber(key);
|
||||
public String getKeyNumeral(int key) {
|
||||
String digit = numerals.containsKey(key) ? numerals.get(key) : null;
|
||||
return digit != null ? digit : super.getKeyNumeral(key);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ public class SoftKeyNumber extends BaseSoftKeyWithIcons {
|
|||
|
||||
|
||||
protected String getLocalizedNumber(int number) {
|
||||
if (isArabicNumber() && tt9 != null && tt9.getLanguage() != null) {
|
||||
return tt9.getLanguage().getKeyNumber(number);
|
||||
if (tt9 != null && !tt9.isInputModeNumeric() && tt9.getLanguage() != null) {
|
||||
return tt9.getLanguage().getKeyNumeral(number);
|
||||
} else {
|
||||
return String.valueOf(number);
|
||||
}
|
||||
|
|
@ -98,9 +98,4 @@ public class SoftKeyNumber extends BaseSoftKeyWithIcons {
|
|||
float defaultScale = super.getHoldElementScale();
|
||||
return tt9 != null && LanguageKind.isArabic(tt9.getLanguage()) ? defaultScale * 1.25f : defaultScale;
|
||||
}
|
||||
|
||||
|
||||
private boolean isArabicNumber() {
|
||||
return tt9 != null && !tt9.isInputModeNumeric() && LanguageKind.isArabic(tt9.getLanguage());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@ class Punctuation {
|
|||
public static final String ZWNJ = "\u200C";
|
||||
public static final String ZWNJ_GRAPHIC = "ZWNJ";
|
||||
|
||||
final public static ArrayList<String> ArabicNumbers = new ArrayList<>(Arrays.asList(
|
||||
"٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"
|
||||
));
|
||||
|
||||
final public static ArrayList<Character> CombiningPunctuation = new ArrayList<>(Arrays.asList(
|
||||
',', '-', '\'', ':', ';', '!', '?', '.'
|
||||
));
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ ext.parseLanguageDefintion = { File languageFile, String dictionariesDir ->
|
|||
|
||||
boolean hasLayout = false
|
||||
boolean hasSounds = false
|
||||
boolean isLocaleValid = false
|
||||
boolean areNumeralsValid = true
|
||||
String localeString = ""
|
||||
String dictionaryFileName = ""
|
||||
|
||||
|
|
@ -69,6 +69,7 @@ ext.parseLanguageDefintion = { File languageFile, String dictionariesDir ->
|
|||
&& !rawLine.startsWith("layout")
|
||||
&& !rawLine.startsWith("locale")
|
||||
&& !rawLine.startsWith("name")
|
||||
&& !rawLine.startsWith("numerals")
|
||||
&& !rawLine.startsWith("sounds")
|
||||
) {
|
||||
def parts = rawLine.split(":")
|
||||
|
|
@ -90,6 +91,10 @@ ext.parseLanguageDefintion = { File languageFile, String dictionariesDir ->
|
|||
errorMsg += "Language '${languageFile.name}' is invalid. Unrecognized '${property}' value: '${invalidVal}'. Only 'yes' and 'no' are allowed.\n"
|
||||
}
|
||||
|
||||
if (line.startsWith("numerals")) {
|
||||
areNumeralsValid = line.matches("^numerals:\\s*\\[(.,\\s*?){9}.\\]")
|
||||
}
|
||||
|
||||
if (line.startsWith("layout")) {
|
||||
hasLayout = true
|
||||
}
|
||||
|
|
@ -100,7 +105,6 @@ ext.parseLanguageDefintion = { File languageFile, String dictionariesDir ->
|
|||
|
||||
if (line.startsWith("locale")) {
|
||||
localeString = line.replace("locale:", "").trim()
|
||||
isLocaleValid = localeString.matches("^[a-z]{2,3}(?:-[A-Z]{2})?\$")
|
||||
}
|
||||
|
||||
if (line.startsWith("dictionaryFile")) {
|
||||
|
|
@ -146,12 +150,17 @@ ext.parseLanguageDefintion = { File languageFile, String dictionariesDir ->
|
|||
errorMsg += "Language '${languageFile.name}' is invalid. 'sounds' property must contain series of phonetic transcriptions per digit sequence in the format: ' - [Yae,1221]' and so on.\n"
|
||||
}
|
||||
|
||||
if (!isLocaleValid) {
|
||||
if (!localeString.matches("^[a-z]{2,3}(?:-[A-Z]{2})?\$")) {
|
||||
errorCount++
|
||||
def msg = localeString.isEmpty() ? "Missing 'locale' property." : "Unrecognized locale format: '${localeString}'"
|
||||
errorMsg += "Language '${languageFile.name}' is invalid. ${msg}\n"
|
||||
}
|
||||
|
||||
if (!areNumeralsValid) {
|
||||
errorCount++
|
||||
errorMsg += "Language '${languageFile.name}' is invalid. 'numerals' property must contain a comma-separated list of 10 characters representing the digits from 0 to 9.\n"
|
||||
}
|
||||
|
||||
dictionaryFile = new File("$dictionariesDir/${dictionaryFileName}")
|
||||
if (dictionaryFileName.isEmpty() || !dictionaryFile.exists()) {
|
||||
errorCount++
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue