1
0
Fork 0

fixed incorrect displaying of word + punctuation in Hindi

This commit is contained in:
sspanak 2024-12-16 16:42:59 +02:00 committed by Dimo Karaivanov
parent 55038c4719
commit 19fa3dc772
18 changed files with 203 additions and 173 deletions

View file

@ -8,8 +8,8 @@ import io.github.sspanak.tt9.hacks.InputType;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.NaturalLanguage;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.TextTools;
import io.github.sspanak.tt9.util.chars.Characters;
class Mode123 extends ModePassthrough {
@Override public int getId() { return MODE_123; }

View file

@ -10,7 +10,7 @@ import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageKind;
import io.github.sspanak.tt9.languages.NaturalLanguage;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.chars.Characters;
class ModeABC extends InputMode {
private final ArrayList<ArrayList<String>> KEY_CHARACTERS = new ArrayList<>();

View file

@ -17,8 +17,8 @@ import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.languages.LanguageKind;
import io.github.sspanak.tt9.languages.NaturalLanguage;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.TextTools;
import io.github.sspanak.tt9.util.chars.Characters;
class ModeCheonjiin extends InputMode {
// used when we want do display a different set of characters for a given key, for example

View file

@ -7,8 +7,8 @@ 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.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.Text;
import io.github.sspanak.tt9.util.chars.Characters;
public class AutoSpace {
private static final Set<Character> PRECEDING_SPACE_PUNCTUATION = Set.of('(', '«', '„');

View file

@ -7,8 +7,8 @@ import io.github.sspanak.tt9.ime.helpers.TextField;
import io.github.sspanak.tt9.languages.EmojiLanguage;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.TextTools;
import io.github.sspanak.tt9.util.chars.Characters;
public class WordPredictions extends Predictions {
private final TextField textField;

View file

@ -5,8 +5,8 @@ import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Locale;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.TextTools;
import io.github.sspanak.tt9.util.chars.Characters;
public class EmojiLanguage extends Language {
final public static String EMOJI_SEQUENCE = "11";

View file

@ -9,9 +9,9 @@ import java.util.Locale;
import java.util.Map;
import io.github.sspanak.tt9.languages.exceptions.InvalidLanguageCharactersException;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.Text;
import io.github.sspanak.tt9.util.TextTools;
import io.github.sspanak.tt9.util.chars.Characters;
public class NaturalLanguage extends Language implements Comparable<NaturalLanguage> {

View file

@ -20,9 +20,9 @@ import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.ime.TraditionalT9;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.ui.Vibration;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.Logger;
import io.github.sspanak.tt9.util.Text;
import io.github.sspanak.tt9.util.chars.Characters;
public class SoftKey extends androidx.appcompat.widget.AppCompatButton implements View.OnTouchListener, View.OnLongClickListener {
private final String LOG_TAG = getClass().getSimpleName();

View file

@ -4,7 +4,7 @@ import android.content.Context;
import android.util.AttributeSet;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.chars.Characters;
public class SoftKeyF5 extends SoftKeyFn {
public SoftKeyF5(Context context) {

View file

@ -10,7 +10,7 @@ import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.widget.TextViewCompat;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.chars.Characters;
public class SoftKeyFn extends SoftKeyNumber {
public SoftKeyFn(Context context) { super(context);}

View file

@ -5,7 +5,7 @@ import android.util.AttributeSet;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.languages.LanguageKind;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.chars.Characters;
public class SoftKeyPunctuation extends SoftKey {
public SoftKeyPunctuation(Context context) {

View file

@ -21,12 +21,12 @@ import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.ui.Vibration;
import io.github.sspanak.tt9.ui.main.ResizableMainView;
import io.github.sspanak.tt9.util.Characters;
import io.github.sspanak.tt9.util.chars.Characters;
public class SuggestionsBar {
private final String STEM_SUFFIX = "… +";
private final String STEM_VARIATION_PREFIX = "";
private final String STEM_PUNCTUATION_VARIATION_PREFIX = " ";
private final String STEM_PUNCTUATION_VARIATION_PREFIX = "";
@NonNull private String stem = "";
private double lastClickTime = 0;
@ -199,7 +199,11 @@ public class SuggestionsBar {
// shorten the stem variations
if (!stem.isEmpty() && suggestion.length() == stem.length() + 1 && suggestion.toLowerCase().startsWith(stem.toLowerCase())) {
String trimmedSuggestion = suggestion.substring(stem.length());
trimmedSuggestion = Character.isAlphabetic(trimmedSuggestion.charAt(0)) ? STEM_VARIATION_PREFIX + trimmedSuggestion : STEM_PUNCTUATION_VARIATION_PREFIX + trimmedSuggestion;
char firstChar = trimmedSuggestion.charAt(0);
String prefix = Character.isAlphabetic(firstChar) && !Characters.isCombiningPunctuation(firstChar) ? STEM_VARIATION_PREFIX : STEM_PUNCTUATION_VARIATION_PREFIX;
trimmedSuggestion = prefix + trimmedSuggestion;
suggestions.add(trimmedSuggestion);
return;
}

View file

@ -1,159 +0,0 @@
package io.github.sspanak.tt9.util;
import android.graphics.Paint;
import android.os.Build;
import java.util.ArrayList;
import java.util.Arrays;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageKind;
public class Characters {
public static final String GR_QUESTION_MARK = ";";
public static final String NEW_LINE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && new Paint().hasGlyph("") ? "" : "\\n";
public static final String ZWJ = "\u200D";
public static final String ZWJ_GRAPHIC = "ZWJ";
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(
',', '-', '\'', ':', ';', '!', '?', '.'
));
final public static ArrayList<Character> CombiningPunctuationHebrew = new ArrayList<>(Arrays.asList(
',' , '-', '\'', ':', ';', '!', '?', '.', '"',
'·', GR_QUESTION_MARK.charAt(0), // Greek
'،', '؛', ':', '!', '؟' // Arabic
));
final public static ArrayList<String> PunctuationArabic = new ArrayList<>(Arrays.asList(
"،", ".", "-", "(", ")", "&", "~", "`", "'", "\"", "؛", ":", "!", "؟"
));
final public static ArrayList<String> PunctuationEnglish = new ArrayList<>(Arrays.asList(
",", ".", "-", "(", ")", "&", "~", "`", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> PunctuationFrench = new ArrayList<>(Arrays.asList(
",", ".", "-", "«", "»", "(", ")", "&", "`", "~", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> PunctuationGerman = new ArrayList<>(Arrays.asList(
",", ".", "-", "", "", "(", ")", "&", "~", "`", "'", "\"", ";", ":", "!", "?"
));
final public static ArrayList<String> PunctuationGreek = new ArrayList<>(Arrays.asList(
",", ".", "-", "«", "»", "(", ")", "&", "~", "`", "'", "\"", "·", ":", "!", GR_QUESTION_MARK
));
final public static ArrayList<String> PunctuationIndic = new ArrayList<>(Arrays.asList(
",", ".", "-", ZWJ, ZWNJ, "(", ")", "", "", "", "&", "~", "`", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> PunctuationKorean = new ArrayList<>(Arrays.asList(
",", ".", "~", "1", "(", ")", "&", "-", "`", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> Currency = new ArrayList<>(Arrays.asList(
"$", "", "", "", "", "¢", "¤", "", "", "¥", "", "£"
));
final public static ArrayList<String> Special = new ArrayList<>(Arrays.asList(
" ", "\n", "@", "_", "#", "%", "[", "]", "{", "}", "§", "|", "^", "<", ">", "\\", "/", "=", "*", "+"
));
/**
* The English punctuation filtered to contain only valid email characters.
*/
final public static ArrayList<ArrayList<String>> Email = new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList("@", "_", "#", "%", "{", "}", "|", "^", "/", "=", "*", "+")),
new ArrayList<>(Arrays.asList(".", "-", "&", "~", "`", "'", "!", "?"))
));
/**
* Special characters for phone number fields, including both characters for conveniently typing a phone number: "()-",
* as well as command characters such as "," = "slight pause" and ";" = "wait" used in Japan and some other countries.
*/
final public static ArrayList<ArrayList<String>> Phone = new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList("+", " ")),
new ArrayList<>(Arrays.asList("-", "(", ")", ".", ";", ","))
));
/**
* Special characters for all kinds of numeric fields: integer, decimal with +/- included as necessary.
*/
public static ArrayList<ArrayList<String>> getNumberSpecialCharacters(boolean decimal, boolean signed) {
ArrayList<ArrayList<String>> keyCharacters = new ArrayList<>();
keyCharacters.add(signed ? new ArrayList<>(Arrays.asList("-", "+")) : new ArrayList<>());
if (decimal) {
keyCharacters.add(new ArrayList<>(Arrays.asList(".", ",")));
}
return keyCharacters;
}
final private static ArrayList<String> TextEmoticons = new ArrayList<>(Arrays.asList(
":)", ":D", ":P", ";)", "\\m/", ":-O", ":|", ":("
));
final private static ArrayList<ArrayList<String>> Emoji = new ArrayList<>(Arrays.asList(
// positive
new ArrayList<>(Arrays.asList(
"🙂", "😀", "🤣", "🤓", "😎", "😛", "😉"
)),
// negative
new ArrayList<>(Arrays.asList(
"🙁", "😢", "😭", "😱", "😲", "😳", "😐", "😠"
)),
// hands
new ArrayList<>(Arrays.asList(
"👍", "👋", "✌️", "👏", "🖖", "🤘", "🤝", "💪", "👎"
)),
// emotions
new ArrayList<>(Arrays.asList(
"", "🤗", "😍", "😘", "😇", "😈", "🍺", "🎉", "🥱", "🤔", "🥶", "😬"
))
));
public static boolean isGraphic(char ch) {
return !(ch < 256 || Character.isLetterOrDigit(ch) || Character.isAlphabetic(ch));
}
public static boolean noEmojiSupported() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M;
}
public static ArrayList<String> getEmoji(int level) {
if (noEmojiSupported()) {
return new ArrayList<>(TextEmoticons);
}
if (level < 0 || level >= Emoji.size()) {
return new ArrayList<>();
}
Paint paint = new Paint();
ArrayList<String> availableEmoji = new ArrayList<>();
for (String emoji : Emoji.get(level)) {
if (paint.hasGlyph(emoji)) {
availableEmoji.add(emoji);
}
}
return availableEmoji.isEmpty() ? new ArrayList<>(TextEmoticons) : availableEmoji;
}
public static int getMaxEmojiLevel() {
return Emoji.size();
}
public static boolean isCombiningPunctuation(Language language, char ch) {
return
CombiningPunctuation.contains(ch)
|| (LanguageKind.isHebrew(language) && CombiningPunctuationHebrew.contains(ch));
}
}

View file

@ -6,6 +6,7 @@ import java.util.Locale;
import io.github.sspanak.tt9.ime.modes.InputMode;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.util.chars.Characters;
public class Text extends TextTools {
private final Language language;

View file

@ -8,6 +8,8 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;
import io.github.sspanak.tt9.util.chars.Characters;
public class TextTools {
private static final Pattern containsOtherThan1 = Pattern.compile("[02-9]");
private static final Pattern combiningString = Pattern.compile("^\\p{M}+$");

View file

@ -0,0 +1,43 @@
package io.github.sspanak.tt9.util.chars;
import java.util.ArrayList;
import java.util.Arrays;
public class Characters extends Emoji {
final public static ArrayList<String> Currency = new ArrayList<>(Arrays.asList(
"$", "", "", "", "", "¢", "¤", "", "", "¥", "", "£"
));
final public static ArrayList<String> Special = new ArrayList<>(Arrays.asList(
" ", "\n", "@", "_", "#", "%", "[", "]", "{", "}", "§", "|", "^", "<", ">", "\\", "/", "=", "*", "+"
));
/**
* The English punctuation filtered to contain only valid email characters.
*/
final public static ArrayList<ArrayList<String>> Email = new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList("@", "_", "#", "%", "{", "}", "|", "^", "/", "=", "*", "+")),
new ArrayList<>(Arrays.asList(".", "-", "&", "~", "`", "'", "!", "?"))
));
/**
* Special characters for phone number fields, including both characters for conveniently typing a phone number: "()-",
* as well as command characters such as "," = "slight pause" and ";" = "wait" used in Japan and some other countries.
*/
final public static ArrayList<ArrayList<String>> Phone = new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList("+", " ")),
new ArrayList<>(Arrays.asList("-", "(", ")", ".", ";", ","))
));
/**
* Special characters for all kinds of numeric fields: integer, decimal with +/- included as necessary.
*/
public static ArrayList<ArrayList<String>> getNumberSpecialCharacters(boolean decimal, boolean signed) {
ArrayList<ArrayList<String>> keyCharacters = new ArrayList<>();
keyCharacters.add(signed ? new ArrayList<>(Arrays.asList("-", "+")) : new ArrayList<>());
if (decimal) {
keyCharacters.add(new ArrayList<>(Arrays.asList(".", ",")));
}
return keyCharacters;
}
}

View file

@ -0,0 +1,64 @@
package io.github.sspanak.tt9.util.chars;
import android.graphics.Paint;
import android.os.Build;
import java.util.ArrayList;
import java.util.Arrays;
class Emoji extends Punctuation {
final private static ArrayList<String> TextEmoticons = new ArrayList<>(Arrays.asList(
":)", ":D", ":P", ";)", "\\m/", ":-O", ":|", ":("
));
final private static ArrayList<ArrayList<String>> Emoji = new ArrayList<>(Arrays.asList(
// positive
new ArrayList<>(Arrays.asList(
"🙂", "😀", "🤣", "🤓", "😎", "😛", "😉"
)),
// negative
new ArrayList<>(Arrays.asList(
"🙁", "😢", "😭", "😱", "😲", "😳", "😐", "😠"
)),
// hands
new ArrayList<>(Arrays.asList(
"👍", "👋", "✌️", "👏", "🖖", "🤘", "🤝", "💪", "👎"
)),
// emotions
new ArrayList<>(Arrays.asList(
"", "🤗", "😍", "😘", "😇", "😈", "🍺", "🎉", "🥱", "🤔", "🥶", "😬"
))
));
public static boolean isGraphic(char ch) {
return !(ch < 256 || Character.isLetterOrDigit(ch) || Character.isAlphabetic(ch));
}
public static boolean noEmojiSupported() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M;
}
public static ArrayList<String> getEmoji(int level) {
if (noEmojiSupported()) {
return new ArrayList<>(TextEmoticons);
}
if (level < 0 || level >= Emoji.size()) {
return new ArrayList<>();
}
Paint paint = new Paint();
ArrayList<String> availableEmoji = new ArrayList<>();
for (String emoji : Emoji.get(level)) {
if (paint.hasGlyph(emoji)) {
availableEmoji.add(emoji);
}
}
return availableEmoji.isEmpty() ? new ArrayList<>(TextEmoticons) : availableEmoji;
}
public static int getMaxEmojiLevel() {
return Emoji.size();
}
}

View file

@ -0,0 +1,75 @@
package io.github.sspanak.tt9.util.chars;
import android.graphics.Paint;
import android.os.Build;
import java.util.ArrayList;
import java.util.Arrays;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageKind;
class Punctuation {
public static final String GR_QUESTION_MARK = ";";
public static final String NEW_LINE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && new Paint().hasGlyph("") ? "" : "\\n";
public static final String ZWJ = "\u200D";
public static final String ZWJ_GRAPHIC = "ZWJ";
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(
',', '-', '\'', ':', ';', '!', '?', '.'
));
final private static ArrayList<Character> CombiningPunctuationIndic = new ArrayList<>(Arrays.asList(
'्', '़', 'ऽ', '', '।', '॰', '॥'
));
final private static ArrayList<Character> CombiningPunctuationHebrew = new ArrayList<>(Arrays.asList(
',' , '-', '\'', ':', ';', '!', '?', '.', '"'
));
final public static ArrayList<String> PunctuationArabic = new ArrayList<>(Arrays.asList(
"،", ".", "-", "(", ")", "&", "~", "`", "'", "\"", "؛", ":", "!", "؟"
));
final public static ArrayList<String> PunctuationEnglish = new ArrayList<>(Arrays.asList(
",", ".", "-", "(", ")", "&", "~", "`", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> PunctuationFrench = new ArrayList<>(Arrays.asList(
",", ".", "-", "«", "»", "(", ")", "&", "`", "~", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> PunctuationGerman = new ArrayList<>(Arrays.asList(
",", ".", "-", "", "", "(", ")", "&", "~", "`", "'", "\"", ";", ":", "!", "?"
));
final public static ArrayList<String> PunctuationGreek = new ArrayList<>(Arrays.asList(
",", ".", "-", "«", "»", "(", ")", "&", "~", "`", "'", "\"", "·", ":", "!", GR_QUESTION_MARK
));
final public static ArrayList<String> PunctuationIndic = new ArrayList<>(Arrays.asList(
",", ".", "-", ZWJ, ZWNJ, "(", ")", "", "", "", "&", "~", "`", ";", ":", "'", "\"", "!", "?"
));
final public static ArrayList<String> PunctuationKorean = new ArrayList<>(Arrays.asList(
",", ".", "~", "1", "(", ")", "&", "-", "`", ";", ":", "'", "\"", "!", "?"
));
public static boolean isCombiningPunctuation(Language language, char ch) {
return
CombiningPunctuation.contains(ch)
|| (LanguageKind.isIndic(language) && CombiningPunctuationIndic.contains(ch))
|| (LanguageKind.isHebrew(language) && CombiningPunctuationHebrew.contains(ch));
}
public static boolean isCombiningPunctuation(char ch) {
return CombiningPunctuation.contains(ch) || CombiningPunctuationIndic.contains(ch) || CombiningPunctuationHebrew.contains(ch);
}
}