return line.length();
}
int nextWhitespace = matcher.start();
+ int lastPunctuation = nextWhitespace;
+ while (isPunctuation(line.charAt(lastPunctuation - 1))) {
+ lastPunctuation -= 1;
+ }
+ if (lastPunctuation < nextWhitespace) {
+ return lastPunctuation;
+ }
int openParens = 0;
for (int i = 0; i < nextWhitespace; i++) {
switch (line.charAt(i)) {
return nextWhitespace;
}
+ private boolean isPunctuation(char character) {
+ return character == '.';
+ }
+
private static class NextLink {
private final int position;
assertThat("Part Text", "Some text (and a link: [http://example.sone/abc_(def)|example.sone/abc_(def)|example.sone/abc_(def)]) – nice!", is(convertText(parts, PlainTextPart.class, LinkPart.class)));
}
+ @Test
+ public void punctuationIsIgnoredAtEndOfLinkBeforeWhitespace() {
+ SoneTextParser soneTextParser = new SoneTextParser(null, null);
+ Iterable<Part> parts = soneTextParser.parse("Some text and a link: http://example.sone/abc. Nice!", null);
+ assertThat("Parts", parts, notNullValue());
+ assertThat("Part Text", "Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]. Nice!", is(convertText(parts, PlainTextPart.class, LinkPart.class)));
+ }
+
+ @Test
+ public void multiplePunctuationCharactersAreIgnoredAtEndOfLinkBeforeWhitespace() {
+ SoneTextParser soneTextParser = new SoneTextParser(null, null);
+ Iterable<Part> parts = soneTextParser.parse("Some text and a link: http://example.sone/abc... Nice!", null);
+ assertThat("Parts", parts, notNullValue());
+ assertThat("Part Text", "Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]... Nice!", is(convertText(parts, PlainTextPart.class, LinkPart.class)));
+ }
+
/**
* Converts all given {@link Part}s into a string, validating that the
* part’s classes match only the expected classes.