Fix UTF-8 and "/" -> "\" issues for Win32
[fanfix.git] / src / be / nikiroo / fanfix / output / LaTeX.java
1 package be.nikiroo.fanfix.output;
2
3 import java.io.BufferedWriter;
4 import java.io.File;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.OutputStreamWriter;
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;
14 import be.nikiroo.fanfix.data.Paragraph.ParagraphType;
15 import be.nikiroo.fanfix.data.Story;
16
17 class LaTeX extends BasicOutput {
18 protected BufferedWriter writer;
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;
35 targetName += getDefaultExtension();
36
37 File target = new File(targetDir, targetName);
38
39 writer = new BufferedWriter(new OutputStreamWriter(
40 new FileOutputStream(target), "UTF-8"));
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
52 public String getDefaultExtension() {
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 }