/[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 109 - (show annotations)
Fri Feb 16 18:49:14 2001 UTC (23 years, 1 month ago) by frodo
File MIME type: text/plain
File size: 11445 byte(s)
(Frodo) Jim Ottaway's gen_latex module, and two example files

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 /* This is incomplete at the moment.
53
54 Most of the translation/faking of chars is borrowed from the
55 HTML::Latex.pm perl module. */
56 static const char *char_table[0x100] =
57 {
58 /* 0x00 */ "" ,"" ,"" ,"" ,"" ,"" ,"\n\n","\\\\"
59 ,
60 /* 0x08 */ "\n\n" ," " ,"" ,"" ,"" ,"" ,"" ,""
61 ,
62 /* 0x10 */ " " ,"" ,"" ,"" ,"" ,"" ,"" ,""
63 ,
64 /* 0x18 */ "" ,"" ,"" ,"" ,"" ,"" ,"" ,""
65 ,
66 /* 0x20 */ " " ,"!" ,"\"" ,"\\#" ,"\\$" ,"\\%" ,"\\&","'"
67 ,
68 /* 0x28 */ "(" ,")" ,"*" ,"+" ,"," ,"-" ,"." ,"/"
69 ,
70 /* 0x30 */ "0" ,"1" ,"2" ,"3" ,"4" ,"5" ,"6" ,"7"
71 ,
72 /* 0x38 */ "8" ,"9" ,":" ,";" ,"$<$" ,"=" ,"$>$" ,"?" ,
73 /* 0x40 */ "@" ,"A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G"
74 ,
75 /* 0x48 */ "H" ,"I" ,"J" ,"K" ,"L" ,"M" ,"N" ,"O"
76 ,
77 /* 0x50 */ "P" ,"Q" ,"R" ,"S" ,"T" ,"U" ,"V" ,"W"
78 ,
79 /* 0x58 */ "X" ,"Y" ,"Z" ,"[" ,"$\\backslash$" ,"]" ,"\\^{}"
80 ,"\\_" ,
81 /* 0x60 */ "`" ,"a" ,"b" ,"c" ,"d" ,"e" ,"f" ,"g"
82 ,
83 /* 0x68 */ "h" ,"i" ,"j" ,"k" ,"l" ,"m" ,"n" ,"o"
84 ,
85 /* 0x70 */ "p" ,"q" ,"r" ,"s" ,"t" ,"u" ,"v" ,"w"
86 ,
87 /* 0x78 */ "x" ,"y" ,"z" ,"\\{" ,"$|$" ,"\\}" ,"~"
88 ,"" ,
89 /* 0x80 */ "" ,"","","$f$","","{\\ldots}", "$\\dagger$","$\\ddagger$",
90 /* 0x88 */ "\\^{}","","","","\\OE","" ,"" ,"" ,
91 /* 0x90 */ "","`","'","``","''", "$\\bullet$","--","---",
92 /* 0x98 */ "~","{\\textsc{tm}}","","","\\oe","","","\\\"Y",
93 /* 0xa0 */ "","!`","c","{\\pounds}",
94 "","{Y\\hspace*{-1.4ex}--}","$|$","{\\S}",
95 /* 0xa8 */
96 "\"","{\\copyright}","$^{\\underline{a}}$","","$\\neg$","$-$","","$^-$",
97 /* 0xb0 */ "$^{\\circ}$","$\\pm$","$^2$","$^3$",
98 "$^\\prime$","$\\mu$","{\\P}","$\\cdot$",
99 /* 0xb8 */ ",","$^1$","$^{\\underline{\\circ}}$","",
100 "$\\frac{1}{4}$","$\\frac{1}{2}$","$\\frac{3}{4}$","?`",
101 /* 0xc0 */ "\\`A","\\'A","\\^A","\\~A", "\\\"A","\\AA","\\AE","\\c{C}",
102 /* 0xc8 */ "\\`E","\\'E","\\^E","\\\"E", "\\`I","\\'I","\\^I","\\\"I",
103 /* 0xd0 */ "{D\\hspace*{-1.7ex}-\\hspace{.9ex}}","\\~N","\\`O","\\'O",
104 "\\^O","\\~O","\\\"O","$\\times$",
105 /* 0xd8 */ "{\\O}","\\`U","\\'U","\\^U", "\\\"U","\\'Y","","",
106 /* 0xe0 */ "\\`a","\\'a","\\^a","\\~a",
107 "\\\"a","\\r{a}","{\\ae}","\\c{c}",
108 /* 0xe8 */ "\\`e","\\'e","\\^e","\\\"e",
109 "\\`{\\i}","\\'{\\i}","\\^{\\i}","\\\"{\\i}",
110 /* 0xf0 */ "\\v{o}","\\~n","\\`o","\\'o", "\\^o","\\~o","\\\"o","$\\div$",
111 /* 0xf8 */ "{\\o}","\\`u","\\'u","\\^u", "\\\"u","\\'y","","\\\"y"
112 };
113
114 static psiconv_character_layout gen_base_char(const psiconv_font font,
115 const psiconv_color color,
116 const psiconv_color
117 back_color);
118 static void diff_char(FILE *of, const psiconv_character_layout old,
119 const psiconv_character_layout new, int *flags);
120 static void gen_para(FILE *of, const psiconv_paragraph para,
121 const psiconv_character_layout base_char,
122 psiconv_word_f wf);
123
124 static void psiconv_gen_latex_word(FILE *of,psiconv_word_f wf);
125 static void psiconv_gen_latex_texted(FILE *of,psiconv_texted_f tf);
126
127 psiconv_character_layout gen_base_char(const psiconv_font font,
128 const psiconv_color color,
129 const psiconv_color back_color)
130 {
131 struct psiconv_character_layout_s base_char_struct =
132 {
133 NULL, /* color */
134 NULL, /* back_color */
135 13.0, /* font_size */
136 psiconv_bool_false, /* italic */
137 psiconv_bool_false, /* bold */
138 psiconv_normalscript, /* super_sub */
139 psiconv_bool_false, /* underline */
140 psiconv_bool_false, /* strikethrough */
141 NULL, /* font */
142 };
143 base_char_struct.color = color;
144 base_char_struct.back_color = back_color;
145 base_char_struct.font = font;
146 return psiconv_clone_character_layout(&base_char_struct);
147 }
148
149 /* flags & 1: 1 if in a section
150 flags & 2: 1 if at end-of-paragraph
151 */
152 void diff_char(FILE *of, const psiconv_character_layout old,
153 const psiconv_character_layout new,
154 int *flags)
155 {
156 if ((*flags & 3) == 3) { /* end of section command argument */
157 putc('}',of);
158 return;
159 }
160 if (old->italic != new->italic) {
161 if (old->italic)
162 putc('}',of);
163 else
164 fputs("\\emph{",of);
165 }
166 if (old->bold != new->bold) {
167 if (old->bold)
168 putc('}',of);
169 else
170 fputs("\\textbf{",of);
171 }
172 if (old->underline != new->underline) {
173 if (old->underline)
174 putc('}',of);
175 else
176 fputs("\\underline{",of);
177 }
178 }
179
180
181 const static char *sections[] = {
182 "section",
183 "subsection",
184 "subsubsection",
185 "paragraph",
186 "subparagraph"
187 };
188
189 struct environment {
190 char *style_name;
191 char *environment_name;
192 };
193
194 const static struct environment environments[] = {
195 {"quotation", "quotation"},
196 {"", NULL}
197 };
198
199 char *find_env(char *style) {
200 int n = 0;
201 while (environments[n].environment_name != NULL) {
202 if (strcmp(style, environments[n].style_name) == 0) {
203 return environments[n].environment_name;
204 }
205 n++;
206 }
207 return NULL;
208 }
209
210 psiconv_bool_t bullet_switch_on = psiconv_bool_false;
211
212 void gen_para(FILE *of, const psiconv_paragraph para,
213 const psiconv_character_layout base_char,
214 psiconv_word_f wf)
215 {
216 int i,j,loc;
217 psiconv_character_layout cur_char;
218 psiconv_in_line_layout inl;
219 int flags = 0;
220 psiconv_word_style sty;
221 char *env = NULL;
222
223 if (para->base_paragraph->bullet->on) {
224 if (! bullet_switch_on) {
225 fputs("\\begin{itemize}\n\n", of);
226 bullet_switch_on = psiconv_bool_true;
227 }
228 fputs("\\item ",of);
229 } else {
230 if (bullet_switch_on) {
231 fputs("\\end{itemize}\n\n", of);
232 bullet_switch_on = psiconv_bool_false;
233 }
234 }
235
236 cur_char = base_char;
237
238 if (wf) {
239 sty = psiconv_get_style(wf->styles_sec, para->base_style);
240 if (sty->name && (env = find_env(sty->name))) {
241 fputs("\\begin{",of);
242 fputs(env,of);
243 fputs("}\n",of);
244 } else {
245 if (sty->outline_level &&
246 (sty->outline_level > 0) && (sty->outline_level < 6)) {
247 putc('\\', of);
248 fputs(sections[(sty->outline_level - 1)], of);
249 putc('{', of);
250 cur_char = para->base_character; /* ignore initial formatting */
251 flags |= 1;
252 }
253 }
254 }
255
256 if (psiconv_list_length(para->in_lines) == 0) {
257 diff_char(of,cur_char,para->base_character,&flags);
258 cur_char = para->base_character;
259 }
260 loc = 0;
261
262 for (i = 0; i < psiconv_list_length(para->in_lines); i++) {
263 inl = psiconv_list_get(para->in_lines,i);
264 diff_char(of,cur_char,inl->layout,&flags);
265 cur_char = inl->layout;
266 for (j = loc; j < inl->length + loc; j ++) {
267 fputs(char_table[(unsigned char) (para->text[j])],of);
268 }
269 loc = j;
270 }
271
272 if (loc < strlen(para->text)) {
273 diff_char(of,cur_char,para->base_character,&flags);
274 cur_char = para->base_character;
275 for (j = loc; j < strlen(para->text); j ++) {
276 fputs(char_table[(unsigned char) (para->text[j])],of);
277 }
278 }
279
280 flags |= 2;
281 diff_char(of,cur_char,base_char,&flags);
282
283 if (env) {
284 fputs("\n\\end{",of);
285 fputs(env,of);
286 putc('}',of);
287 }
288
289 fputs("\n\n", of);
290 }
291
292 int psiconv_gen_latex(const char * filename,const psiconv_file file,
293 const char *dest)
294 {
295 FILE *of = fopen(filename,"w");
296 if (! of)
297 return -1;
298
299 if (file->type == psiconv_word_file) {
300 psiconv_gen_latex_word(of,(psiconv_word_f) file->file);
301 } else if (file->type == psiconv_texted_file) {
302 psiconv_gen_latex_texted(of,(psiconv_texted_f) file->file);
303 } else {
304 fclose(of);
305 return -1;
306 }
307 return fclose(of);
308 }
309
310 /* This isn't tested !!! */
311 void psiconv_gen_latex_texted(FILE *of,psiconv_texted_f tf)
312 {
313 psiconv_character_layout base_char;
314 psiconv_paragraph para;
315 int i;
316
317 /* We have nothing better */
318 base_char = psiconv_basic_character_layout();
319
320 fputs("\\documentclass{article}\n\n\\begin{document}\n\n", of);
321 for (i = 0; i < psiconv_list_length(tf->texted_sec->paragraphs); i++) {
322 para = psiconv_list_get(tf->texted_sec->paragraphs,i);
323 gen_para(of,para,base_char, NULL);
324 }
325 fputs("\\end{document}",of);
326 psiconv_free_character_layout(base_char);
327 }
328
329 void psiconv_gen_latex_word(FILE *of,psiconv_word_f wf)
330 {
331 int i;
332 psiconv_paragraph para;
333 psiconv_color white,black;
334 psiconv_character_layout base_char;
335
336 white = malloc(sizeof(*white));
337 black = malloc(sizeof(*black));
338 white->red = 0x00;
339 white->green = 0x00;
340 white->blue = 0x00;
341 black->red = 0xff;
342 black->green = 0xff;
343 black->blue = 0xff;
344
345 /* To keep from generating a font desc for each line */
346 base_char = gen_base_char(wf->styles_sec->normal->character->font,
347 black,white);
348
349 psiconv_free_color(black);
350 psiconv_free_color(white);
351
352 fputs("\\documentclass{article}\n\n\\begin{document}\n\n", of);
353
354 for (i = 0; i < psiconv_list_length(wf->paragraphs); i++) {
355 para = psiconv_list_get(wf->paragraphs,i);
356 gen_para(of,para,base_char,wf);
357 }
358 fputs("\\end{document}\n",of);
359 for (i = 0; i <
360 psiconv_list_length(wf->page_sec->header->text->paragraphs); i++) {
361 para = psiconv_list_get(wf->page_sec->header->text->paragraphs,i);
362 gen_para(of,para,base_char,wf);
363 }
364
365 psiconv_free_character_layout(base_char);
366 }
367
368 static struct psiconv_fileformat_s ff =
369 {
370 "LaTeX",
371 "LaTeX conversion to article class",
372 &psiconv_gen_latex
373 };
374
375 void init_latex(void)
376 {
377 psiconv_list_add(fileformat_list,&ff);
378 }
379

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