From 505c771415cd5c6f71c24e6c2b837d6e2f0c3a78 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Mon, 15 Aug 2016 20:41:39 +0200 Subject: [PATCH] Change parser to better recognize the end of links --- .../pterodactylus/sone/text/SoneTextParser.java | 30 +++++++++++++++++++--- .../sone/text/SoneTextParserTest.java | 15 +++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java b/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java index fb4e7cd..b675c12 100644 --- a/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java +++ b/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java @@ -175,9 +175,8 @@ public class SoneTextParser implements Parser { } lineComplete = false; - Matcher matcher = whitespacePattern.matcher(line); - int nextSpace = matcher.find(0) ? matcher.start() : line.length(); - String link = line.substring(0, nextSpace); + int endOfLink = findEndOfLink(line); + String link = line.substring(0, endOfLink); String name = link; logger.log(Level.FINER, String.format("Found link: %s", link)); @@ -271,7 +270,7 @@ public class SoneTextParser implements Parser { } parts.add(new LinkPart(link, name)); } - line = line.substring(nextSpace); + line = line.substring(endOfLink); } lastLineEmpty = false; } @@ -291,6 +290,29 @@ public class SoneTextParser implements Parser { return parts; } + private int findEndOfLink(String line) { + Matcher matcher = whitespacePattern.matcher(line); + if (!matcher.find(0)) { + return line.length(); + } + int nextWhitespace = matcher.start(); + int openParens = 0; + for (int i = 0; i < nextWhitespace; i++) { + switch (line.charAt(i)) { + case '(': + openParens++; + break; + case ')': + openParens--; + if (openParens < 0) { + return i; + } + default: + } + } + return nextWhitespace; + } + private static class NextLink { private final int position; diff --git a/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java b/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java index 200a773..8d83c95 100644 --- a/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java +++ b/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java @@ -108,6 +108,21 @@ public class SoneTextParserTest { assertThat("Part Text", "Some text. Empty link: http:// – nice!", is(convertText(parts, PlainTextPart.class))); } + @Test + public void httpLinkWithoutParensEndsAtNextClosingParen() { + SoneTextParser soneTextParser = new SoneTextParser(null, null); + Iterable 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 httpLinkWithOpenedAndClosedParensEndsAtNextClosingParen() { + SoneTextParser soneTextParser = new SoneTextParser(null, null); + Iterable parts = soneTextParser.parse("Some text (and a link: http://example.sone/abc_(def)) – nice!", null); + assertThat("Parts", parts, notNullValue()); + 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))); + } /** * Converts all given {@link Part}s into a string, validating that the -- 2.7.4