From: Niki Roo Date: Mon, 13 Feb 2017 22:23:54 +0000 (+0100) Subject: Partial HTML implementation, partial GUI support X-Git-Tag: fanfix-0.9.3~1 X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=commitdiff_plain;h=a6395bef99a8e917f67341ef1906917b87df24a4 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 --- 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 7e42479..42d2774 100644 Binary files a/libs/nikiroo-utils-0.9.5-sources.jar and b/libs/nikiroo-utils-0.9.6-sources.jar differ diff --git a/src/be/nikiroo/fanfix/Main.java b/src/be/nikiroo/fanfix/Main.java index d5669d5..46eb0b5 100644 --- a/src/be/nikiroo/fanfix/Main.java +++ b/src/be/nikiroo/fanfix/Main.java @@ -379,6 +379,7 @@ public class Main { } else { try { BasicSupport support = BasicSupport.getSupport(source); + if (support != null) { Story story = support.process(source); diff --git a/src/be/nikiroo/fanfix/bundles/Config.java b/src/be/nikiroo/fanfix/bundles/Config.java index 060bc81..86f480d 100644 --- a/src/be/nikiroo/fanfix/bundles/Config.java +++ b/src/be/nikiroo/fanfix/bundles/Config.java @@ -46,4 +46,9 @@ public enum Config { CHAPTER_EN, // @Meta(what = "Chapter identification string", where = "", format = "", info = "used to identify a starting chapter in text mode") CHAPTER_FR, // + @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, // + @Meta(what = "Output type", where = "Local Reader", format = "One of the known output type", info = "The type of output for the Local Reader for images documents") + LOCAL_READER_IMAGES_DOCUMENT_TYPE, // + } diff --git a/src/be/nikiroo/fanfix/bundles/config.properties b/src/be/nikiroo/fanfix/bundles/config.properties index 67b5e7f..535fb32 100644 --- a/src/be/nikiroo/fanfix/bundles/config.properties +++ b/src/be/nikiroo/fanfix/bundles/config.properties @@ -59,3 +59,9 @@ CHAPTER_EN = Chapter # (WHAT: Chapter identification string) # used to identify a starting chapter in text mode CHAPTER_FR = Chapitre +# (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 +LOCAL_READER_NON_IMAGES_DOCUMENT_TYPE = HTML +# (WHAT: Output type, WHERE: Local Reader, FORMAT: One of the known output type) +# The type of output for the Local Reader for images documents +LOCAL_READER_IMAGES_DOCUMENT_TYPE = CBZ diff --git a/src/be/nikiroo/fanfix/bundles/resources.properties b/src/be/nikiroo/fanfix/bundles/resources.properties index 035594f..37ecd55 100644 --- a/src/be/nikiroo/fanfix/bundles/resources.properties +++ b/src/be/nikiroo/fanfix/bundles/resources.properties @@ -133,4 +133,4 @@ OUTPUT_DESC_SYSOUT = A simple DEBUG console output LATEX_LANG_UNKNOWN = Unknown language: %s # (WHAT: 'by' prefix before author name) # used to output the author, make sure it is covered by Config.BYS for input detection -BY = By +BY = by diff --git a/src/be/nikiroo/fanfix/output/BasicOutput.java b/src/be/nikiroo/fanfix/output/BasicOutput.java index 9b53859..33a42c5 100644 --- a/src/be/nikiroo/fanfix/output/BasicOutput.java +++ b/src/be/nikiroo/fanfix/output/BasicOutput.java @@ -92,7 +92,7 @@ public abstract class BasicOutput { /** * Call {@link OutputType#valueOf(String.toUpperCase())} but return NULL - * for NULL instead of raising exception. + * for NULL and empty instead of raising an exception. * * @param typeName * the possible type name @@ -100,7 +100,7 @@ public abstract class BasicOutput { * @return NULL or the type */ public static OutputType valueOfNullOkUC(String typeName) { - if (typeName == null) { + if (typeName == null || typeName.isEmpty()) { return null; } @@ -441,7 +441,7 @@ public abstract class BasicOutput { case LATEX: return new LaTeX().setType(type, infoCover, infoCover); case HTML: - return new Html().setType(type, false, false); + return new Html().setType(type, infoCover, infoCover); } } diff --git a/src/be/nikiroo/fanfix/output/Html.java b/src/be/nikiroo/fanfix/output/Html.java index 4226bf8..29a0f32 100644 --- a/src/be/nikiroo/fanfix/output/Html.java +++ b/src/be/nikiroo/fanfix/output/Html.java @@ -1,6 +1,167 @@ package be.nikiroo.fanfix.output; -//TODO: implement it for LocalReader -class Html extends Text { +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.bundles.StringId; +import be.nikiroo.fanfix.data.Chapter; +import be.nikiroo.fanfix.data.Paragraph; +import be.nikiroo.fanfix.data.Paragraph.ParagraphType; +import be.nikiroo.fanfix.data.Story; +import be.nikiroo.utils.StringUtils; + +class Html extends BasicOutput { + protected FileWriter writer; + private boolean inDialogue = false; + private boolean inNormal = false; + + @Override + public File process(Story story, File targetDir, String targetName) + throws IOException { + File target = new File(targetDir, targetName); + target.mkdir(); + + targetName = new File(targetName, "index").getPath(); + + String targetNameOrig = targetName; + targetName += getDefaultExtension(); + + target = new File(targetDir, targetName); + + writer = new FileWriter(target); + try { + super.process(story, targetDir, targetNameOrig); + } finally { + writer.close(); + writer = null; + } + + return target; + } + + @Override + public String getDefaultExtension() { + return ".html"; + } + + @Override + protected void writeStoryHeader(Story story) throws IOException { + String title = ""; + if (story.getMeta() != null) { + title = story.getMeta().getTitle(); + } + + writer.write(""); + 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) {