/[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 351 - (show annotations)
Wed Oct 22 19:53:40 2014 UTC (9 years, 5 months ago) by frodo
File MIME type: text/plain
File size: 27947 byte(s)
(Frodo) Update copyright year in all source files

1 /* gen_html.c - Part of psiconv, a PSION 5 file formats converter
2 Copyright (c) 1999-2014 Frodo Looijaard <frodo@frodo.looijaard.name>
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 #include "gen.h"
25
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29
30 #ifdef DMALLOC
31 #include "dmalloc.h"
32 #endif
33
34 #define TEMPSTR_LEN 100
35
36 static void text(const psiconv_config config,psiconv_list list,
37 psiconv_string_t data,const encoding enc);
38 static void color(const psiconv_config config, psiconv_list list,
39 psiconv_color color,int may_be_transparant, const encoding enc);
40 static void border(const psiconv_config config, psiconv_list list,
41 psiconv_border_kind_t border,const encoding enc);
42 static void style_name(const psiconv_config config, psiconv_list list,
43 const psiconv_string_t name,const encoding enc);
44 static int character_layout_equal(const psiconv_character_layout l1,
45 const psiconv_character_layout l2);
46 static void character_layout_diffs(const psiconv_config config,
47 psiconv_list list,
48 const psiconv_character_layout new,
49 const psiconv_character_layout base,
50 const encoding enc);
51 static void paragraph_layout_diffs(const psiconv_config config,
52 psiconv_list list,
53 const psiconv_paragraph_layout new,
54 const psiconv_paragraph_layout base,
55 const encoding enc);
56 static void style(const psiconv_config config, psiconv_list list,
57 const psiconv_word_style style,
58 const psiconv_paragraph_layout base_para,
59 const psiconv_character_layout base_char,
60 const encoding enc);
61 static void styles(const psiconv_config config, psiconv_list list,
62 const psiconv_word_styles_section styles_sec,const encoding enc);
63 static void header(const psiconv_config config, psiconv_list list,
64 const psiconv_word_styles_section styles_sec,const encoding enc);
65 static void footer(const psiconv_config config, psiconv_list list,
66 const encoding enc);
67 static void characters(const psiconv_config config, psiconv_list list,
68 const psiconv_string_t textstr,
69 const psiconv_character_layout layout,
70 const psiconv_character_layout base,
71 const encoding enc);
72 static void paragraphs(const psiconv_config config, psiconv_list list,
73 psiconv_text_and_layout paragraphs,
74 const psiconv_word_styles_section styles,
75 const encoding enc);
76 static void paragraph(const psiconv_config config, psiconv_list list,
77 const psiconv_paragraph para,
78 const psiconv_word_styles_section styles_sec,
79 const encoding enc);
80 static void gen_word(const psiconv_config config, psiconv_list list,
81 const psiconv_word_f file, const encoding enc);
82 static void gen_texted(const psiconv_config config, psiconv_list list,
83 const psiconv_texted_f file, const encoding enc);
84 static int gen_xhtml(const psiconv_config config, psiconv_list list,
85 const psiconv_file file, const char *dest,
86 const encoding enc);
87
88
89
90 void text(const psiconv_config config,psiconv_list list,
91 psiconv_string_t data,const encoding enc)
92 {
93 int i;
94 for (i = 0; i < psiconv_unicode_strlen(data); i++) {
95 if ((data[i] == 0x06) || (data[i] == 0x07) || (data[i] == 0x08))
96 output_simple_chars(config,list,"<br/>",enc);
97 else if ((data[i] == 0x0b) || (data[i] == 0x0c))
98 output_simple_chars(config,list,"-",enc);
99 else if ((data[i] == 0x0f) || (data[i] == 0x09) || (data[i] == 0x0a))
100 output_simple_chars(config,list," ",enc);
101 else if (data[i] >= 0x20)
102 output_char(config,list,data[i],enc);
103 }
104 }
105
106 void color(const psiconv_config config, psiconv_list list,
107 psiconv_color color,int may_be_transparant, const encoding enc)
108 {
109 char tempstr[TEMPSTR_LEN];
110 if (may_be_transparant &&
111 (color->red == 0xff) &&
112 (color->blue == 0xff) &&
113 (color->green == 0xff))
114 output_simple_chars(config,list,"transparant",enc);
115 else {
116 snprintf(tempstr,TEMPSTR_LEN,"rgb(%d,%d,%d)",
117 color->red,
118 color->green,
119 color->blue);
120 output_simple_chars(config,list,tempstr,enc);
121 }
122 }
123
124 void border(const psiconv_config config, psiconv_list list,
125 psiconv_border_kind_t border,const encoding enc)
126 {
127 output_simple_chars(config,list,
128 border == psiconv_border_none?"none":
129 border == psiconv_border_solid?"solid":
130 border == psiconv_border_double?"double":
131 border == psiconv_border_dotted?"dotted":
132 border == psiconv_border_dashed?"dashed":
133 border == psiconv_border_dotdashed?"dashed":
134 border == psiconv_border_dotdotdashed?"dashed":"",enc);
135 }
136
137 void style_name(const psiconv_config config, psiconv_list list,
138 const psiconv_string_t name,const encoding enc)
139 {
140 psiconv_string_t name_copy;
141 int i;
142
143 if (!name)
144 return;
145
146 if (!(name_copy = psiconv_unicode_strdup(name))) {
147 fputs("Out of memory error\n",stderr);
148 exit(1);
149 }
150 for (i = 0; i < psiconv_unicode_strlen(name_copy); i++) {
151 if ((name_copy[i] < 0x21) ||
152 ((name_copy[i] >= 0x7f) && name_copy[i] <= 0xa0))
153 name_copy[i] = '_';
154 }
155 output_string(config,list,name_copy,enc);
156 free(name_copy);
157 }
158
159 /* Check whether the same layout information would be generated */
160 int character_layout_equal(const psiconv_character_layout l1,
161 const psiconv_character_layout l2)
162 {
163 return (l1 && l2 &&
164 (l1->color->red == l2->color->red) &&
165 (l1->color->green == l2->color->green) &&
166 (l1->color->blue == l2->color->blue) &&
167 (l1->back_color->red == l2->back_color->red) &&
168 (l1->back_color->green == l2->back_color->green) &&
169 (l1->back_color->blue == l2->back_color->blue) &&
170 (l1->font_size == l2->font_size) &&
171 (l1->italic == l2->italic) &&
172 (l1->bold == l2->bold) &&
173 (l1->super_sub == l2->super_sub) &&
174 (l1->underline == l2->underline) &&
175 (l1->strikethrough == l2->strikethrough) &&
176 (l1->font->screenfont == l2->font->screenfont));
177 }
178
179 void character_layout_diffs(const psiconv_config config, psiconv_list list,
180 const psiconv_character_layout new,
181 const psiconv_character_layout base,
182 const encoding enc)
183 {
184 char tempstr[TEMPSTR_LEN];
185
186 if (!base || (new->color->red != base->color->red) ||
187 (new->color->green != base->color->green) ||
188 (new->color->blue != base->color->blue)) {
189 output_simple_chars(config,list,"color:",enc);
190 color(config,list,new->color,0,enc);
191 output_simple_chars(config,list,";",enc);
192 }
193
194 if (!base || (new->back_color->red != base->back_color->red) ||
195 (new->back_color->green != base->back_color->green) ||
196 (new->back_color->blue != base->back_color->blue)) {
197 output_simple_chars(config,list,"background-color:",enc);
198 color(config,list,new->back_color,1,enc);
199 output_simple_chars(config,list,";",enc);
200 }
201
202 if (!base || (new->font_size != base->font_size)) {
203 output_simple_chars(config,list,"font-size:",enc);
204 snprintf(tempstr,TEMPSTR_LEN,"%f",new->font_size);
205 output_simple_chars(config,list,tempstr,enc);
206 output_simple_chars(config,list,"pt;",enc);
207 }
208
209 if (!base || (new->italic != base->italic)) {
210 output_simple_chars(config,list,"font-style:",enc);
211 output_simple_chars(config,list,new->italic?"italic":"normal",enc);
212 output_simple_chars(config,list,";",enc);
213 }
214 if (!base || (new->bold != base->bold)) {
215 output_simple_chars(config,list,"font-weight:",enc);
216 output_simple_chars(config,list,new->bold?"bold":"normal",enc);
217 output_simple_chars(config,list,";",enc);
218 }
219 if (!base || (new->super_sub != base->super_sub)) {
220 output_simple_chars(config,list,"font-style:",enc);
221 output_simple_chars(config,list,
222 new->super_sub==psiconv_superscript?"super":
223 new->super_sub==psiconv_subscript?"sub":
224 "normal",enc);
225 output_simple_chars(config,list,";",enc);
226 }
227 if (!base || (new->underline != base->underline) ||
228 (new->strikethrough != base->strikethrough)) {
229 output_simple_chars(config,list,"text-decoration:",enc);
230 output_simple_chars(config,list,new->underline?"underline":
231 new->strikethrough?"line-through":
232 "none",enc);
233 output_simple_chars(config,list,";",enc);
234 }
235 if (!base || (new->font->screenfont != base->font->screenfont)) {
236 output_simple_chars(config,list,"font-family:",enc);
237 output_simple_chars(config,list,
238 new->font->screenfont == psiconv_font_serif?"serif":
239 new->font->screenfont == psiconv_font_sansserif?"sans-serif":
240 new->font->screenfont == psiconv_font_nonprop?"monospace":
241 new->font->screenfont == psiconv_font_misc?"fantasy":"",
242 enc);
243 }
244 }
245
246 void paragraph_layout_diffs(const psiconv_config config, psiconv_list list,
247 const psiconv_paragraph_layout new,
248 const psiconv_paragraph_layout base,
249 const encoding enc)
250 {
251 char tempstr[TEMPSTR_LEN];
252 float pad_left_base=0.0,pad_left_new,text_indent_base=0.0,text_indent_new;
253
254 if (new->bullet->on) {
255 pad_left_new = new->indent_left < new->indent_first?
256 new->indent_left:new->indent_first;
257 text_indent_new = 0.0;
258 } else {
259 pad_left_new = new->indent_left;
260 text_indent_new = new->indent_first;
261 }
262 if (base) {
263 if (base->bullet->on) {
264 pad_left_base = base->indent_left < base->indent_first?
265 base->indent_left:base->indent_first;
266 text_indent_base = 0.0;
267 } else {
268 pad_left_base = base->indent_left;
269 text_indent_base = base->indent_first;
270 }
271 }
272
273
274 if (!base || (new->back_color->red != base->back_color->red) ||
275 (new->back_color->green != base->back_color->green) ||
276 (new->back_color->blue != base->back_color->blue)) {
277 output_simple_chars(config,list,"background-color:",enc);
278 color(config,list,new->back_color,1,enc);
279 output_simple_chars(config,list,";",enc);
280 }
281
282 if (!base || (pad_left_new != pad_left_base)) {
283 output_simple_chars(config,list,"padding-left:",enc);
284 snprintf(tempstr,TEMPSTR_LEN,"%f",pad_left_new);
285 output_simple_chars(config,list,tempstr,enc);
286 output_simple_chars(config,list,"cm;",enc);
287 }
288
289 if (!base || (new->indent_right != base->indent_right)) {
290 output_simple_chars(config,list,"padding-right:",enc);
291 snprintf(tempstr,TEMPSTR_LEN,"%f",new->indent_right);
292 output_simple_chars(config,list,tempstr,enc);
293 output_simple_chars(config,list,"cm;",enc);
294 }
295
296 if (!base || (text_indent_new != text_indent_base)) {
297 output_simple_chars(config,list,"text-indent:",enc);
298 snprintf(tempstr,TEMPSTR_LEN,"%f",text_indent_new);
299 output_simple_chars(config,list,tempstr,enc);
300 output_simple_chars(config,list,"cm;",enc);
301 }
302
303 if (!base || (new->justify_hor != base ->justify_hor)) {
304 output_simple_chars(config,list,"font-style:",enc);
305 output_simple_chars(config,list,
306 new->justify_hor==psiconv_justify_left?"left":
307 new->justify_hor==psiconv_justify_centre?"center":
308 new->justify_hor==psiconv_justify_right?"right":
309 new->justify_hor==psiconv_justify_full?"justify":
310 "",enc);
311 output_simple_chars(config,list,";",enc);
312 }
313
314 #if 0
315 /* This gave bad output... */
316 if (!base || (new->linespacing != base->linespacing)) {
317 output_simple_chars(config,list,"line-height:",enc);
318 snprintf(tempstr,TEMPSTR_LEN,"%f",new->linespacing);
319 output_simple_chars(config,list,tempstr,enc);
320 output_simple_chars(config,list,"pt;",enc);
321 }
322 #endif
323
324 if (!base || (new->space_above != base->space_above)) {
325 output_simple_chars(config,list,"padding-top:",enc);
326 snprintf(tempstr,TEMPSTR_LEN,"%f",new->space_above);
327 output_simple_chars(config,list,tempstr,enc);
328 output_simple_chars(config,list,"pt;",enc);
329 }
330
331 if (!base || (new->space_below != base->space_below)) {
332 output_simple_chars(config,list,"padding-bottom:",enc);
333 snprintf(tempstr,TEMPSTR_LEN,"%f",new->space_below);
334 output_simple_chars(config,list,tempstr,enc);
335 output_simple_chars(config,list,"pt;",enc);
336 }
337
338 if (!base || (new->right_border->kind != base->right_border->kind)) {
339 output_simple_chars(config,list,"border-right-style:",enc);
340 border(config,list,new->right_border->kind,enc);
341 output_simple_chars(config,list,";",enc);
342 }
343 if (!base || (new->bottom_border->kind != base->bottom_border->kind)) {
344 output_simple_chars(config,list,"border-bottom-style:",enc);
345 border(config,list,new->bottom_border->kind,enc);
346 output_simple_chars(config,list,";",enc);
347 }
348 if (!base || (new->top_border->kind != base->top_border->kind)) {
349 output_simple_chars(config,list,"border-top-style:",enc);
350 border(config,list,new->top_border->kind,enc);
351 output_simple_chars(config,list,";",enc);
352 }
353 if (!base || (new->left_border->kind != base->left_border->kind)) {
354 output_simple_chars(config,list,"border-left-style:",enc);
355 border(config,list,new->left_border->kind,enc);
356 output_simple_chars(config,list,";",enc);
357 }
358
359 if (!base ||
360 ((new->right_border->kind != psiconv_border_none) &&
361 (new->right_border->thickness != base->right_border->thickness))) {
362 output_simple_chars(config,list,"border-right-width:",enc);
363 snprintf(tempstr,TEMPSTR_LEN,"%f",new->right_border->thickness);
364 output_simple_chars(config,list,tempstr,enc);
365 output_simple_chars(config,list,"pt;",enc);
366 }
367 if (!base ||
368 ((new->bottom_border->kind != psiconv_border_none) &&
369 (new->bottom_border->thickness != base->bottom_border->thickness))) {
370 output_simple_chars(config,list,"border-bottom-width:",enc);
371 snprintf(tempstr,TEMPSTR_LEN,"%f",new->bottom_border->thickness);
372 output_simple_chars(config,list,tempstr,enc);
373 output_simple_chars(config,list,"pt;",enc);
374 }
375 if (!base ||
376 ((new->top_border->kind != psiconv_border_none) &&
377 ( new->top_border->thickness != base->top_border->thickness))) {
378 output_simple_chars(config,list,"border-top-width:",enc);
379 snprintf(tempstr,TEMPSTR_LEN,"%f",new->top_border->thickness);
380 output_simple_chars(config,list,tempstr,enc);
381 output_simple_chars(config,list,"pt;",enc);
382 }
383 if (!base ||
384 ((new->left_border->kind != psiconv_border_none) &&
385 (new->left_border->thickness != base->left_border->thickness))) {
386 output_simple_chars(config,list,"border-left-width:",enc);
387 snprintf(tempstr,TEMPSTR_LEN,"%f",new->left_border->thickness);
388 output_simple_chars(config,list,tempstr,enc);
389 output_simple_chars(config,list,"pt;",enc);
390 }
391
392 if (!base ||
393 ((new->right_border->kind != psiconv_border_none) &&
394 ((new->right_border->color->red != base->right_border->color->red) ||
395 (new->right_border->color->green != base->right_border->color->green)||
396 (new->right_border->color->blue != base->right_border->color->blue)))) {
397 output_simple_chars(config,list,"border-right-color:",enc);
398 color(config,list,new->right_border->color,0,enc);
399 output_simple_chars(config,list,";",enc);
400 }
401 if (!base ||
402 ((new->top_border->kind != psiconv_border_none) &&
403 ((new->top_border->color->red != base->top_border->color->red) ||
404 (new->top_border->color->green != base->top_border->color->green) ||
405 (new->top_border->color->blue != base->top_border->color->blue)))) {
406 output_simple_chars(config,list,"border-top-color:",enc);
407 color(config,list,new->top_border->color,0,enc);
408 output_simple_chars(config,list,";",enc);
409 }
410 if (!base ||
411 ((new->bottom_border->kind != psiconv_border_none) &&
412 ((new->bottom_border->color->red != base->bottom_border->color->red) ||
413 (new->bottom_border->color->green !=base->bottom_border->color->green)||
414 (new->bottom_border->color->blue != base->bottom_border->color->blue)))){
415 output_simple_chars(config,list,"border-bottom-color:",enc);
416 color(config,list,new->bottom_border->color,0,enc);
417 output_simple_chars(config,list,";",enc);
418 }
419 if (!base ||
420 ((new->left_border->kind != psiconv_border_none) &&
421 ((new->left_border->color->red != base->left_border->color->red) ||
422 (new->left_border->color->green != base->left_border->color->green) ||
423 (new->left_border->color->blue != base->left_border->color->blue)))) {
424 output_simple_chars(config,list,"border-left-color:",enc);
425 color(config,list,new->left_border->color,0,enc);
426 output_simple_chars(config,list,";",enc);
427 }
428 }
429
430 void style(const psiconv_config config, psiconv_list list,
431 const psiconv_word_style style,
432 const psiconv_paragraph_layout base_para,
433 const psiconv_character_layout base_char,
434 const encoding enc)
435 {
436 output_simple_chars(config,list,"*.style_",enc);
437 style_name(config,list,style->name,enc);
438 output_simple_chars(config,list," {",enc);
439 paragraph_layout_diffs(config,list,style->paragraph,base_para,enc);
440 character_layout_diffs(config,list,style->character,base_char,enc);
441 output_simple_chars(config,list,"}\n",enc);
442 }
443
444 void styles(const psiconv_config config, psiconv_list list,
445 const psiconv_word_styles_section styles_sec,const encoding enc)
446 {
447 int i;
448 psiconv_word_style styl;
449 psiconv_character_layout base_char;
450 psiconv_paragraph_layout base_para;
451
452 if (!(base_char = psiconv_basic_character_layout())) {
453 fputs("Out of memory error\n",stderr);
454 exit(1);
455 }
456 if (!(base_para = psiconv_basic_paragraph_layout())) {
457 fputs("Out of memory error\n",stderr);
458 exit(1);
459 }
460
461 output_simple_chars(config,list,"<style type=\"text/css\">\n",enc);
462 /* output_simple_chars(config,list,"<![CDATA[\n",enc); */
463
464 output_simple_chars(config,list,"body {",enc);
465 paragraph_layout_diffs(config,list,base_para,NULL,enc);
466 character_layout_diffs(config,list,base_char,NULL,enc);
467 output_simple_chars(config,list,"}\n",enc);
468
469 if (styles_sec) {
470 style(config,list,styles_sec->normal,base_para,base_char,enc);
471
472 for (i = 0; i < psiconv_list_length(styles_sec->styles); i++) {
473 if (!(styl = psiconv_list_get(styles_sec->styles,i))) {
474 fputs("Internal datastructure corruption\n",stderr);
475 exit(1);
476 }
477 style(config,list,styl,base_para,base_char,enc);
478 }
479 }
480
481 /* output_simple_chars(config,list,"]]>\n",enc); */
482 output_simple_chars(config,list,"</style>\n",enc);
483 }
484
485 void header(const psiconv_config config, psiconv_list list,
486 const psiconv_word_styles_section styles_sec,const encoding enc)
487 {
488 output_simple_chars(config,list,
489 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",enc);
490 output_simple_chars(config,list,"<!DOCTYPE html PUBLIC ",enc);
491 output_simple_chars(config,list, "\"-//W3C//DTD XHTML 1.0 Strict//EN\" ",enc);
492 output_simple_chars(config,list,
493 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
494 enc);
495 output_simple_chars(config,list,"\n<html",enc);
496 output_simple_chars(config,list,
497 " xmlns=\"http://www.w3.org/1999/xhtml\"",enc);
498 output_simple_chars(config,list,">\n",enc);
499 output_simple_chars(config,list,"<head>\n",enc);
500 output_simple_chars(config,list,"<meta http-equiv=\"Content-Type\" "
501 "content=\"text/html; charset=",enc);
502 output_simple_chars(config,list,enc==ENCODING_UTF8?"UTF-8":
503 enc==ENCODING_UCS2?"UTF-16BE":
504 enc==ENCODING_ASCII?"US-ASCII":
505 "",enc);
506 output_simple_chars(config,list,"\">\n",enc);
507 output_simple_chars(config,list,"<meta http-equiv=\"Content-Style-Type\" "
508 "content=\"text/css\">\n",enc);
509 output_simple_chars(config,list,"<title>EPOC32 file "
510 "converted by psiconv</title>\n",enc);
511 styles(config,list,styles_sec,enc);
512 output_simple_chars(config,list,"</head>\n",enc);
513 output_simple_chars(config,list,"<body>\n",enc);
514 }
515
516 void footer(const psiconv_config config, psiconv_list list, const encoding enc)
517 {
518 output_simple_chars(config,list,"</body>\n",enc);
519 output_simple_chars(config,list,"</html>\n",enc);
520 }
521
522 void characters(const psiconv_config config, psiconv_list list,
523 const psiconv_string_t textstr,
524 const psiconv_character_layout layout,
525 const psiconv_character_layout base,
526 const encoding enc)
527 {
528 psiconv_list templist;
529
530 if (!(templist = psiconv_list_new(sizeof(psiconv_u8)))) {
531 fputs("Out of memory error\n",stderr);
532 exit(1);
533 }
534 character_layout_diffs(config,templist,layout,base,enc);
535
536 if (psiconv_list_length(templist)) {
537 output_simple_chars(config,list,"<span style=\"",enc);
538 if (psiconv_list_concat(list,templist)) {
539 fputs("Out of memory error\n",stderr);
540 exit(1);
541 }
542 output_simple_chars(config,list,"\">",enc);
543 }
544
545 text(config,list,textstr,enc);
546
547 if (psiconv_list_length(templist)) {
548 output_simple_chars(config,list,"</span>",enc);
549 }
550
551 psiconv_list_free(templist);
552 }
553
554 void paragraph(const psiconv_config config, psiconv_list list,
555 const psiconv_paragraph para,
556 const psiconv_word_styles_section styles_sec,
557 const encoding enc)
558 {
559 int i,charnr,start,len;
560 psiconv_string_t text;
561 psiconv_in_line_layout layout,next_layout;
562 psiconv_word_style style = NULL;
563 psiconv_paragraph_layout base_para;
564 psiconv_character_layout base_char;
565 psiconv_list templist;
566
567 if (!(templist = psiconv_list_new(sizeof(psiconv_u8)))) {
568 fputs("Out of memory error\n",stderr);
569 exit(1);
570 }
571
572 if (styles_sec) {
573 if (!(style = psiconv_get_style(styles_sec,para->base_style))) {
574 fputs("Unknown style found; data corrupt\n",stderr);
575 exit(1);
576 }
577 base_para = style->paragraph;
578 base_char = style->character;
579 } else {
580 base_para = psiconv_basic_paragraph_layout();
581 base_char = psiconv_basic_character_layout();
582 if (!base_para || !base_char) {
583 fputs("Out of memory error\n",stderr);
584 exit(1);
585 }
586 }
587
588 output_simple_chars(config,
589 list,para->base_paragraph->bullet->on?"<ul><li ":"<p ",
590 enc);
591
592 if (styles_sec) {
593 output_simple_chars(config,list,"class=\"style_",enc);
594 style_name(config,list,style->name,enc);
595 output_simple_chars(config,list,"\" ",enc);
596 }
597
598 paragraph_layout_diffs(config,templist,para->base_paragraph,base_para,enc);
599 character_layout_diffs(config,templist,para->base_character,base_char,enc);
600
601 if (psiconv_list_length(templist)) {
602 output_simple_chars(config,list,"style=\"",enc);
603 if (psiconv_list_concat(list,templist)) {
604 fputs("Out of memory error\n",stderr);
605 exit(1);
606 }
607 output_simple_chars(config,list,"\"",enc);
608 }
609 output_simple_chars(config,list,">",enc);
610
611 if (psiconv_list_length(para->in_lines) == 0) {
612 if (psiconv_unicode_strlen(para->text))
613 characters(config,list,para->text,para->base_character,
614 para->base_character,enc);
615 } else {
616 charnr = 0;
617 start = -1;
618 for (i = 0; i < psiconv_list_length(para->in_lines); i++) {
619 if (start < 0)
620 start = charnr;
621 if (!(layout = psiconv_list_get(para->in_lines,i))) {
622 fputs("Internal data structures corruption\n",stderr);
623 exit(1);
624 }
625 if (i+1 < psiconv_list_length(para->in_lines)) {
626 if (!(next_layout = psiconv_list_get(para->in_lines,i+1))) {
627 fputs("Internal data structures corruption\n",stderr);
628 exit(1);
629 }
630 } else {
631 next_layout = NULL;
632 }
633 if (next_layout &&
634 character_layout_equal(layout->layout,next_layout->layout)) {
635 charnr += layout->length;
636 continue;
637 }
638 len = charnr - start + layout->length;
639 if (len) {
640 if (!(text = malloc(sizeof (*text) * (len + 1)))) {
641 fputs("Out of memory error\n",stderr);
642 exit(1);
643 }
644 memcpy(text,para->text+start,len * sizeof(*text));
645 text[len] = 0;
646 characters(config,list,text,layout->layout,para->base_character,enc);
647 free(text);
648 }
649 charnr += layout->length;
650 start = -1;
651 }
652 }
653 output_simple_chars(config, list,
654 para->base_paragraph->bullet->on?"</li></ul>\n":"</p>\n",
655 enc);
656 if (!styles_sec) {
657 psiconv_free_paragraph_layout(base_para);
658 psiconv_free_character_layout(base_char);
659 }
660 psiconv_list_free(templist);
661 }
662
663 void paragraphs(const psiconv_config config, psiconv_list list,
664 psiconv_text_and_layout paragraphs,
665 const psiconv_word_styles_section styles,
666 const encoding enc)
667 {
668 int i;
669 psiconv_paragraph para;
670 for (i = 0; i < psiconv_list_length(paragraphs); i++) {
671 if (!(para = psiconv_list_get(paragraphs,i))) {
672 fputs("Internal datastructure corruption\n",stderr);
673 exit(1);
674 }
675 paragraph(config,list,para,styles,enc);
676 }
677 }
678
679 void gen_word(const psiconv_config config, psiconv_list list,
680 const psiconv_word_f file, const encoding enc)
681 {
682 if (!file)
683 return;
684
685 header(config,list,file->styles_sec,enc);
686 paragraphs(config,list,file->paragraphs,file->styles_sec,enc);
687 footer(config,list,enc);
688 }
689
690
691 void gen_texted(const psiconv_config config, psiconv_list list,
692 const psiconv_texted_f file, const encoding enc)
693 {
694 header(config,list,NULL,enc);
695 paragraphs(config,list,file->texted_sec->paragraphs,NULL,enc);
696 footer(config,list,enc);
697 }
698
699 int gen_xhtml(const psiconv_config config, psiconv_list list,
700 const psiconv_file file, const char *dest,
701 const encoding enc)
702 {
703 encoding enc1 = enc;
704
705 if (enc == ENCODING_PSION) {
706 fputs("Unsupported encoding\n",stderr);
707 return -1;
708 } else if (enc == ENCODING_ASCII)
709 enc1 = ENCODING_ASCII_HTML;
710
711 if (file->type == psiconv_word_file) {
712 gen_word(config,list,(psiconv_word_f) file->file,enc1);
713 return 0;
714 } else if (file->type == psiconv_texted_file) {
715 gen_texted(config,list,(psiconv_texted_f) file->file,enc1);
716 return 0;
717 } else
718 return -1;
719 }
720
721
722 static struct fileformat_s fileformats[] =
723 {
724 {
725 "XHTML",
726 "XHTML 1.0 Strict, using CSS for formatting",
727 FORMAT_WORD | FORMAT_TEXTED,
728 gen_xhtml
729 },
730 {
731 NULL,
732 NULL,
733 0,
734 NULL
735 }
736 };
737
738
739 void init_xhtml(void)
740 {
741 int i;
742 for (i = 0; fileformats[i].name; i++)
743 psiconv_list_add(fileformat_list,fileformats+i);
744 }

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