Commit | Line | Data |
---|---|---|
08fe2e33 NR |
1 | package be.nikiroo.fanfix.output; |
2 | ||
3d247bc3 | 3 | import java.io.BufferedWriter; |
08fe2e33 | 4 | import java.io.File; |
3d247bc3 | 5 | import java.io.FileOutputStream; |
08fe2e33 | 6 | import java.io.IOException; |
3d247bc3 | 7 | import java.io.OutputStreamWriter; |
08fe2e33 NR |
8 | |
9 | import be.nikiroo.fanfix.Instance; | |
10 | import be.nikiroo.fanfix.bundles.Config; | |
11 | import be.nikiroo.fanfix.bundles.StringId; | |
12 | import be.nikiroo.fanfix.data.Chapter; | |
13 | import be.nikiroo.fanfix.data.MetaData; | |
08fe2e33 | 14 | import be.nikiroo.fanfix.data.Paragraph.ParagraphType; |
3d247bc3 | 15 | import be.nikiroo.fanfix.data.Story; |
08fe2e33 NR |
16 | |
17 | class LaTeX extends BasicOutput { | |
3d247bc3 | 18 | protected BufferedWriter writer; |
08fe2e33 NR |
19 | private boolean lastWasQuote = false; |
20 | ||
21 | // quote chars | |
22 | private char openQuote = Instance.getTrans().getChar( | |
23 | StringId.OPEN_SINGLE_QUOTE); | |
24 | private char closeQuote = Instance.getTrans().getChar( | |
25 | StringId.CLOSE_SINGLE_QUOTE); | |
26 | private char openDoubleQuote = Instance.getTrans().getChar( | |
27 | StringId.OPEN_DOUBLE_QUOTE); | |
28 | private char closeDoubleQuote = Instance.getTrans().getChar( | |
29 | StringId.CLOSE_DOUBLE_QUOTE); | |
30 | ||
31 | @Override | |
32 | public File process(Story story, File targetDir, String targetName) | |
33 | throws IOException { | |
34 | String targetNameOrig = targetName; | |
10d558d2 | 35 | targetName += getDefaultExtension(false); |
08fe2e33 NR |
36 | |
37 | File target = new File(targetDir, targetName); | |
38 | ||
3d247bc3 NR |
39 | writer = new BufferedWriter(new OutputStreamWriter( |
40 | new FileOutputStream(target), "UTF-8")); | |
08fe2e33 NR |
41 | try { |
42 | super.process(story, targetDir, targetNameOrig); | |
43 | } finally { | |
44 | writer.close(); | |
45 | writer = null; | |
46 | } | |
47 | ||
48 | return target; | |
49 | } | |
50 | ||
51 | @Override | |
10d558d2 | 52 | public String getDefaultExtension(boolean readerTarget) { |
08fe2e33 NR |
53 | return ".tex"; |
54 | } | |
55 | ||
56 | @Override | |
57 | protected void writeStoryHeader(Story story) throws IOException { | |
58 | String date = ""; | |
59 | String author = ""; | |
60 | String title = "\\title{}"; | |
61 | String lang = ""; | |
62 | if (story.getMeta() != null) { | |
63 | MetaData meta = story.getMeta(); | |
64 | title = "\\title{" + latexEncode(meta.getTitle()) + "}"; | |
65 | date = "\\date{" + latexEncode(meta.getDate()) + "}"; | |
66 | author = "\\author{" + latexEncode(meta.getAuthor()) + "}"; | |
67 | lang = meta.getLang().toLowerCase(); | |
68 | if (lang != null && !lang.isEmpty()) { | |
69 | lang = Instance.getConfig().getStringX(Config.LATEX_LANG, lang); | |
70 | if (lang == null) { | |
71 | System.err.println(Instance.getTrans().getString( | |
72 | StringId.LATEX_LANG_UNKNOWN, lang)); | |
73 | } | |
74 | } | |
75 | } | |
76 | ||
77 | writer.append("%\n"); | |
78 | writer.append("% This LaTeX document was auto-generated by Fanfic Reader, created by Niki.\n"); | |
79 | writer.append("%\n\n"); | |
80 | writer.append("\\documentclass[a4paper]{book}\n"); | |
81 | if (lang != null && !lang.isEmpty()) { | |
82 | writer.append("\\usepackage[" + lang + "]{babel}\n"); | |
83 | } | |
84 | writer.append("\\usepackage[utf8]{inputenc}\n"); | |
85 | writer.append("\\usepackage[T1]{fontenc}\n"); | |
86 | writer.append("\\usepackage{lmodern}\n"); | |
87 | writer.append("\\newcommand{\\br}{\\vspace{10 mm}}\n"); | |
88 | writer.append("\\newcommand{\\say}{--- \\noindent\\emph}\n"); | |
89 | writer.append("\\hyphenpenalty=1000\n"); | |
90 | writer.append("\\tolerance=5000\n"); | |
91 | writer.append("\\begin{document}\n"); | |
92 | if (story.getMeta() != null && story.getMeta().getDate() != null) | |
93 | writer.append(date + "\n"); | |
94 | writer.append(title + "\n"); | |
95 | writer.append(author + "\n"); | |
96 | writer.append("\\maketitle\n"); | |
97 | writer.append("\n"); | |
98 | ||
99 | // TODO: cover | |
100 | } | |
101 | ||
102 | @Override | |
103 | protected void writeStoryFooter(Story story) throws IOException { | |
104 | writer.append("\\end{document}\n"); | |
105 | } | |
106 | ||
107 | @Override | |
108 | protected void writeChapterHeader(Chapter chap) throws IOException { | |
109 | writer.append("\n\n\\chapter{" + latexEncode(chap.getName()) + "}" | |
110 | + "\n"); | |
111 | } | |
112 | ||
113 | @Override | |
114 | protected void writeChapterFooter(Chapter chap) throws IOException { | |
115 | writer.write("\n"); | |
116 | } | |
117 | ||
118 | @Override | |
119 | protected String enbold(String word) { | |
120 | return "\\textsc{" + word + "}"; | |
121 | } | |
122 | ||
123 | @Override | |
124 | protected String italize(String word) { | |
125 | return "\\emph{" + word + "}"; | |
126 | } | |
127 | ||
128 | @Override | |
129 | protected void writeTextLine(ParagraphType type, String line) | |
130 | throws IOException { | |
131 | ||
132 | line = decorateText(latexEncode(line)); | |
133 | ||
134 | switch (type) { | |
135 | case BLANK: | |
136 | writer.write("\n"); | |
137 | lastWasQuote = false; | |
138 | break; | |
139 | case BREAK: | |
140 | writer.write("\n\\br"); | |
141 | writer.write("\n"); | |
142 | lastWasQuote = false; | |
143 | break; | |
144 | case NORMAL: | |
145 | writer.write(line); | |
146 | writer.write("\n"); | |
147 | lastWasQuote = false; | |
148 | break; | |
149 | case QUOTE: | |
150 | writer.write("\n\\say{" + line + "}\n"); | |
151 | if (lastWasQuote) { | |
152 | writer.write("\n\\noindent{}"); | |
153 | } | |
154 | lastWasQuote = true; | |
155 | break; | |
156 | case IMAGE: | |
157 | // TODO | |
158 | break; | |
159 | } | |
160 | } | |
161 | ||
162 | private String latexEncode(String input) { | |
163 | StringBuilder builder = new StringBuilder(); | |
164 | for (char car : input.toCharArray()) { | |
165 | // TODO: check restricted chars? | |
166 | if (car == '^' || car == '$' || car == '\\' || car == '#' | |
167 | || car == '%') { | |
168 | builder.append('\\'); | |
169 | builder.append(car); | |
170 | } else if (car == openQuote) { | |
171 | builder.append('`'); | |
172 | } else if (car == closeQuote) { | |
173 | builder.append('\''); | |
174 | } else if (car == openDoubleQuote) { | |
175 | builder.append("``"); | |
176 | } else if (car == closeDoubleQuote) { | |
177 | builder.append("''"); | |
178 | } else { | |
179 | builder.append(car); | |
180 | } | |
181 | } | |
182 | ||
183 | return builder.toString(); | |
184 | } | |
185 | } |