debug = true;
}
- if (tmp == null || readerTmp == null) {
- String tmpDir = System.getProperty("java.io.tmpdir");
- if (tmpDir != null) {
- if (tmp == null) {
- tmp = new File(tmpDir, "fanfic-tmp");
- }
- if (readerTmp == null) {
- readerTmp = new File(tmpDir, "fanfic-reader");
- }
- } else {
- syserr(new IOException(
- "The system does not have a default temporary directory"));
- }
+ // Could have used: System.getProperty("java.io.tmpdir")
+ if (tmp == null) {
+ tmp = new File(configDir, "tmp");
+ }
+ if (readerTmp == null) {
+ readerTmp = new File(configDir, "tmp-reader");
}
+ //
if (coverDir != null && !coverDir.exists()) {
syserr(new IOException(
LANG, //
@Meta(what = "reader type", where = "", format = "CLI or LOCAL", info = "Select the reader to use to read stories (CLI = simple output to console, LOCAL = use local system file handler)")
READER_TYPE, //
- @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to a directory 'fanfic-tmp' in the system default temporary directory")
+ @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to directory 'tmp' in the conig directory (usually $HOME/.fanfix)")
CACHE_DIR, //
@Meta(what = "delay in hours", where = "", format = "integer | 0: no cache | -1: infinite time cache which is default", info = "The delay after which a cached resource that is thought to change ~often is considered too old and triggers a refresh")
CACHE_MAX_TIME_CHANGING, //
* @author niki
*/
public enum UiConfig {
- @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to a directory 'fanfic-reader' in the system default temporary directory")
+ @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to directory 'tmp.reader' in the conig directory (usually $HOME/.fanfix)")
CACHE_DIR_LOCAL_READER, //
@Meta(what = "Output type", where = "Local Reader", format = "One of the known output type", info = "The type of output for the Local Reader for non-images documents")
LOCAL_READER_NON_IMAGES_DOCUMENT_TYPE, //
# Select the reader to use to read stories (CLI = simple output to console, LOCAL = use local system file handler)
READER_TYPE =
# (WHAT: directory, FORMAT: absolute path, $HOME variable supported, / is always accepted as dir separator)
-# The directory where to store temporary files, defaults to a directory 'fanfic-tmp' in the system default temporary directory
+# The directory where to store temporary files, defaults to directory 'tmp' in the conig directory (usually $HOME/.fanfix)
CACHE_DIR =
# (WHAT: delay in hours, FORMAT: integer | 0: no cache | -1: infinite time cache which is default)
# The delay after which a cached resource that is thought to change ~often is considered too old and triggers a refresh
# (WHAT: directory, FORMAT: absolute path, $HOME variable supported, / is always accepted as dir separator)
-# The directory where to store temporary files, defaults to a directory 'fanfic-reader' in the system default temporary directory
+# The directory where to store temporary files, defaults to directory 'tmp.reader' in the conig directory (usually $HOME/.fanfix)
CACHE_DIR_LOCAL_READER =
# (WHAT: Output type, WHERE: Local Reader, FORMAT: One of the known output type)
# The type of output for the Local Reader for non-images documents
package be.nikiroo.fanfix.supported;
import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
Chapter chap = new Chapter(number, chapterName);
- if (content == null) {
- return chap;
+ if (content != null) {
+ chap.setParagraphs(makeParagraphs(source, content));
}
+ return chap;
+
+ }
+
+ /**
+ * Convert the given content into {@link Paragraph}s.
+ *
+ * @param source
+ * the source URL of the story
+ * @param content
+ * the textual content
+ *
+ * @return the {@link Paragraph}s
+ *
+ * @throws IOException
+ * in case of I/O error
+ */
+ protected List<Paragraph> makeParagraphs(URL source, String content)
+ throws IOException {
if (isHtml()) {
// Special <HR> processing:
content = content.replaceAll("(<hr [^>]*>)|(<hr/>)|(<hr>)",
"\n* * *\n");
}
+ List<Paragraph> paras = new ArrayList<Paragraph>();
InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8"));
try {
- @SuppressWarnings("resource")
- Scanner scan = new Scanner(in, "UTF-8");
- scan.useDelimiter("(\\n|</p>)"); // \n for test, </p> for html
-
- List<Paragraph> paras = new ArrayList<Paragraph>();
- while (scan.hasNext()) {
- String line = scan.next().trim();
- boolean image = false;
- if (line.startsWith("[") && line.endsWith("]")) {
- URL url = getImageUrl(this, source,
- line.substring(1, line.length() - 1).trim());
- if (url != null) {
- paras.add(new Paragraph(url));
- image = true;
- }
+ BufferedReader buff = new BufferedReader(new InputStreamReader(in,
+ "UTF-8"));
+
+ for (String encodedLine = buff.readLine(); encodedLine != null; encodedLine = buff
+ .readLine()) {
+ String lines[];
+ if (isHtml()) {
+ lines = encodedLine.split("(<p>|</p>|<br>|<br/>|\\n)");
+ } else {
+ lines = new String[] { encodedLine };
}
- if (!image) {
- paras.add(processPara(line));
+ for (String aline : lines) {
+ String line = aline.trim();
+
+ URL image = null;
+ if (line.startsWith("[") && line.endsWith("]")) {
+ image = getImageUrl(this, source,
+ line.substring(1, line.length() - 1).trim());
+ }
+
+ if (image != null) {
+ paras.add(new Paragraph(image));
+ } else {
+ paras.add(processPara(line));
+ }
}
}
+ } finally {
+ in.close();
+ }
- // Check quotes for "bad" format
- List<Paragraph> newParas = new ArrayList<Paragraph>();
- for (Paragraph para : paras) {
- newParas.addAll(requotify(para));
- }
- paras = newParas;
-
- // Remove double blanks/brks
- boolean space = false;
- boolean brk = true;
- for (int i = 0; i < paras.size(); i++) {
- Paragraph para = paras.get(i);
- boolean thisSpace = para.getType() == ParagraphType.BLANK;
- boolean thisBrk = para.getType() == ParagraphType.BREAK;
-
- if (space && thisBrk) {
- paras.remove(i - 1);
- i--;
- } else if ((space || brk) && (thisSpace || thisBrk)) {
- paras.remove(i);
- i--;
- }
+ // Check quotes for "bad" format
+ List<Paragraph> newParas = new ArrayList<Paragraph>();
+ for (Paragraph para : paras) {
+ newParas.addAll(requotify(para));
+ }
+ paras = newParas;
- space = thisSpace;
- brk = thisBrk;
- }
+ // Remove double blanks/brks
+ fixBlanksBreaks(paras);
- // Remove blank/brk at start
- if (paras.size() > 0
- && (paras.get(0).getType() == ParagraphType.BLANK || paras
- .get(0).getType() == ParagraphType.BREAK)) {
- paras.remove(0);
- }
+ return paras;
+ }
- // Remove blank/brk at end
- int last = paras.size() - 1;
- if (paras.size() > 0
- && (paras.get(last).getType() == ParagraphType.BLANK || paras
- .get(last).getType() == ParagraphType.BREAK)) {
- paras.remove(last);
+ /**
+ * Fix the {@link ParagraphType#BLANK}s and {@link ParagraphType#BREAK}s of
+ * those {@link Paragraph}s.
+ * <p>
+ * The resulting list will not contain a starting or trailing blank/break
+ * nor 2 blanks or breaks following each other.
+ *
+ * @param paras
+ * the list of {@link Paragraph}s to fix
+ */
+ protected void fixBlanksBreaks(List<Paragraph> paras) {
+ boolean space = false;
+ boolean brk = true;
+ for (int i = 0; i < paras.size(); i++) {
+ Paragraph para = paras.get(i);
+ boolean thisSpace = para.getType() == ParagraphType.BLANK;
+ boolean thisBrk = para.getType() == ParagraphType.BREAK;
+
+ if (i > 0 && space && thisBrk) {
+ paras.remove(i - 1);
+ i--;
+ } else if ((space || brk) && (thisSpace || thisBrk)) {
+ paras.remove(i);
+ i--;
}
- chap.setParagraphs(paras);
+ space = thisSpace;
+ brk = thisBrk;
+ }
- return chap;
- } finally {
- in.close();
+ // Remove blank/brk at start
+ if (paras.size() > 0
+ && (paras.get(0).getType() == ParagraphType.BLANK || paras.get(
+ 0).getType() == ParagraphType.BREAK)) {
+ paras.remove(0);
+ }
+
+ // Remove blank/brk at end
+ int last = paras.size() - 1;
+ if (paras.size() > 0
+ && (paras.get(last).getType() == ParagraphType.BLANK || paras
+ .get(last).getType() == ParagraphType.BREAK)) {
+ paras.remove(last);
}
}
+ /**
+ * Get the default cover related to this subject (see <tt>.info</tt> files).
+ *
+ * @param subject
+ * the subject
+ *
+ * @return the cover if any, or NULL
+ */
static BufferedImage getDefaultCover(String subject) {
if (subject != null && !subject.isEmpty()
&& Instance.getCoverDir() != null) {
*
* @return the correctly (or so we hope) quotified paragraphs
*/
- private List<Paragraph> requotify(Paragraph para) {
+ protected List<Paragraph> requotify(Paragraph para) {
List<Paragraph> newParas = new ArrayList<Paragraph>();
if (para.getType() == ParagraphType.QUOTE
--- /dev/null
+package be.nikiroo.fanfix.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import be.nikiroo.fanfix.data.MetaData;
+import be.nikiroo.fanfix.data.Paragraph;
+import be.nikiroo.fanfix.data.Paragraph.ParagraphType;
+import be.nikiroo.fanfix.supported.BasicSupport;
+import be.nikiroo.utils.test.TestCase;
+import be.nikiroo.utils.test.TestLauncher;
+
+public class BasicSupportTest extends TestLauncher {
+
+ public BasicSupportTest(String[] args) {
+ super("BasicSupport", args);
+
+ addSeries(new TestLauncher("General", args) {
+ {
+ addTest(new TestCase("BasicSupport.makeParagraphs()") {
+ @Override
+ public void test() throws Exception {
+ BasicSupportEmpty support = new BasicSupportEmpty() {
+ @Override
+ protected boolean isHtml() {
+ return true;
+ }
+
+ @Override
+ public void fixBlanksBreaks(List<Paragraph> paras) {
+ }
+
+ @Override
+ protected List<Paragraph> requotify(Paragraph para) {
+ List<Paragraph> paras = new ArrayList<Paragraph>(
+ 1);
+ paras.add(para);
+ return paras;
+ }
+ };
+
+ List<Paragraph> paras = null;
+
+ paras = support.makeParagraphs(null, "");
+ assertEquals(
+ "An empty content should not generate paragraphs",
+ 0, paras.size());
+
+ paras = support.makeParagraphs(null,
+ "Line 1</p><p>Line 2</p><p>Line 3</p>");
+ assertEquals(5, paras.size());
+ assertEquals("Line 1", paras.get(0).getContent());
+ assertEquals(ParagraphType.BLANK, paras.get(1)
+ .getType());
+ assertEquals("Line 2", paras.get(2).getContent());
+ assertEquals(ParagraphType.BLANK, paras.get(3)
+ .getType());
+ assertEquals("Line 3", paras.get(4).getContent());
+
+ paras = support.makeParagraphs(null,
+ "<p>Line1</p><p>Line2</p><p>Line3</p>");
+ assertEquals(6, paras.size());
+ }
+ });
+
+ addTest(new TestCase("BasicSupport.removeDoubleBlanks()") {
+ @Override
+ public void test() throws Exception {
+ BasicSupportEmpty support = new BasicSupportEmpty() {
+ @Override
+ protected boolean isHtml() {
+ return true;
+ }
+ };
+
+ List<Paragraph> paras = null;
+
+ paras = support
+ .makeParagraphs(null,
+ "<p>Line1</p><p>Line2</p><p>Line3<br/><br><p></p>");
+ assertEquals(5, paras.size());
+
+ paras = support
+ .makeParagraphs(null,
+ "<p>Line1</p><p>Line2</p><p>Line3<br/><br><p></p>* * *");
+ assertEquals(5, paras.size());
+
+ paras = support.makeParagraphs(null, "1<p>* * *<p>2");
+ assertEquals(3, paras.size());
+ assertEquals(ParagraphType.BREAK, paras.get(1)
+ .getType());
+
+ paras = support.makeParagraphs(null,
+ "1<p><br/><p>* * *<p>2");
+ assertEquals(3, paras.size());
+ assertEquals(ParagraphType.BREAK, paras.get(1)
+ .getType());
+
+ paras = support.makeParagraphs(null,
+ "1<p>* * *<br/><p><br><p>2");
+ assertEquals(3, paras.size());
+ assertEquals(ParagraphType.BREAK, paras.get(1)
+ .getType());
+
+ paras = support.makeParagraphs(null,
+ "1<p><br/><br>* * *<br/><p><br><p>2");
+ assertEquals(3, paras.size());
+ assertEquals(ParagraphType.BREAK, paras.get(1)
+ .getType());
+ }
+ });
+ }
+ });
+ }
+
+ private class BasicSupportEmpty extends BasicSupport {
+ @Override
+ protected String getSourceName() {
+ return null;
+ }
+
+ @Override
+ protected boolean supports(URL url) {
+ return false;
+ }
+
+ @Override
+ protected boolean isHtml() {
+ return false;
+ }
+
+ @Override
+ protected MetaData getMeta(URL source, InputStream in)
+ throws IOException {
+ return null;
+ }
+
+ @Override
+ protected String getDesc(URL source, InputStream in) throws IOException {
+ return null;
+ }
+
+ @Override
+ protected List<Entry<String, URL>> getChapters(URL source,
+ InputStream in) throws IOException {
+ return null;
+ }
+
+ @Override
+ protected String getChapterContent(URL source, InputStream in,
+ int number) throws IOException {
+ return null;
+ }
+
+ @Override
+ // and make it public!
+ public List<Paragraph> makeParagraphs(URL source, String content)
+ throws IOException {
+ return super.makeParagraphs(source, content);
+ }
+
+ @Override
+ // and make it public!
+ public void fixBlanksBreaks(List<Paragraph> paras) {
+ super.fixBlanksBreaks(paras);
+ }
+ }
+}
*/
public class Test extends TestLauncher {
public Test(String[] args) {
- super("Fanfix (empty: all tests were moved to nikiroo-utils...)", args);
+ super("Fanfix", args);
+ addSeries(new BasicSupportTest(args));
}
/**