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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 frodo 109 /*
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 frodo 142 #ifdef DMALLOC
53     #include "dmalloc.h"
54     #endif
55    
56 frodo 109 /* 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