From a6395bef99a8e917f67341ef1906917b87df24a4 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Mon, 13 Feb 2017 23:23:54 +0100 Subject: [PATCH] Partial HTML implementation, partial GUI support The HTML implementation is working, but subpar, and with lots of copy-pasted code The LocalReader is a work in progress --- Makefile.base | 19 +- configure.sh | 12 ++ ...es.jar => nikiroo-utils-0.9.6-sources.jar} | Bin 34033 -> 39430 bytes src/be/nikiroo/fanfix/Main.java | 1 + src/be/nikiroo/fanfix/bundles/Config.java | 5 + .../nikiroo/fanfix/bundles/config.properties | 6 + .../fanfix/bundles/resources.properties | 2 +- src/be/nikiroo/fanfix/output/BasicOutput.java | 6 +- src/be/nikiroo/fanfix/output/Html.java | 165 +++++++++++++++++- src/be/nikiroo/fanfix/reader/LocalReader.java | 92 ++++++++++ .../fanfix/reader/LocalReaderFrame.java | 55 ++++++ .../fanfix/supported/BasicSupport.java | 20 ++- 12 files changed, 369 insertions(+), 14 deletions(-) rename libs/{nikiroo-utils-0.9.5-sources.jar => nikiroo-utils-0.9.6-sources.jar} (66%) create mode 100644 src/be/nikiroo/fanfix/reader/LocalReader.java create mode 100644 src/be/nikiroo/fanfix/reader/LocalReaderFrame.java diff --git a/Makefile.base b/Makefile.base index 559b89d..9901644 100644 --- a/Makefile.base +++ b/Makefile.base @@ -7,6 +7,7 @@ #TEST = path to main test source to compile #JAR_FLAGS += a list of things to pack, each usually prefixed with "-C bin/" #SJAR_FLAGS += a list of things to pack, each usually prefixed with "-C src/", for *-sources.jar files +#TEST_PARAMS = any parameter to pass to the test runnable when "test-run" JAVAC = javac JAVAC_FLAGS += -encoding UTF-8 -d ./bin/ -cp ./src/ @@ -34,7 +35,7 @@ RJAR_FLAGS += -jar all: build jar -.PHONY: all clean mrproper mrpropre build run jrun jar resources install libs love +.PHONY: all clean mrproper mrpropre build run jrun jar resources test-resources install libs love bin: @mkdir -p bin @@ -50,7 +51,7 @@ build: resources $(JAVAC) $(JAVAC_FLAGS) "src/$$sup.java" ; \ done -test: +test: test-resources @[ -e bin/$(MAIN).class ] || echo You need to build the sources @[ -e bin/$(MAIN).class ] @echo Compiling test program... @@ -86,7 +87,17 @@ love: resources: libs @echo Copying resources into bin/... - @cd src && find . | grep -v '\.java$$' | while read -r ln; do \ + @cd src && find . | grep -v '\.java$$' | grep -v '/test/' | while read -r ln; do \ + if [ -f "$$ln" ]; then \ + dir="`dirname "$$ln"`"; \ + mkdir -p "../bin/$$dir" ; \ + cp "$$ln" "../bin/$$ln" ; \ + fi ; \ + done + +test-resources: resources + @echo Copying test resources into bin/... + @cd src && find . | grep -v '\.java$$' | grep '/test/' | while read -r ln; do \ if [ -f "$$ln" ]; then \ dir="`dirname "$$ln"`"; \ mkdir -p "../bin/$$dir" ; \ @@ -134,7 +145,7 @@ run-test: @[ "$(TEST)" = "" -o -e "bin/$(TEST).class" ] @echo Running tests for "$(NAME)"... @[ "$(TEST)" != "" ] || echo No test sources defined. - [ "$(TEST)" = "" ] || $(JAVA) $(JAVA_FLAGS) $(TEST) + [ "$(TEST)" = "" ] || ( clear ; $(JAVA) $(JAVA_FLAGS) $(TEST) $(TEST_PARAMS) ) install: @[ -e $(NAME).jar ] || echo You need to build the jar diff --git a/configure.sh b/configure.sh index 2954620..1da9835 100755 --- a/configure.sh +++ b/configure.sh @@ -33,7 +33,19 @@ done [ $valid = false ] && exit 2 +if [ "`whereis tput`" = "tput:" ]; then + ok='"[ ok ]"'; + ko='"[ !! ]"'; + cols=80; +else + ok='"`tput bold`[`tput setf 2` OK `tput init``tput bold`]`tput init`"'; + ko='"`tput bold`[`tput setf 4` !! `tput init``tput bold`]`tput init`"'; + cols='"`tput cols`"'; +fi; + echo "MAIN = be/nikiroo/fanfix/Main" > Makefile +echo "TEST = " >> Makefile +echo "TEST_PARAMS = $cols $ok $ko" >> Makefile echo "NAME = fanfix" >> Makefile echo "PREFIX = $PREFIX" >> Makefile echo "JAR_FLAGS += -C bin/ org -C bin/ be -C ./ VERSION" >> Makefile diff --git a/libs/nikiroo-utils-0.9.5-sources.jar b/libs/nikiroo-utils-0.9.6-sources.jar similarity index 66% rename from libs/nikiroo-utils-0.9.5-sources.jar rename to libs/nikiroo-utils-0.9.6-sources.jar index 7e424791ebb8637014546b728cc47b6f1b97eee7..42d2774f3505998f1b129f265c13509ee36188f7 100644 GIT binary patch delta 10803 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 delta 5633 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"); + writer.write("\n"); + writer.write("\n"); + writer.write("\n "); + writer.write("\n "); + writer.write("\n " + StringUtils.xmlEscape(title) + ""); + writer.write("\n"); + writer.write("\n\n"); + + writer.write("

