Remove or move java.awt dependencies
[nikiroo-utils.git] / src / be / nikiroo / fanfix / output / Html.java
CommitLineData
2206ef66
NR
1package be.nikiroo.fanfix.output;
2
3d247bc3 3import java.io.BufferedWriter;
a6395bef 4import java.io.File;
3d247bc3 5import java.io.FileOutputStream;
a6395bef 6import java.io.IOException;
333f0e7b 7import java.io.InputStream;
3d247bc3 8import java.io.OutputStreamWriter;
333f0e7b 9
a6395bef 10import be.nikiroo.fanfix.Instance;
333f0e7b 11import be.nikiroo.fanfix.bundles.Config;
a6395bef 12import be.nikiroo.fanfix.data.Chapter;
333f0e7b 13import be.nikiroo.fanfix.data.MetaData;
a6395bef
NR
14import be.nikiroo.fanfix.data.Paragraph;
15import be.nikiroo.fanfix.data.Paragraph.ParagraphType;
16import be.nikiroo.fanfix.data.Story;
333f0e7b 17import be.nikiroo.utils.IOUtils;
a6395bef
NR
18import be.nikiroo.utils.StringUtils;
19
20class Html extends BasicOutput {
333f0e7b 21 private File dir;
3d247bc3 22 protected BufferedWriter writer;
a6395bef
NR
23 private boolean inDialogue = false;
24 private boolean inNormal = false;
25
26 @Override
27 public File process(Story story, File targetDir, String targetName)
28 throws IOException {
333f0e7b
NR
29 String targetNameOrig = targetName;
30
a6395bef
NR
31 File target = new File(targetDir, targetName);
32 target.mkdir();
333f0e7b 33 dir = target;
a6395bef 34
373da363
NR
35 // write a copy of the originals inside
36 InfoCover.writeInfo(dir, targetName, story.getMeta());
37 InfoCover.writeCover(dir, targetName, story.getMeta());
925298fd
NR
38 BasicOutput.getOutput(OutputType.TEXT, isWriteInfo(), isWriteCover())
39 .process(story, dir, targetNameOrig);
373da363 40
10d558d2 41 target = new File(targetDir, targetName + getDefaultExtension(true));
373da363 42
3d247bc3
NR
43 writer = new BufferedWriter(new OutputStreamWriter(
44 new FileOutputStream(target), "UTF-8"));
a6395bef
NR
45 try {
46 super.process(story, targetDir, targetNameOrig);
47 } finally {
48 writer.close();
49 writer = null;
50 }
51
333f0e7b 52 if (story.getMeta().getCover() != null) {
16a81ef7
NR
53 Instance.getCache().saveAsImage(story.getMeta().getCover(),
54 new File(dir, "cover"), true);
333f0e7b
NR
55 }
56
a6395bef
NR
57 return target;
58 }
59
60 @Override
10d558d2
NR
61 public String getDefaultExtension(boolean readerTarget) {
62 if (readerTarget) {
63 return File.separator + "index.html";
10d558d2 64 }
211f7ddb
NR
65
66 return "";
a6395bef
NR
67 }
68
69 @Override
70 protected void writeStoryHeader(Story story) throws IOException {
71 String title = "";
333f0e7b
NR
72 String tags = "";
73 String author = "";
74 Chapter resume = null;
a6395bef 75 if (story.getMeta() != null) {
333f0e7b
NR
76 MetaData meta = story.getMeta();
77 title = meta.getTitle();
78 resume = meta.getResume();
79 if (meta.getTags() != null) {
80 for (String tag : meta.getTags()) {
81 if (!tags.isEmpty()) {
82 tags += ", ";
83 }
84 tags += tag;
85 }
86
87 if (!tags.isEmpty()) {
88 tags = "(" + tags + ")";
89 }
90 }
91 author = meta.getAuthor();
92 }
93
94 String format = Instance.getConfig()
95 .getString(Config.IMAGE_FORMAT_COVER).toLowerCase();
96
97 InputStream inStyle = getClass().getResourceAsStream("html.style.css");
98 if (inStyle == null) {
99 throw new IOException("Cannot find style.css resource");
100 }
101 try {
102 IOUtils.write(inStyle, new File(dir, "style.css"));
103 } finally {
104 inStyle.close();
a6395bef
NR
105 }
106
107 writer.write("<!DOCTYPE html>");
108 writer.write("\n<html>");
109 writer.write("\n<head>");
110 writer.write("\n <meta http-equiv='content-type' content='text/html; charset=utf-8'>");
111 writer.write("\n <meta name='viewport' content='width=device-width, initial-scale=1.0'>");
333f0e7b 112 writer.write("\n <link rel='stylesheet' type='text/css' href='style.css'>");
a6395bef
NR
113 writer.write("\n <title>" + StringUtils.xmlEscape(title) + "</title>");
114 writer.write("\n</head>");
115 writer.write("\n<body>\n");
116
333f0e7b
NR
117 writer.write("\n <div class=\"titlepage\">");
118 writer.write("\n <h1>" + StringUtils.xmlEscape(title) + "</h1>");
119 writer.write("\n <div class=\"type\">" + StringUtils.xmlEscape(tags)
120 + "</div>");
121 writer.write("\n <div class=\"cover\">");
122 writer.write("\n <img src=\"cover." + format + "\"></img>");
123 writer.write("\n </div>");
124 writer.write("\n <div class=\"author\">"
125 + StringUtils.xmlEscape(author) + "</div>");
126 writer.write("\n </div>");
127
128 writer.write("\n <hr/><br/>");
129
130 if (resume != null) {
131 for (Paragraph para : resume) {
132 writeParagraph(para);
133 }
134 if (inDialogue) {
135 writer.write(" </div>\n");
136 inDialogue = false;
137 }
138 if (inNormal) {
139 writer.write(" </div>\n");
140 inNormal = false;
141 }
142 }
143
144 writer.write("\n <br/>");
a6395bef
NR
145 }
146
147 @Override
148 protected void writeStoryFooter(Story story) throws IOException {
149 writer.write("</body>\n");
150 }
151
152 @Override
153 protected void writeChapterHeader(Chapter chap) throws IOException {
333f0e7b 154 String nameOrNumber;
a6395bef 155 if (chap.getName() != null && !chap.getName().isEmpty()) {
333f0e7b 156 nameOrNumber = chap.getName();
a6395bef 157 } else {
333f0e7b 158 nameOrNumber = Integer.toString(chap.getNumber());
a6395bef
NR
159 }
160
333f0e7b
NR
161 writer.write("\n <h2>");
162 writer.write("\n <span class='chap'>Chapter <span class='chapnumber'>"
163 + chap.getNumber() + "</span>:</span> ");
164 writer.write("\n <span class='chaptitle'>"
165 + StringUtils.xmlEscape(nameOrNumber) + "</span>");
166 writer.write("\n </h2>");
167 writer.write("\n ");
168 writer.write("\n <div class='chapter_content'>\n");
a6395bef
NR
169
170 inDialogue = false;
171 inNormal = false;
172 }
173
333f0e7b
NR
174 @Override
175 protected void writeChapterFooter(Chapter chap) throws IOException {
176 if (inDialogue) {
177 writer.write(" </div>\n");
178 inDialogue = false;
179 }
180 if (inNormal) {
181 writer.write(" </div>\n");
182 inNormal = false;
183 }
184
185 writer.write("\n </div>");
186 }
187
a6395bef
NR
188 @Override
189 protected void writeParagraphHeader(Paragraph para) throws IOException {
190 if (para.getType() == ParagraphType.QUOTE && !inDialogue) {
191 writer.write(" <div class='dialogues'>\n");
192 inDialogue = true;
193 } else if (para.getType() != ParagraphType.QUOTE && inDialogue) {
194 writer.write(" </div>\n");
195 inDialogue = false;
196 }
197
198 if (para.getType() == ParagraphType.NORMAL && !inNormal) {
199 writer.write(" <div class='normals'>\n");
200 inNormal = true;
201 } else if (para.getType() != ParagraphType.NORMAL && inNormal) {
202 writer.write(" </div>\n");
203 inNormal = false;
204 }
205
206 switch (para.getType()) {
207 case BLANK:
208 writer.write(" <div class='blank'></div>");
209 break;
210 case BREAK:
f977d05b 211 writer.write(" <hr class='break'/>");
a6395bef
NR
212 break;
213 case NORMAL:
214 writer.write(" <span class='normal'>");
215 break;
216 case QUOTE:
217 writer.write(" <div class='dialogue'>&mdash; ");
218 break;
219 case IMAGE:
220 // TODO
221 writer.write("<a href='"
222 + StringUtils.xmlEscapeQuote(para.getContent()) + "'>"
223 + StringUtils.xmlEscape(para.getContent()) + "</a>");
224 break;
225 }
226 }
227
228 @Override
229 protected void writeParagraphFooter(Paragraph para) throws IOException {
230 switch (para.getType()) {
231 case NORMAL:
232 writer.write("</span>\n");
233 break;
234 case QUOTE:
235 writer.write("</div>\n");
236 break;
237 default:
238 writer.write("\n");
239 break;
240 }
241 }
242
243 @Override
244 protected void writeTextLine(ParagraphType type, String line)
245 throws IOException {
246 switch (type) {
247 case QUOTE:
248 case NORMAL:
249 writer.write(decorateText(StringUtils.xmlEscape(line)));
250 break;
251 default:
252 break;
253 }
254 }
255
256 @Override
257 protected String enbold(String word) {
258 return "<strong>" + word + "</strong>";
259 }
260
261 @Override
262 protected String italize(String word) {
263 return "<emph>" + word + "</emph>";
264 }
2206ef66 265}