Ignore commas at the end of links, too
[Sone.git] / src / main / java / net / pterodactylus / sone / text / SoneTextParser.java
index ae299e1..dbfa0f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneTextParser.java - Copyright © 2010–2015 David Roden
+ * Sone - SoneTextParser.java - Copyright © 2010–2016 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@ public class SoneTextParser implements Parser<SoneTextParserContext> {
         */
        @Nonnull
        @Override
-       public Iterable<Part> parse(@Nullable SoneTextParserContext context, @Nonnull String source) {
+       public Iterable<Part> parse(@Nonnull String source, @Nullable SoneTextParserContext context) {
                PartContainer parts = new PartContainer();
                BufferedReader bufferedReader = new BufferedReader(new StringReader(source));
                try {
@@ -175,9 +175,8 @@ public class SoneTextParser implements Parser<SoneTextParserContext> {
                                        }
                                        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<SoneTextParserContext> {
                                                }
                                                parts.add(new LinkPart(link, name));
                                        }
-                                       line = line.substring(nextSpace);
+                                       line = line.substring(endOfLink);
                                }
                                lastLineEmpty = false;
                        }
@@ -291,6 +290,40 @@ public class SoneTextParser implements Parser<SoneTextParserContext> {
                return parts;
        }
 
+       private int findEndOfLink(String line) {
+               Matcher matcher = whitespacePattern.matcher(line);
+               if (!matcher.find(0)) {
+                       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)) {
+                               case '(':
+                                       openParens++;
+                                       break;
+                               case ')':
+                                       openParens--;
+                                       if (openParens < 0) {
+                                               return i;
+                                       }
+                               default:
+                       }
+               }
+               return nextWhitespace;
+       }
+
+       private boolean isPunctuation(char character) {
+               return (character == '.') || (character == ',');
+       }
+
        private static class NextLink {
 
                private final int position;