diff --git a/java/res/values-el/donottranslate-config-spacing-and-punctuations.xml b/java/res/values-el/donottranslate-config-spacing-and-punctuations.xml new file mode 100644 index 000000000..117c075a6 --- /dev/null +++ b/java/res/values-el/donottranslate-config-spacing-and-punctuations.xml @@ -0,0 +1,23 @@ + + + + + .;!? + diff --git a/java/res/values/donottranslate-config-spacing-and-punctuations.xml b/java/res/values/donottranslate-config-spacing-and-punctuations.xml index 2faf578d2..06144d021 100644 --- a/java/res/values/donottranslate-config-spacing-and-punctuations.xml +++ b/java/res/values/donottranslate-config-spacing-and-punctuations.xml @@ -33,9 +33,14 @@ "  "()[]{}*&<>+=|.,;:!?/_\" \'- - + 46 + + + 46 + + .?! true diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java index b8d2a2248..8f2e9de61 100644 --- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java +++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java @@ -35,6 +35,8 @@ public final class SpacingAndPunctuations { public final int[] mSortedWordSeparators; public final PunctuationSuggestions mSuggestPuncList; private final int mSentenceSeparator; + private final int mAbbreviationMarker; + private final int[] mSortedSentenceTerminators; public final String mSentenceSeparatorAndSpace; public final boolean mCurrentLanguageHasSpaces; public final boolean mUsesAmericanTypography; @@ -54,7 +56,10 @@ public final class SpacingAndPunctuations { res.getString(R.string.symbols_word_connectors)); mSortedWordSeparators = StringUtils.toSortedCodePointArray( res.getString(R.string.symbols_word_separators)); + mSortedSentenceTerminators = StringUtils.toSortedCodePointArray( + res.getString(R.string.symbols_sentence_terminators)); mSentenceSeparator = res.getInteger(R.integer.sentence_separator); + mAbbreviationMarker = res.getInteger(R.integer.abbreviation_marker); mSentenceSeparatorAndSpace = new String(new int[] { mSentenceSeparator, Constants.CODE_SPACE }, 0, 2); mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces); @@ -92,6 +97,14 @@ public final class SpacingAndPunctuations { return Arrays.binarySearch(mSortedSymbolsClusteringTogether, code) >= 0; } + public boolean isSentenceTerminator(final int code) { + return Arrays.binarySearch(mSortedSentenceTerminators, code) >= 0; + } + + public boolean isAbbreviationMarker(final int code) { + return code == mAbbreviationMarker; + } + public boolean isSentenceSeparator(final int code) { return code == mSentenceSeparator; } diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java index 92bd02c54..02f1c5f00 100644 --- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java @@ -213,13 +213,22 @@ public final class CapsModeUtils { char c = cs.charAt(--j); // We found the next interesting chunk of text ; next we need to determine if it's the - // end of a sentence. If we have a question mark or an exclamation mark, it's the end of - // a sentence. If it's neither, the only remaining case is the period so we get the opposite - // case out of the way. - if (c == Constants.CODE_QUESTION_MARK || c == Constants.CODE_EXCLAMATION_MARK) { + // end of a sentence. If we have a sentence terminator (typically a question mark or an + // exclamation mark), then it's the end of a sentence; however, we treat the abbreviation + // marker specially because usually is the same char as the sentence separator (the + // period in most languages) and in this case we need to apply a heuristic to determine + // in which of these senses it's used. + if (spacingAndPunctuations.isSentenceTerminator(c) + && !spacingAndPunctuations.isAbbreviationMarker(c)) { return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS | TextUtils.CAP_MODE_SENTENCES) & reqModes; } + // If we reach here, we know we have whitespace before the cursor and before that there + // is something that either does not terminate the sentence, or a symbol preceded by the + // start of the text, or it's the sentence separator AND it happens to be the same code + // point as the abbreviation marker. + // If it's a symbol or something that does not terminate the sentence, then we need to + // return caps for MODE_CHARACTERS and MODE_WORDS, but not for MODE_SENTENCES. if (!spacingAndPunctuations.isSentenceSeparator(c) || j <= 0) { return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes; } diff --git a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java index 5d3664765..4646a823d 100644 --- a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java @@ -136,5 +136,17 @@ public class CapsModeUtilsTests extends AndroidTestCase { allPathsForCaps("Word; ", c | w, sp, false); allPathsForCaps("Word;", c | w, sp, true); allPathsForCaps("Word;", c, sp, false); + // Test for sentence terminators in Greek + sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("el")); + allPathsForCaps("Word? ", c | w | s, sp, false); + allPathsForCaps("Word?", c | w | s, sp, true); + allPathsForCaps("Word?", c, sp, false); + allPathsForCaps("Word! ", c | w | s, sp, false); + allPathsForCaps("Word!", c | w | s, sp, true); + allPathsForCaps("Word!", c, sp, false); + // In Greek ";" is the question mark and it terminates the sentence + allPathsForCaps("Word; ", c | w | s, sp, false); + allPathsForCaps("Word;", c | w | s, sp, true); + allPathsForCaps("Word;", c, sp, false); } }