diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java index 6acf1cdae..19003683c 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/common/StringUtils.java @@ -500,6 +500,9 @@ public final class StringUtils { * double quote character, and looking at whether it's followed by whitespace. If so, that * was a closing quotation mark, so we're not inside a double quote. If it's not followed * by whitespace, then it was an opening quotation mark, and we're inside a quotation. + * However, on the way to the double quote we can determine, some double quotes might be + * ignored, e.g. because they are followed by punctuation. These double quotes are counted and + * taken into account. * * @param text the text to examine. * @return whether we're inside a double quote. @@ -514,26 +517,33 @@ public final class StringUtils { return true; } int prevCodePoint = 0; + int ignoredDoubleQuoteCount = 0; while (i > 0) { codePoint = Character.codePointBefore(text, i); if (Constants.CODE_DOUBLE_QUOTE == codePoint) { // If we see a double quote followed by whitespace, then that // was a closing quote. if (Character.isWhitespace(prevCodePoint)) { - return false; + return ignoredDoubleQuoteCount % 2 == 1; } } if (Character.isWhitespace(codePoint) && Constants.CODE_DOUBLE_QUOTE == prevCodePoint) { // If we see a double quote preceded by whitespace, then that // was an opening quote. No need to continue seeking. - return true; + return ignoredDoubleQuoteCount % 2 == 0; + } + if (Constants.CODE_DOUBLE_QUOTE == prevCodePoint) { + ignoredDoubleQuoteCount++; } i -= Character.charCount(codePoint); prevCodePoint = codePoint; } // We reached the start of text. If the first char is a double quote, then we're inside // a double quote. Otherwise we're not. - return Constants.CODE_DOUBLE_QUOTE == codePoint; + if (ignoredDoubleQuoteCount % 2 == 0) + return Constants.CODE_DOUBLE_QUOTE == codePoint; + else + return Constants.CODE_DOUBLE_QUOTE != codePoint; } public static boolean isEmptyStringOrWhiteSpaces(@NonNull final String s) { diff --git a/app/src/test/java/org/dslul/openboard/inputmethod/latin/InputLogicTest.kt b/app/src/test/java/org/dslul/openboard/inputmethod/latin/InputLogicTest.kt index e6a182617..e74ffc63f 100644 --- a/app/src/test/java/org/dslul/openboard/inputmethod/latin/InputLogicTest.kt +++ b/app/src/test/java/org/dslul/openboard/inputmethod/latin/InputLogicTest.kt @@ -133,6 +133,7 @@ class InputLogicTest { } // todo: make it work, but it might not be that simple because adding is done in combiner + // https://github.com/Helium314/openboard/issues/214 @Test fun insertLetterIntoWordHangul() { reset() currentScript = ScriptUtils.SCRIPT_HANGUL @@ -511,7 +512,6 @@ class InputLogicTest { } // https://github.com/Helium314/openboard/issues/230 - // todo: make it work @Test fun `no autospace after opening quotes`() { reset() chainInput("\"Hi\" \"h") @@ -520,7 +520,7 @@ class InputLogicTest { reset() chainInput("\"Hi\", \"h") assertEquals("\"Hi\", \"h", text) - assertEquals("", composingText) + assertEquals("h", composingText) } // ------- helper functions --------- diff --git a/app/src/test/java/org/dslul/openboard/inputmethod/latin/StringUtilsTest.kt b/app/src/test/java/org/dslul/openboard/inputmethod/latin/StringUtilsTest.kt index d9d399718..8b84a1750 100644 --- a/app/src/test/java/org/dslul/openboard/inputmethod/latin/StringUtilsTest.kt +++ b/app/src/test/java/org/dslul/openboard/inputmethod/latin/StringUtilsTest.kt @@ -13,17 +13,20 @@ class StringUtilsTest { assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes")) } + @Test fun `inside double quotes with quote at start`() { + assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("\"hello yes")) + } + // maybe this is not that bad, should be correct after entering next text @Test fun `not inside double quotes directly after closing quote`() { assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\"")) } - @Test fun `not inside double quotes after closing quote0`() { + @Test fun `not inside double quotes after closing quote`() { assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\" ")) } - // todo: fix it! - @Test fun `not inside double quotes after closing quote1`() { + @Test fun `not inside double quotes after closing quote followed by comma`() { assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", ")) } @@ -31,7 +34,7 @@ class StringUtilsTest { assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\" \"h")) } - @Test fun `inside double quotes after opening another quote2`() { + @Test fun `inside double quotes after opening another quote with closing quote followed by comma`() { assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", \"h")) }