fix isInsideDoubleQuoteOrAfterDigit not determining inside quote status correctly

happened because only quotes followed or preceded by space can be identified correctly

previously unclear quotes, e.g. followed by comma, were ignored
now the number of ignored quotes is counted and taken into account

fixes ##230
This commit is contained in:
Helium314 2023-10-24 01:06:34 +02:00
parent f1de1a6410
commit c7a8548921
3 changed files with 22 additions and 9 deletions

View file

@ -500,6 +500,9 @@ public final class StringUtils {
* double quote character, and looking at whether it's followed by whitespace. If so, that * 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 * 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. * 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. * @param text the text to examine.
* @return whether we're inside a double quote. * @return whether we're inside a double quote.
@ -514,26 +517,33 @@ public final class StringUtils {
return true; return true;
} }
int prevCodePoint = 0; int prevCodePoint = 0;
int ignoredDoubleQuoteCount = 0;
while (i > 0) { while (i > 0) {
codePoint = Character.codePointBefore(text, i); codePoint = Character.codePointBefore(text, i);
if (Constants.CODE_DOUBLE_QUOTE == codePoint) { if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
// If we see a double quote followed by whitespace, then that // If we see a double quote followed by whitespace, then that
// was a closing quote. // was a closing quote.
if (Character.isWhitespace(prevCodePoint)) { if (Character.isWhitespace(prevCodePoint)) {
return false; return ignoredDoubleQuoteCount % 2 == 1;
} }
} }
if (Character.isWhitespace(codePoint) && Constants.CODE_DOUBLE_QUOTE == prevCodePoint) { if (Character.isWhitespace(codePoint) && Constants.CODE_DOUBLE_QUOTE == prevCodePoint) {
// If we see a double quote preceded by whitespace, then that // If we see a double quote preceded by whitespace, then that
// was an opening quote. No need to continue seeking. // 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); i -= Character.charCount(codePoint);
prevCodePoint = codePoint; prevCodePoint = codePoint;
} }
// We reached the start of text. If the first char is a double quote, then we're inside // 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. // a double quote. Otherwise we're not.
if (ignoredDoubleQuoteCount % 2 == 0)
return Constants.CODE_DOUBLE_QUOTE == codePoint; return Constants.CODE_DOUBLE_QUOTE == codePoint;
else
return Constants.CODE_DOUBLE_QUOTE != codePoint;
} }
public static boolean isEmptyStringOrWhiteSpaces(@NonNull final String s) { public static boolean isEmptyStringOrWhiteSpaces(@NonNull final String s) {

View file

@ -133,6 +133,7 @@ class InputLogicTest {
} }
// todo: make it work, but it might not be that simple because adding is done in combiner // 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() { @Test fun insertLetterIntoWordHangul() {
reset() reset()
currentScript = ScriptUtils.SCRIPT_HANGUL currentScript = ScriptUtils.SCRIPT_HANGUL
@ -511,7 +512,6 @@ class InputLogicTest {
} }
// https://github.com/Helium314/openboard/issues/230 // https://github.com/Helium314/openboard/issues/230
// todo: make it work
@Test fun `no autospace after opening quotes`() { @Test fun `no autospace after opening quotes`() {
reset() reset()
chainInput("\"Hi\" \"h") chainInput("\"Hi\" \"h")
@ -520,7 +520,7 @@ class InputLogicTest {
reset() reset()
chainInput("\"Hi\", \"h") chainInput("\"Hi\", \"h")
assertEquals("\"Hi\", \"h", text) assertEquals("\"Hi\", \"h", text)
assertEquals("", composingText) assertEquals("h", composingText)
} }
// ------- helper functions --------- // ------- helper functions ---------

View file

@ -13,17 +13,20 @@ class StringUtilsTest {
assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes")) 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 // maybe this is not that bad, should be correct after entering next text
@Test fun `not inside double quotes directly after closing quote`() { @Test fun `not inside double quotes directly after closing quote`() {
assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\"")) 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\" ")) assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\" "))
} }
// todo: fix it! @Test fun `not inside double quotes after closing quote followed by comma`() {
@Test fun `not inside double quotes after closing quote1`() {
assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", ")) assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", "))
} }
@ -31,7 +34,7 @@ class StringUtilsTest {
assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\" \"h")) 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")) assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", \"h"))
} }