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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /* 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