diff options
author | Stefan Niedermann <info@niedermann.it> | 2020-12-17 16:20:54 +0300 |
---|---|---|
committer | Niedermann IT-Dienstleistungen <stefan-niedermann@users.noreply.github.com> | 2020-12-17 18:14:29 +0300 |
commit | e8203720058f00f941593b492ae4b031397c949f (patch) | |
tree | 73e2ffa4d8ce4165794f1f64f69215b6a931125b | |
parent | 268c106ce811f38f7281ac760d686d8fb1c31a77 (diff) |
Handle contained punctuation better
Signed-off-by: Stefan Niedermann <info@niedermann.it>
2 files changed, 53 insertions, 22 deletions
diff --git a/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java b/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java index c0e32ea34..ca70fe19a 100644 --- a/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java +++ b/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java @@ -197,20 +197,30 @@ public class MarkwonMarkdownUtilTest extends TestCase { // Text is not directly surrounded by punctuation but contains it - // TODO Remove containing punctuation -// builder = new StringBuilder("Lorem *ipsum* dolor sit amet."); -// assertEquals(11, MarkwonMarkdownUtil.togglePunctuation(builder, 6, 13, "*")); -// assertEquals("Lorem ipsum dolor sit amet.", builder.toString()); + // Do nothing when the same punctuation is contained only one time + builder = new StringBuilder("Lorem *ipsum dolor sit amet."); + assertEquals(28, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 28, "*")); + assertEquals("Lorem *ipsum dolor sit amet.", builder.toString()); - // TODO Remove containing punctuation -// builder = new StringBuilder("Lorem *ipsum* dolor sit amet."); -// assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 29, "*")); -// assertEquals("Lorem ipsum dolor sit amet.", builder.toString()); + // Do nothing when the same punctuation is contained only one time + builder = new StringBuilder("Lorem **ipsum dolor sit amet."); + assertEquals(29, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 29, "**")); + assertEquals("Lorem **ipsum dolor sit amet.", builder.toString()); + + // Remove containing punctuation + builder = new StringBuilder("Lorem *ipsum* dolor sit amet."); + assertEquals(11, MarkwonMarkdownUtil.togglePunctuation(builder, 6, 13, "*")); + assertEquals("Lorem ipsum dolor sit amet.", builder.toString()); - // TODO Remove multiple containing punctuations -// builder = new StringBuilder("Lorem *ipsum* dolor *sit* amet."); -// assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 31, "*")); -// assertEquals("Lorem ipsum dolor sit amet.", builder.toString()); + // Remove containing punctuation + builder = new StringBuilder("Lorem *ipsum* dolor sit amet."); + assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 29, "*")); + assertEquals("Lorem ipsum dolor sit amet.", builder.toString()); + + // Remove multiple containing punctuations + builder = new StringBuilder("Lorem *ipsum* dolor *sit* amet."); + assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 31, "*")); + assertEquals("Lorem ipsum dolor sit amet.", builder.toString()); // TODO Toggle bold to italic // builder = new StringBuilder("Lorem **ipsum** dolor sit amet."); @@ -221,11 +231,6 @@ public class MarkwonMarkdownUtilTest extends TestCase { // builder = new StringBuilder("Lorem **ipsum** dolor **sit** amet."); // assertEquals(31, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 35, "*")); // assertEquals("Lorem *ipsum* dolor *sit* amet.", builder.toString()); - - // TODO Do nothing -// builder = new StringBuilder("Lorem *ipsum dolor sit amet."); -// assertEquals(28, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 28, "*")); -// assertEquals("Lorem *ipsum dolor sit amet.", builder.toString()); } @Test diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java index fe28ac0b5..61809091d 100644 --- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java +++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java @@ -130,11 +130,20 @@ public class MarkwonMarkdownUtil { if (selectionIsSurroundedByPunctuation) { builder.delete(selectionEnd, selectionEnd + punctuation.length()); builder.delete(selectionStart - punctuation.length(), selectionStart); + return selectionEnd - punctuation.length(); } else { - builder.insert(selectionEnd, punctuation); - builder.insert(selectionStart, punctuation); + final int containedPunctuationCount = getContainedPunctuationCount(builder.toString(), selectionStart, selectionEnd, punctuation); + if (containedPunctuationCount == 0) { + builder.insert(selectionEnd, punctuation); + builder.insert(selectionStart, punctuation); + return selectionEnd + punctuation.length() * 2; + } else if (containedPunctuationCount % 2 > 0) { + return selectionEnd; + } else { + removeContainingPunctuation(builder, selectionStart, selectionEnd, punctuation); + return selectionEnd - containedPunctuationCount * punctuation.length(); + } } - return selectionIsSurroundedByPunctuation ? selectionEnd - punctuation.length() : selectionEnd + punctuation.length() * 2; } default: throw new UnsupportedOperationException("This kind of punctuation is not yet supported: " + punctuation); @@ -187,9 +196,26 @@ public class MarkwonMarkdownUtil { && punctuation.contentEquals(text.subSequence(end, end + punctuation.length())); } + private static int getContainedPunctuationCount(@NonNull CharSequence text, int start, int end, @NonNull String punctuation) { + final Matcher matcher = Pattern.compile(Pattern.quote(punctuation)).matcher(text.subSequence(start, end)); + int counter = 0; + while (matcher.find()) { + counter++; + } + return counter; + } + + private static void removeContainingPunctuation(@NonNull StringBuilder builder, int start, int end, @NonNull String punctuation) { + final Matcher matcher = Pattern.compile(Pattern.quote(punctuation)).matcher(builder.toString().subSequence(start, end)); + int countDeletedPunctuations = 0; + while (matcher.find()) { + builder.delete(start + matcher.start() - countDeletedPunctuations * punctuation.length(), start + matcher.end() - countDeletedPunctuations * punctuation.length()); + countDeletedPunctuations++; + } + } + public static boolean selectionIsInLink(@NonNull CharSequence text, int start, int end) { - final Pattern pattern = Pattern.compile("\\[(.+)?]\\(([^ ]+?)?( \"(.+)\")?\\)"); - final Matcher matcher = pattern.matcher(text); + final Matcher matcher = Pattern.compile("\\[(.+)?]\\(([^ ]+?)?( \"(.+)\")?\\)").matcher(text); while (matcher.find()) { if ((start >= matcher.start() && start < matcher.end()) || (end > matcher.start() && end <= matcher.end())) { return true; |