/[public]/psiconv/trunk/program/psiconv/gen_latex.c
ViewVC logotype

Contents of /psiconv/trunk/program/psiconv/gen_latex.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 142 - (show annotations)
Tue Jan 29 18:38:38 2002 UTC (17 years, 11 months ago) by frodo
File MIME type: text/plain
File size: 11489 byte(s)
(Frodo) DMALLOC support

1 /*
2 gen_latex.h - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 2001 Jim Ottaway <j.ottaway@lse.ac.uk>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /* gen_latex.c
21
22 Sun Feb 11 12:16:29 2001
23
24 Jim Ottaway <j.ottaway@lse.ac.uk>
25
26 Conversion to LaTeX:
27
28 * Converts to the article class
29
30 * If the file is a Word file and has outline levels (i.e. is not a
31 Psion 5 file), outline levels 1 to 5 are converted to sectioning
32 commands, otherwise headings are just formatted
33
34 * If there is a style with the name 'quotation', the paragraph is
35 converted to a quotation environment (other styles/environments
36 could be added)
37
38 * Also does formatting commands (italics -> \emph, bold -> \textbf,
39 underline -> \underline), and character translation
40
41 */
42
43 #include "config.h"
44 #include <stdio.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include "psiconv/data.h"
48 #include "psiconv/list.h"
49 #include "gen.h"
50 #include "psiconv.h"
51
52 #ifdef DMALLOC
53 #include "dmalloc.h"
54 #endif
55
56 /* This is incomplete at the moment.
57
58 Most of the translation/faking of chars is borrowed from the
59 HTML::Latex.pm perl module. */
60 static const char *char_table[0x100] =
61 {
62 /* 0x00 */ "" ,"" ,"" ,"" ,"" ,"" ,"\n\n","\\\\"
63 ,
64 /* 0x08 */ "\n\n" ," " ,"" ,"" ,"" ,"" ,"" ,""
65 ,
66 /* 0x10 */ " " ,"" ,"" ,"" ,"" ,"" ,"" ,""
67 ,
68 /* 0x18 */ "" ,"" ,"" ,"" ,"" ,"" ,"" ,""
69 ,
70 /* 0x20 */ " " ,"!" ,"\"" ,"\\#" ,"\\$" ,"\\%" ,"\\&","'"
71 ,
72 /* 0x28 */ "(" ,")" ,"*" ,"+" ,"," ,"-" ,"." ,"/"
73 ,
74 /* 0x30 */ "0" ,"1" ,"2" ,"3" ,"4" ,"5" ,"6" ,"7"
75 ,
76 /* 0x38 */ "8" ,"9" ,":" ,";" ,"$<$" ,"=" ,"$>$" ,"?" ,
77 /* 0x40 */ "@" ,"A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G"
78 ,
79 /* 0x48 */ "H" ,"I" ,"J" ,"K" ,"L" ,"M" ,"N" ,"O"
80 ,
81 /* 0x50 */ "P" ,"Q" ,"R" ,"S" ,"T" ,"U" ,"V" ,"W"
82 ,
83 /* 0x58 */ "X" ,"Y" ,"Z" ,"[" ,"$\\backslash$" ,"]" ,"\\^{}"
84 ,"\\_" ,
85 /* 0x60 */ "`" ,"a" ,"b" ,"c" ,"d" ,"e" ,"f" ,"g"
86 ,
87 /* 0x68 */ "h" ,"i" ,"j" ,"k" ,"l" ,"m" ,"n" ,"o"
88 ,
89 /* 0x70 */ "p" ,"q" ,"r" ,"s" ,"t" ,"u" ,"v" ,"w"
90 ,
91 /* 0x78 */ "x" ,"y" ,"z" ,"\\{" ,"$|$" ,"\\}" ,"~"
92 ,"" ,
93 /* 0x80 */ "" ,"","","$f$","","{\\ldots}", "$\\dagger$","$\\ddagger$",
94 /* 0x88 */ "\\^{}","","","","\\OE","" ,"" ,"" ,
95 /* 0x90 */ "","`","'","``","''", "$\\bullet$","--","---",
96 /* 0x98 */ "~","{\\textsc{tm}}","","","\\oe","","","\\\"Y",
97 /* 0xa0 */ "","!`","c","{\\pounds}",
98 "","{Y\\hspace*{-1.4ex}--}","$|$","{\\S}",
99 /* 0xa8 */
100 "\"","{\\copyright}","$^{\\underline{a}}$","","$\\neg$","$-$","","$^-$",
101 /* 0xb0 */ "$^{\\circ}$","$\\pm$","$^2$","$^3$",
102 "$^\\prime$","$\\mu$","{\\P}","$\\cdot$",
103 /* 0xb8 */ ",","$^1$","$^{\\underline{\\circ}}$","",
104 "$\\frac{1}{4}$","$\\frac{1}{2}$","$\\frac{3}{4}$","?`",
105 /* 0xc0 */ "\\`A","\\'A","\\^A","\\~A", "\\\"A","\\AA","\\AE","\\c{C}",
106 /* 0xc8 */ "\\`E","\\'E","\\^E","\\\"E", "\\`I","\\'I","\\^I","\\\"I",
107 /* 0xd0 */ "{D\\hspace*{-1.7ex}-\\hspace{.9ex}}","\\~N","\\`O","\\'O",
108 "\\^O","\\~O","\\\"O","$\\times$",
109 /* 0xd8 */ "{\\O}","\\`U","\\'U","\\^U", "\\\"U","\\'Y","","",
110 /* 0xe0 */ "\\`a","\\'a","\\^a","\\~a",
111 "\\\"a","\\r{a}","{\\ae}","\\c{c}",
112 /* 0xe8 */ "\\`e","\\'e","\\^e","\\\"e",
113 "\\`{\\i}","\\'{\\i}","\\^{\\i}","\\\"{\\i}",
114 /* 0xf0 */ "\\v{o}","\\~n","\\`o","\\'o", "\\^o","\\~o","\\\"o","$\\div$",
115 /* 0xf8 */ "{\\o}","\\`u","\\'u","\\^u", "\\\"u","\\'y","","\\\"y"
116 };
117
118 static psiconv_character_layout gen_base_char(const psiconv_font font,
119 const psiconv_color color,
120 const psiconv_color
121 back_color);
122 static void diff_char(FILE *of, const psiconv_character_layout old,
123 const psiconv_character_layout new, int *flags);
124 static void gen_para(FILE *of, const psiconv_paragraph para,
125 const psiconv_character_layout base_char,
126 psiconv_word_f wf);
127
128 static void psiconv_gen_latex_word(FILE *of,psiconv_word_f wf);
129 static void psiconv_gen_latex_texted(FILE *of,psiconv_texted_f tf);
130
131 psiconv_character_layout gen_base_char(const psiconv_font font,
132 const psiconv_color color,
133 const psiconv_color back_color)
134 {
135 struct psiconv_character_layout_s base_char_struct =
136 {
137 NULL, /* color */
138 NULL, /* back_color */
139 13.0, /* font_size */
140 psiconv_bool_false, /* italic */
141 psiconv_bool_false, /* bold */
142 psiconv_normalscript, /* super_sub */
143 psiconv_bool_false, /* underline */
144 psiconv_bool_false, /* strikethrough */
145 NULL, /* font */
146 };
147 base_char_struct.color = color;
148 base_char_struct.back_color = back_color;
149 base_char_struct.font = font;
150 return psiconv_clone_character_layout(&base_char_struct);
151 }
152
153 /* flags & 1: 1 if in a section
154 flags & 2: 1 if at end-of-paragraph
155 */
156 void diff_char(FILE *of, const psiconv_character_layout old,
157 const psiconv_character_layout new,
158 int *flags)
159 {
160 if ((*flags & 3) == 3) { /* end of section command argument */
161 putc('}',of);
162 return;
163 }
164 if (old->italic != new->italic) {
165 if (old->italic)
166 putc('}',of);
167 else
168 fputs("\\emph{",of);
169 }
170 if (old->bold != new->bold) {
171 if (old->bold)
172 putc('}',of);
173 else
174 fputs("\\textbf{",of);
175 }
176 if (old->underline != new->underline) {
177 if (old->underline)
178 putc('}',of);
179 else
180 fputs("\\underline{",of);
181 }
182 }
183
184
185 const static char *sections[] = {
186 "section",
187 "subsection",
188 "subsubsection",
189 "paragraph",
190 "subparagraph"
191 };
192
193 struct environment {
194 char *style_name;
195 char *environment_name;
196 };
197
198 const static struct environment environments[] = {
199 {"quotation", "quotation"},
200 {"", NULL}
201 };
202
203 char *find_env(char *style) {
204 int n = 0;
205 while (environments[n].environment_name != NULL) {
206 if (strcmp(style, environments[n].style_name) == 0) {
207 return environments[n].environment_name;
208 }
209 n++;
210 }
211 return NULL;
212 }
213
214 psiconv_bool_t bullet_switch_on = psiconv_bool_false;
215
216 void gen_para(FILE *of, const psiconv_paragraph para,
217 const psiconv_character_layout base_char,
218 psiconv_word_f wf)
219 {
220 int i,j,loc;
221 psiconv_character_layout cur_char;
222 psiconv_in_line_layout inl;
223 int flags = 0;
224 psiconv_word_style sty;
225 char *env = NULL;
226
227 if (para->base_paragraph->bullet->on) {
228 if (! bullet_switch_on) {
229 fputs("\\begin{itemize}\n\n", of);
230 bullet_switch_on = psiconv_bool_true;
231 }
232 fputs("\\item ",of);
233 } else {
234 if (bullet_switch_on) {
235 fputs("\\end{itemize}\n\n", of);
236 bullet_switch_on = psiconv_bool_false;
237 }
238 }
239
240 cur_char = base_char;
241
242 if (wf) {
243 sty = psiconv_get_style(wf->styles_sec, para->base_style);
244 if (sty->name && (env = find_env(sty->name))) {
245 fputs("\\begin{",of);
246 fputs(env,of);
247 fputs("}\n",of);
248 } else {
249 if (sty->outline_level &&
250 (sty->outline_level > 0) && (sty->outline_level < 6)) {
251 putc('\\', of);
252 fputs(sections[(sty->outline_level - 1)], of);
253 putc('{', of);
254 cur_char = para->base_character; /* ignore initial formatting */
255 flags |= 1;
256 }
257 }
258 }
259
260 if (psiconv_list_length(para->in_lines) == 0) {
261 diff_char(of,cur_char,para->base_character,&flags);
262 cur_char = para->base_character;
263 }
264 loc = 0;
265
266 for (i = 0; i < psiconv_list_length(para->in_lines); i++) {
267 inl = psiconv_list_get(para->in_lines,i);
268 diff_char(of,cur_char,inl->layout,&flags);
269 cur_char = inl->layout;
270 for (j = loc; j < inl->length + loc; j ++) {
271 fputs(char_table[(unsigned char) (para->text[j])],of);
272 }
273 loc = j;
274 }
275
276 if (loc < strlen(para->text)) {
277 diff_char(of,cur_char,para->base_character,&flags);
278 cur_char = para->base_character;
279 for (j = loc; j < strlen(para->text); j ++) {
280 fputs(char_table[(unsigned char) (para->text[j])],of);
281 }
282 }
283
284 flags |= 2;
285 diff_char(of,cur_char,base_char,&flags);
286
287 if (env) {
288 fputs("\n\\end{",of);
289 fputs(env,of);
290 putc('}',of);
291 }
292
293 fputs("\n\n", of);
294 }
295
296 int psiconv_gen_latex(const char * filename,const psiconv_file file,
297 const char *dest)
298 {
299 FILE *of = fopen(filename,"w");
300 if (! of)
301 return -1;
302
303 if (file->type == psiconv_word_file) {
304 psiconv_gen_latex_word(of,(psiconv_word_f) file->file);
305 } else if (file->type == psiconv_texted_file) {
306 psiconv_gen_latex_texted(of,(psiconv_texted_f) file->file);
307 } else {
308 fclose(of);
309 return -1;
310 }
311 return fclose(of);
312 }
313
314 /* This isn't tested !!! */
315 void psiconv_gen_latex_texted(FILE *of,psiconv_texted_f tf)
316 {
317 psiconv_character_layout base_char;
318 psiconv_paragraph para;
319 int i;
320
321 /* We have nothing better */
322 base_char = psiconv_basic_character_layout();
323
324 fputs("\\documentclass{article}\n\n\\begin{document}\n\n", of);
325 for (i = 0; i < psiconv_list_length(tf->texted_sec->paragraphs); i++) {
326 para = psiconv_list_get(tf->texted_sec->paragraphs,i);
327 gen_para(of,para,base_char, NULL);
328 }
329 fputs("\\end{document}",of);
330 psiconv_free_character_layout(base_char);
331 }
332
333 void psiconv_gen_latex_word(FILE *of,psiconv_word_f wf)
334 {
335 int i;
336 psiconv_paragraph para;
337 psiconv_color white,black;
338 psiconv_character_layout base_char;
339
340 white = malloc(sizeof(*white));
341 black = malloc(sizeof(*black));
342 white->red = 0x00;
343 white->green = 0x00;
344 white->blue = 0x00;
345 black->red = 0xff;
346 black->green = 0xff;
347 black->blue = 0xff;
348
349 /* To keep from generating a font desc for each line */
350 base_char = gen_base_char(wf->styles_sec->normal->character->font,
351 black,white);
352
353 psiconv_free_color(black);
354 psiconv_free_color(white);
355
356 fputs("\\documentclass{article}\n\n\\begin{document}\n\n", of);
357
358 for (i = 0; i < psiconv_list_length(wf->paragraphs); i++) {
359 para = psiconv_list_get(wf->paragraphs,i);
360 gen_para(of,para,base_char,wf);
361 }
362 fputs("\\end{document}\n",of);
363 for (i = 0; i <
364 psiconv_list_length(wf->page_sec->header->text->paragraphs); i++) {
365 para = psiconv_list_get(wf->page_sec->header->text->paragraphs,i);
366 gen_para(of,para,base_char,wf);
367 }
368
369 psiconv_free_character_layout(base_char);
370 }
371
372 static struct psiconv_fileformat_s ff =
373 {
374 "LaTeX",
375 "LaTeX conversion to article class",
376 &psiconv_gen_latex
377 };
378
379 void init_latex(void)
380 {
381 psiconv_list_add(fileformat_list,&ff);
382 }
383

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26