" + StringUtils.xmlEscape(title) + "

\n\n"); + } + + @Override + protected void writeStoryFooter(Story story) throws IOException { + writer.write("\n"); + } + + @Override + protected void writeChapterHeader(Chapter chap) throws IOException { + String txt; + if (chap.getName() != null && !chap.getName().isEmpty()) { + txt = Instance.getTrans().getString(StringId.CHAPTER_NAMED, + chap.getNumber(), chap.getName()); + } else { + txt = Instance.getTrans().getString(StringId.CHAPTER_UNNAMED, + chap.getNumber()); + } + + writer.write("

" + StringUtils.xmlEscape(txt) + "

\n\n"); + + inDialogue = false; + inNormal = false; + } + + @Override + protected void writeParagraphHeader(Paragraph para) throws IOException { + if (para.getType() == ParagraphType.QUOTE && !inDialogue) { + writer.write("
\n"); + inDialogue = true; + } else if (para.getType() != ParagraphType.QUOTE && inDialogue) { + writer.write("
\n"); + inDialogue = false; + } + + if (para.getType() == ParagraphType.NORMAL && !inNormal) { + writer.write("
\n"); + inNormal = true; + } else if (para.getType() != ParagraphType.NORMAL && inNormal) { + writer.write("
\n"); + inNormal = false; + } + + switch (para.getType()) { + case BLANK: + writer.write("
"); + break; + case BREAK: + writer.write("
"); + break; + case NORMAL: + writer.write(" "); + break; + case QUOTE: + writer.write("
— "); + break; + case IMAGE: + // TODO + writer.write("" + + StringUtils.xmlEscape(para.getContent()) + ""); + break; + } + } + + @Override + protected void writeParagraphFooter(Paragraph para) throws IOException { + switch (para.getType()) { + case NORMAL: + writer.write("\n"); + break; + case QUOTE: + writer.write("
\n"); + break; + default: + writer.write("\n"); + break; + } + } + + @Override + protected void writeTextLine(ParagraphType type, String line) + throws IOException { + switch (type) { + case QUOTE: + case NORMAL: + writer.write(decorateText(StringUtils.xmlEscape(line))); + break; + default: + break; + } + } + + @Override + protected String enbold(String word) { + return "" + word + ""; + } + + @Override + protected String italize(String word) { + return "" + word + ""; + } } diff --git a/src/be/nikiroo/fanfix/reader/LocalReader.java b/src/be/nikiroo/fanfix/reader/LocalReader.java new file mode 100644 index 0000000..26f48f5 --- /dev/null +++ b/src/be/nikiroo/fanfix/reader/LocalReader.java @@ -0,0 +1,92 @@ +package be.nikiroo.fanfix.reader; + +import java.awt.EventQueue; +import java.io.File; +import java.io.IOException; + +import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.Library; +import be.nikiroo.fanfix.bundles.Config; +import be.nikiroo.fanfix.data.MetaData; +import be.nikiroo.fanfix.data.Story; +import be.nikiroo.fanfix.output.BasicOutput.OutputType; +import be.nikiroo.fanfix.supported.BasicSupport.SupportType; + +class LocalReader extends BasicReader { + private Library lib; + + public LocalReader() throws IOException { + File dir = Instance.getReaderDir(); + dir.mkdirs(); + if (!dir.exists()) { + throw new IOException( + "Cannote create cache directory for local reader: " + dir); + } + + // TODO: can throw an exception, manage that (convert to IOEx ?) + OutputType text = OutputType.valueOfNullOkUC(Instance.getConfig() + .getString(Config.LOCAL_READER_NON_IMAGES_DOCUMENT_TYPE)); + if (text == null) { + text = OutputType.HTML; + } + + OutputType images = OutputType.valueOfNullOkUC(Instance.getConfig() + .getString(Config.LOCAL_READER_IMAGES_DOCUMENT_TYPE)); + if (images == null) { + images = OutputType.CBZ; + } + // + + lib = new Library(dir, text, images); + } + + @Override + public void read() throws IOException { + } + + @Override + public void read(int chapter) { + } + + // return new luid + public String imprt(String luid) { + try { + Story story = Instance.getLibrary().getStory(luid); + story = lib.save(story); + return story.getMeta().getLuid(); + } catch (IOException e) { + Instance.syserr(new IOException( + "Cannot import story from library to LocalReader library: " + + luid, e)); + } + + return null; + } + + public File getTarget(String luid) { + MetaData meta = lib.getInfo(luid); + File file = lib.getFile(luid); + if (file == null) { + luid = imprt(luid); + file = lib.getFile(luid); + meta = lib.getInfo(luid); + } + + return file; + } + + @Override + public void start(SupportType type) { + final SupportType typeFinal = type; + EventQueue.invokeLater(new Runnable() { + public void run() { + new LocalReaderFrame(LocalReader.this, typeFinal) + .setVisible(true); + } + }); + } + + public static void main(String[] args) throws IOException { + new LocalReader().start(null); + } +} diff --git a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java new file mode 100644 index 0000000..f196f95 --- /dev/null +++ b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java @@ -0,0 +1,55 @@ +package be.nikiroo.fanfix.reader; + +import java.awt.Desktop; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JFrame; + +import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.data.MetaData; +import be.nikiroo.fanfix.supported.BasicSupport.SupportType; + +class LocalReaderFrame extends JFrame { + private static final long serialVersionUID = 1L; + private LocalReader reader; + + public LocalReaderFrame(LocalReader reader, SupportType type) { + super("HTML reader"); + + this.reader = reader; + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(800, 600); + setLayout(new FlowLayout()); + + // TODO: list all stories, list all TMP stories (and format?) + + List stories = Instance.getLibrary().getList(type); + for (MetaData story : stories) { + JButton button = new JButton(story.getTitle()); + final String luid = story.getLuid(); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + // TODO: config option (image, non image): TXT, + // custom-HTML, CBZ, EPUB + Desktop.getDesktop().browse( + LocalReaderFrame.this.reader.getTarget(luid) + .toURI()); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + }); + + add(button); + } + + setVisible(true); + } +} diff --git a/src/be/nikiroo/fanfix/supported/BasicSupport.java b/src/be/nikiroo/fanfix/supported/BasicSupport.java index 6d44c04..ed7c4db 100644 --- a/src/be/nikiroo/fanfix/supported/BasicSupport.java +++ b/src/be/nikiroo/fanfix/supported/BasicSupport.java @@ -360,6 +360,7 @@ public abstract class BasicSupport { } finally { chapIn.close(); } + i++; } } @@ -767,11 +768,22 @@ public abstract class BasicSupport { line = openDoubleQuote + line + closeDoubleQuote; newParas.add(new Paragraph(ParagraphType.QUOTE, line)); } else { + char open = singleQ ? openQuote : openDoubleQuote; char close = singleQ ? closeQuote : closeDoubleQuote; - int posClose = line.indexOf(close, 1); - int posDot = line.indexOf("."); - while (posDot >= 0 && posDot < posClose) { - posDot = line.indexOf(".", posDot + 1); + + int posDot = -1; + boolean inQuote = false; + int i = 0; + for (char car : line.toCharArray()) { + if (car == open) { + inQuote = true; + } else if (car == close) { + inQuote = false; + } else if (car == '.' && !inQuote) { + posDot = i; + break; + } + i++; } if (posDot >= 0) { -- 2.27.0