/*
- * 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
import java.io.BufferedReader;
import java.io.IOException;
-import java.io.Reader;
+import java.io.StringReader;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import net.pterodactylus.sone.data.Post;
import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.sone.data.impl.IdOnlySone;
/**
* {@inheritDoc}
*/
+ @Nonnull
@Override
- public Iterable<Part> parse(SoneTextParserContext context, Reader source) throws IOException {
+ public Iterable<Part> parse(@Nonnull String source, @Nullable SoneTextParserContext context) {
PartContainer parts = new PartContainer();
- BufferedReader bufferedReader = (source instanceof BufferedReader) ? (BufferedReader) source : new BufferedReader(source);
+ BufferedReader bufferedReader = new BufferedReader(new StringReader(source));
try {
String line;
boolean lastLineEmpty = true;
}
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));
}
parts.add(new LinkPart(link, name));
}
- line = line.substring(nextSpace);
+ line = line.substring(endOfLink);
}
lastLineEmpty = false;
}
+ } catch (IOException ioe1) {
+ // a buffered reader around a string reader should never throw.
+ throw new RuntimeException(ioe1);
} finally {
- if (bufferedReader != source) {
- Closer.close(bufferedReader);
- }
+ Closer.close(bufferedReader);
}
for (int partIndex = parts.size() - 1; partIndex >= 0; --partIndex) {
Part part = parts.getPart(partIndex);
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;