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