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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 190 - (hide annotations)
Mon Jan 26 21:56:49 2004 UTC (20 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 16864 byte(s)
(Frodo) XHTML work

1 frodo 190 /* gen_html.c - Part of psiconv, a PSION 5 file formats converter
2     Copyright (c) 1999-2004 Frodo Looijaard <frodol@dds.nl>
3    
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8    
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     GNU General Public License for more details.
13    
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17     */
18    
19     #include "config.h"
20    
21     #include <psiconv/configuration.h>
22     #include <psiconv/data.h>
23     #include "general.h"
24    
25     #include <string.h>
26     #include <stdlib.h>
27    
28     #ifdef DMALLOC
29     #include "dmalloc.h"
30     #endif
31    
32     #define TEMPSTR_LEN 100
33    
34     void color(const psiconv_config config, psiconv_list list,
35     psiconv_color color,int may_be_transparant, const encoding enc)
36     {
37     char tempstr[TEMPSTR_LEN];
38     if (may_be_transparant &&
39     (color->red == 0xff) &&
40     (color->blue == 0xff) &&
41     (color->green == 0xff))
42     output_simple_chars(config,list,"transparant",enc);
43     else {
44     snprintf(tempstr,TEMPSTR_LEN,"rgb(%d,%d,%d)",
45     color->red,
46     color->green,
47     color->blue);
48     output_simple_chars(config,list,tempstr,enc);
49     }
50     }
51    
52     void style_name(const psiconv_config config, psiconv_list list,
53     const psiconv_string_t name,const encoding enc)
54     {
55     psiconv_string_t name_copy;
56     int i;
57    
58     if (!name)
59     return;
60    
61     if (!(name_copy = psiconv_unicode_strdup(name))) {
62     fputs("Out of memory error\n",stderr);
63     exit(1);
64     }
65     for (i = 0; i < psiconv_unicode_strlen(name_copy); i++) {
66     if ((name_copy[i] < 0x21) ||
67     ((name_copy[i] >= 0x7f) && name_copy[i] <= 0xa0))
68     name_copy[i] = '_';
69     }
70     output_string(config,list,name_copy,enc);
71     free(name_copy);
72     }
73    
74     void character_layout_diffs(const psiconv_config config, psiconv_list list,
75     const psiconv_character_layout new,
76     const psiconv_character_layout base,
77     const encoding enc)
78     {
79     char tempstr[TEMPSTR_LEN];
80    
81     if (!base || (new->italic != base->italic)) {
82     output_simple_chars(config,list,"font-style:",enc);
83     output_simple_chars(config,list,new->italic?"italic":"normal",enc);
84     output_simple_chars(config,list,";",enc);
85     }
86     if (!base || (new->underline != base->underline) ||
87     (new->strikethrough != base->strikethrough)) {
88     output_simple_chars(config,list,"text-decoration:",enc);
89     output_simple_chars(config,list,new->underline?"underline":
90     new->strikethrough?"line-through":
91     "none",enc);
92     output_simple_chars(config,list,";",enc);
93     }
94     if (!base || (new->bold != base->bold)) {
95     output_simple_chars(config,list,"font-weight:",enc);
96     output_simple_chars(config,list,new->bold?"bold":"normal",enc);
97     output_simple_chars(config,list,";",enc);
98     }
99     if (!base || (new->super_sub != base->super_sub)) {
100     output_simple_chars(config,list,"font-style:",enc);
101     output_simple_chars(config,list,
102     new->super_sub==psiconv_superscript?"super":
103     new->super_sub==psiconv_subscript?"sub":
104     "normal",enc);
105     output_simple_chars(config,list,";",enc);
106     }
107    
108     if (!base || (new->color->red != base->color->red) ||
109     (new->color->green != base->color->green) ||
110     (new->color->blue != base->color->blue)) {
111     output_simple_chars(config,list,"color:",enc);
112     color(config,list,new->color,0,enc);
113     output_simple_chars(config,list,";",enc);
114     }
115    
116     if (!base || (new->back_color->red != base->back_color->red) ||
117     (new->back_color->green != base->back_color->green) ||
118     (new->back_color->blue != base->back_color->blue)) {
119     output_simple_chars(config,list,"background-color:",enc);
120     color(config,list,new->back_color,1,enc);
121     output_simple_chars(config,list,";",enc);
122     }
123    
124     if (!base || (new->font_size != base->font_size)) {
125     output_simple_chars(config,list,"font-size:",enc);
126     snprintf(tempstr,TEMPSTR_LEN,"%f",new->font_size);
127     output_simple_chars(config,list,tempstr,enc);
128     output_simple_chars(config,list,"pt;",enc);
129     }
130     }
131    
132     void paragraph_layout_diffs(const psiconv_config config, psiconv_list list,
133     const psiconv_paragraph_layout new,
134     const psiconv_paragraph_layout base,
135     const encoding enc)
136     {
137     char tempstr[TEMPSTR_LEN];
138    
139     if (!base || (new->back_color->red != base->back_color->red) ||
140     (new->back_color->green != base->back_color->green) ||
141     (new->back_color->blue != base->back_color->blue)) {
142     output_simple_chars(config,list,"background-color:",enc);
143     color(config,list,new->back_color,1,enc);
144     output_simple_chars(config,list,";",enc);
145     }
146    
147     if (!base || (new->indent_left != base->indent_left)) {
148     output_simple_chars(config,list,"padding-left:",enc);
149     snprintf(tempstr,TEMPSTR_LEN,"%f",new->indent_left);
150     output_simple_chars(config,list,tempstr,enc);
151     output_simple_chars(config,list,"cm;",enc);
152     }
153    
154     if (!base || (new->indent_right != base->indent_right)) {
155     output_simple_chars(config,list,"padding-right:",enc);
156     snprintf(tempstr,TEMPSTR_LEN,"%f",new->indent_right);
157     output_simple_chars(config,list,tempstr,enc);
158     output_simple_chars(config,list,"cm;",enc);
159     }
160    
161     if (!base || (new->indent_left - new->indent_first !=
162     base->indent_left - base->indent_first)) {
163     output_simple_chars(config,list,"text-indent:",enc);
164     snprintf(tempstr,TEMPSTR_LEN,"%f",new->indent_right - new->indent_first);
165     output_simple_chars(config,list,tempstr,enc);
166     output_simple_chars(config,list,"cm;",enc);
167     }
168    
169     if (!base || (new->justify_hor != base ->justify_hor)) {
170     output_simple_chars(config,list,"font-style:",enc);
171     output_simple_chars(config,list,
172     new->justify_hor==psiconv_justify_left?"left":
173     new->justify_hor==psiconv_justify_centre?"center":
174     new->justify_hor==psiconv_justify_right?"right":
175     new->justify_hor==psiconv_justify_full?"justify":
176     "",enc);
177     output_simple_chars(config,list,";",enc);
178     }
179    
180     if (!base || (new->linespacing != base->linespacing)) {
181     output_simple_chars(config,list,"line-height:",enc);
182     snprintf(tempstr,TEMPSTR_LEN,"%f",new->linespacing);
183     output_simple_chars(config,list,tempstr,enc);
184     output_simple_chars(config,list,"pt;",enc);
185     }
186    
187     if (!base || (new->space_above != base->space_above)) {
188     output_simple_chars(config,list,"padding-top:",enc);
189     snprintf(tempstr,TEMPSTR_LEN,"%f",new->space_above);
190     output_simple_chars(config,list,tempstr,enc);
191     output_simple_chars(config,list,"pt;",enc);
192     }
193    
194     if (!base || (new->space_below != base->space_below)) {
195     output_simple_chars(config,list,"padding-bottom:",enc);
196     snprintf(tempstr,TEMPSTR_LEN,"%f",new->space_below);
197     output_simple_chars(config,list,tempstr,enc);
198     output_simple_chars(config,list,"pt;",enc);
199     }
200    
201     }
202    
203     void style(const psiconv_config config, psiconv_list list,
204     const psiconv_word_style style,
205     const psiconv_paragraph_layout base_para,
206     const psiconv_character_layout base_char,
207     const encoding enc)
208     {
209     output_simple_chars(config,list,"p[class=\"style_",enc);
210     style_name(config,list,style->name,enc);
211     output_simple_chars(config,list,"\"] {",enc);
212     paragraph_layout_diffs(config,list,style->paragraph,base_para,enc);
213     character_layout_diffs(config,list,style->character,base_char,enc);
214     output_simple_chars(config,list,"}\n",enc);
215     }
216    
217     void styles(const psiconv_config config, psiconv_list list,
218     const psiconv_word_styles_section styles_sec,const encoding enc)
219     {
220     int i;
221     psiconv_word_style styl;
222     psiconv_character_layout base_char;
223     psiconv_paragraph_layout base_para;
224    
225     if (!(base_char = psiconv_basic_character_layout())) {
226     fputs("Out of memory error\n",stderr);
227     exit(1);
228     }
229     if (!(base_para = psiconv_basic_paragraph_layout())) {
230     fputs("Out of memory error\n",stderr);
231     exit(1);
232     }
233    
234     output_simple_chars(config,list,"<style type=\"text/css\">\n",enc);
235     /* output_simple_chars(config,list,"<![CDATA[\n",enc); */
236    
237     output_simple_chars(config,list,"body {",enc);
238     paragraph_layout_diffs(config,list,base_para,NULL,enc);
239     character_layout_diffs(config,list,base_char,NULL,enc);
240     output_simple_chars(config,list,"}\n",enc);
241    
242     if (styles_sec) {
243     style(config,list,styles_sec->normal,base_para,base_char,enc);
244    
245     for (i = 0; i < psiconv_list_length(styles_sec->styles); i++) {
246     if (!(styl = psiconv_list_get(styles_sec->styles,i))) {
247     fputs("Internal datastructure corruption\n",stderr);
248     exit(1);
249     }
250     style(config,list,styl,base_para,base_char,enc);
251     }
252     }
253    
254     /* output_simple_chars(config,list,"]]>\n",enc); */
255     output_simple_chars(config,list,"</style>\n",enc);
256     }
257    
258     void header(const psiconv_config config, psiconv_list list,
259     const psiconv_word_styles_section styles_sec,const encoding enc)
260     {
261     output_simple_chars(config,list,
262     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",enc);
263     output_simple_chars(config,list,"<!DOCTYPE html PUBLIC ",enc);
264     output_simple_chars(config,list, "\"-//W3C//DTD XHTML 1.0 Strict//EN\" ",enc);
265     output_simple_chars(config,list,
266     "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
267     enc);
268     output_simple_chars(config,list,"\n<html",enc);
269     output_simple_chars(config,list,
270     " xmlns=\"http://www.w3.org/1999/xhtml\"",enc);
271     output_simple_chars(config,list,">\n",enc);
272     output_simple_chars(config,list,"<head>\n",enc);
273     output_simple_chars(config,list,"<meta http-equiv=\"Content-Type\" "
274     "content=\"text/html; charset=",enc);
275     output_simple_chars(config,list,enc==ENCODING_UTF8?"UTF-8":
276     enc==ENCODING_UCS2?"UTF-16BE":
277     enc==ENCODING_ASCII?"US-ASCII":
278     "",enc);
279     output_simple_chars(config,list,"\">\n",enc);
280     output_simple_chars(config,list,"<meta http-equiv=\"Content-Style-Type\" "
281     "content=\"text/css\">\n",enc);
282     output_simple_chars(config,list,"<title>EPOC32 file "
283     "converted by psiconv</title>\n",enc);
284     styles(config,list,styles_sec,enc);
285     output_simple_chars(config,list,"</head>\n",enc);
286     output_simple_chars(config,list,"<body>\n",enc);
287     }
288    
289     void footer(const psiconv_config config, psiconv_list list, const encoding enc)
290     {
291     output_simple_chars(config,list,"</body>\n",enc);
292     output_simple_chars(config,list,"</html>\n",enc);
293     }
294    
295     void characters(const psiconv_config config, psiconv_list list,
296     const psiconv_string_t text,
297     const psiconv_character_layout layout,
298     const psiconv_character_layout base,
299     const encoding enc)
300     {
301     psiconv_list templist;
302    
303     if (!(templist = psiconv_list_new(sizeof(psiconv_u8)))) {
304     fputs("Out of memory error\n",stderr);
305     exit(1);
306     }
307     character_layout_diffs(config,templist,layout,base,enc);
308    
309     if (psiconv_list_length(templist)) {
310     output_simple_chars(config,list,"<span style=\"",enc);
311     if (psiconv_list_concat(list,templist)) {
312     fputs("Out of memory error\n",stderr);
313     exit(1);
314     }
315     output_simple_chars(config,list,"\">",enc);
316     }
317    
318     output_string(config,list,text,enc);
319    
320     if (psiconv_list_length(templist)) {
321     output_simple_chars(config,list,"</span>",enc);
322     }
323    
324     psiconv_list_free(templist);
325     }
326    
327     void paragraph(const psiconv_config config, psiconv_list list,
328     const psiconv_paragraph para,
329     const psiconv_word_styles_section styles_sec,
330     const encoding enc)
331     {
332     int i,charnr;
333     psiconv_string_t text;
334     psiconv_in_line_layout layout;
335     psiconv_word_style style = NULL;
336     psiconv_paragraph_layout base_para;
337     psiconv_character_layout base_char;
338     psiconv_list templist;
339    
340     if (!(templist = psiconv_list_new(sizeof(psiconv_u8)))) {
341     fputs("Out of memory error\n",stderr);
342     exit(1);
343     }
344    
345     if (styles_sec) {
346     if (!(style = psiconv_get_style(styles_sec,para->base_style))) {
347     fputs("Unknown style found; data corrupt\n",stderr);
348     exit(1);
349     }
350     base_para = style->paragraph;
351     base_char = style->character;
352     } else {
353     base_para = psiconv_basic_paragraph_layout();
354     base_char = psiconv_basic_character_layout();
355     if (!base_para || !base_char) {
356     fputs("Out of memory error\n",stderr);
357     exit(1);
358     }
359     }
360    
361     output_simple_chars(config,list,"<p ",enc);
362    
363     if (styles_sec) {
364     output_simple_chars(config,list,"class=\"style_",enc);
365     style_name(config,list,style->name,enc);
366     output_simple_chars(config,list,"\" ",enc);
367     }
368    
369     paragraph_layout_diffs(config,templist,para->base_paragraph,base_para,enc);
370     character_layout_diffs(config,templist,para->base_character,base_char,enc);
371    
372     if (psiconv_list_length(templist)) {
373     output_simple_chars(config,list,"style=\"",enc);
374     if (psiconv_list_concat(list,templist)) {
375     fputs("Out of memory error\n",stderr);
376     exit(1);
377     }
378     output_simple_chars(config,list,"\"",enc);
379     }
380     output_simple_chars(config,list,">",enc);
381    
382     if (psiconv_list_length(para->in_lines) == 0) {
383     characters(config,list,para->text,para->base_character,
384     para->base_character,enc);
385     } else {
386     charnr = 0;
387     for (i = 0; i < psiconv_list_length(para->in_lines); i++) {
388     if (!(layout = psiconv_list_get(para->in_lines,i))) {
389     fputs("Internal data structures corruption\n",stderr);
390     exit(1);
391     }
392     if (!(text = malloc(sizeof (*text) * (layout->length + 1)))) {
393     fputs("Out of memory error\n",stderr);
394     exit(1);
395     }
396     memcpy(text,para->text+charnr,layout->length * sizeof(*text));
397     text[layout->length] = 0;
398     characters(config,list,text,layout->layout,para->base_character,enc);
399     free(text);
400     charnr += layout->length;
401     }
402     }
403     output_simple_chars(config,list,"</p>\n",enc);
404     if (!styles_sec) {
405     psiconv_free_paragraph_layout(base_para);
406     psiconv_free_character_layout(base_char);
407     }
408     psiconv_list_free(templist);
409     }
410    
411     void paragraphs(const psiconv_config config, psiconv_list list,
412     psiconv_text_and_layout paragraphs,
413     const psiconv_word_styles_section styles,
414     const encoding enc)
415     {
416     int i;
417     psiconv_paragraph para;
418     for (i = 0; i < psiconv_list_length(paragraphs); i++) {
419     if (!(para = psiconv_list_get(paragraphs,i))) {
420     fputs("Internal datastructure corruption\n",stderr);
421     exit(1);
422     }
423     paragraph(config,list,para,styles,enc);
424     }
425     }
426    
427     void gen_html_word(const psiconv_config config, psiconv_list list,
428     const psiconv_word_f file, const encoding enc)
429     {
430     if (!file)
431     return;
432    
433     header(config,list,file->styles_sec,enc);
434     paragraphs(config,list,file->paragraphs,file->styles_sec,enc);
435     footer(config,list,enc);
436     }
437    
438    
439     void gen_html_texted(const psiconv_config config, psiconv_list list,
440     const psiconv_texted_f file, const encoding enc)
441     {
442     header(config,list,NULL,enc);
443     paragraphs(config,list,file->texted_sec->paragraphs,NULL,enc);
444     footer(config,list,enc);
445     }
446    
447     int gen_html(const psiconv_config config, psiconv_list list,
448     const psiconv_file file, const char *dest,
449     const encoding enc)
450     {
451     if (enc == ENCODING_PSION) {
452     fputs("Unsupported encoding\n",stderr);
453     return -1;
454     }
455    
456     if (file->type == psiconv_word_file) {
457     gen_html_word(config,list,(psiconv_word_f) file->file,enc);
458     return 0;
459     } else if (file->type == psiconv_texted_file) {
460     gen_html_texted(config,list,(psiconv_texted_f) file->file,enc);
461     return 0;
462     } else
463     return -1;
464     }
465    
466    
467     static struct fileformat_s ffs[] =
468     {
469     {
470     "XHTML",
471     "XHTML 1.0 Strict, using CSS for formatting",
472     gen_html
473     },
474     {
475     NULL,
476     NULL,
477     NULL
478     }
479     };
480    
481    
482     void init_html(void)
483     {
484     int i;
485     for (i = 0; ffs[i].name; i++)
486     psiconv_list_add(fileformat_list,ffs+i);
487     }

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