1 | /* |
|
|
2 | gen_html.c - Part of psiconv, a PSION 5 file formats converter |
1 | /* gen_html.c - Part of psiconv, a PSION 5 file formats converter |
3 | Copyright (c) 1999 Frodo Looijaard <frodol@dds.nl> |
2 | Copyright (c) 1999-2004 Frodo Looijaard <frodol@dds.nl> |
4 | |
3 | |
5 | This program is free software; you can redistribute it and/or modify |
4 | 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 |
5 | 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 |
6 | the Free Software Foundation; either version 2 of the License, or |
8 | (at your option) any later version. |
7 | (at your option) any later version. |
9 | |
8 | |
10 | This program is distributed in the hope that it will be useful, |
9 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. |
12 | GNU General Public License for more details. |
14 | |
13 | |
15 | You should have received a copy of the GNU General Public License |
14 | You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software |
15 | along with this program; if not, write to the Free Software |
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 | */ |
17 | */ |
19 | /* |
|
|
20 | 2002/Apr. Keita KAWABE |
|
|
21 | A: <META HTTP-EQUIV="Content-Type" CONTENT="text/html"> header |
|
|
22 | was added. |
|
|
23 | |
|
|
24 | B: Support for narrow build Asian Psions added. |
|
|
25 | If the encoding_type is PSICONV_ENCODING_UTF8, |
|
|
26 | B-1: use utf8_table for character conversion. |
|
|
27 | B-2: add the "Charset=UTF-8" in the Content-Type header. |
|
|
28 | Otherwise proceed as normal. |
|
|
29 | */ |
|
|
30 | |
18 | |
31 | #include "config.h" |
19 | #include "config.h" |
32 | #include <stdio.h> |
20 | |
|
|
21 | #include <psiconv/configuration.h> |
|
|
22 | #include <psiconv/data.h> |
|
|
23 | #include "general.h" |
|
|
24 | |
33 | #include <string.h> |
25 | #include <string.h> |
34 | #include <stdlib.h> |
26 | #include <stdlib.h> |
35 | #include "psiconv/data.h" |
|
|
36 | #include "psiconv/list.h" |
|
|
37 | #include "gen.h" |
|
|
38 | #include "psiconv.h" |
|
|
39 | |
27 | |
40 | #ifdef DMALLOC |
28 | #ifdef DMALLOC |
41 | #include "dmalloc.h" |
29 | #include "dmalloc.h" |
42 | #endif |
30 | #endif |
43 | |
31 | |
44 | /* This determines for each character how it is displayed */ |
32 | #define TEMPSTR_LEN 100 |
45 | static const char *char_table[0x100] = |
|
|
46 | { |
|
|
47 | /* 0x00 */ "" ,"" ,"" ,"" ,"" ,"" ,"<P> ","<BR>" , |
|
|
48 | /* 0x08 */ "<P>" ," " ,"" ,"" ,"" ,"" ,"" ,"" , |
|
|
49 | /* 0x10 */ " " ,"" ,"" ,"" ,"" ,"" ,"" ,"" , |
|
|
50 | /* 0x18 */ "" ,"" ,"" ,"" ,"" ,"" ,"" ,"" , |
|
|
51 | /* 0x20 */ " " ,"!" ,""","#" ,"$" ,"%" ,"&","'" , |
|
|
52 | /* 0x28 */ "(" ,")" ,"*" ,"+" ,"," ,"-" ,"." ,"/" , |
|
|
53 | /* 0x30 */ "0" ,"1" ,"2" ,"3" ,"4" ,"5" ,"6" ,"7" , |
|
|
54 | /* 0x38 */ "8" ,"9" ,":" ,";" ,"<" ,"=" ,">" ,"?" , |
|
|
55 | /* 0x40 */ "@" ,"A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" , |
|
|
56 | /* 0x48 */ "H" ,"I" ,"J" ,"K" ,"L" ,"M" ,"N" ,"O" , |
|
|
57 | /* 0x50 */ "P" ,"Q" ,"R" ,"S" ,"T" ,"U" ,"V" ,"W" , |
|
|
58 | /* 0x58 */ "X" ,"Y" ,"Z" ,"[" ,"\\" ,"]" ,"^" ,"_" , |
|
|
59 | /* 0x60 */ "`" ,"a" ,"b" ,"c" ,"d" ,"e" ,"f" ,"g" , |
|
|
60 | /* 0x68 */ "h" ,"i" ,"j" ,"k" ,"l" ,"m" ,"n" ,"o" , |
|
|
61 | /* 0x70 */ "p" ,"q" ,"r" ,"s" ,"t" ,"u" ,"v" ,"w" , |
|
|
62 | /* 0x78 */ "x" ,"y" ,"z" ,"{" ,"|" ,"}" ,"~" ,"" , |
|
|
63 | /* 0x80 */ "" ,"","&sbquot;","ƒ","„","…", |
|
|
64 | "†","‡", |
|
|
65 | /* 0x88 */ "^","‰","Š","⟨","Œ","" ,"" ,"" , |
|
|
66 | /* 0x90 */ "","‘","’","“","”", |
|
|
67 | "·","&ndash","&mdash", |
|
|
68 | /* 0x98 */ "˜","™","š","⟩","œ","","","Ÿ", |
|
|
69 | /* 0xa0 */ "","¡","¢","£", |
|
|
70 | "¤","¥","¦","§", |
|
|
71 | /* 0xa8 */ ""","©","a","«","¬","-","®","¯on;", |
|
|
72 | /* 0xb0 */ "°","±","²","³", |
|
|
73 | "&rsquot;","µn;","¶","·", |
|
|
74 | /* 0xb8 */ ",","¹","°","»", |
|
|
75 | "¼","½","¾","¿", |
|
|
76 | /* 0xc0 */ "À","Á","Â","Ã", |
|
|
77 | "Ä","Å","Æ","Ç", |
|
|
78 | /* 0xc8 */ "È","É","Ê","Ë", |
|
|
79 | "Ì","Í","Î","Ï", |
|
|
80 | /* 0xd0 */ "Ð","Ñ","Ò","Ó", |
|
|
81 | "Ô","Õ","Ö","×", |
|
|
82 | /* 0xd8 */ "Ø","Ù","Ú","Û", |
|
|
83 | "Ü","Ý","Þ","ß", |
|
|
84 | /* 0xe0 */ "à","á","â","ã", |
|
|
85 | "ä","å","æ","ç", |
|
|
86 | /* 0xe8 */ "è","é","ê","ë", |
|
|
87 | "ì","í","î","ï", |
|
|
88 | /* 0xf0 */ "ð","ñ","ò","ó", |
|
|
89 | "ô","õ","ö","÷", |
|
|
90 | /* 0xf8 */ "ø","ù","ú","û", |
|
|
91 | "ü","ý","þ","ÿ" |
|
|
92 | }; |
|
|
93 | |
33 | |
94 | static const char *utf_table[0x100] = |
34 | typedef enum output_type_e { output_html, output_xhtml } output_type; |
95 | { |
|
|
96 | /* 0x00 */ "" ,"" ,"" ,"" ,"" ,"" ,"<P> ","<BR>" , |
|
|
97 | /* 0x08 */ "<P>" ," " ,"" ,"" ,"" ,"" ,"" ,"" , |
|
|
98 | /* 0x10 */ " " ,"" ,"" ,"" ,"" ,"" ,"" ,"" , |
|
|
99 | /* 0x18 */ "" ,"" ,"" ,"" ,"" ,"" ,"" ,"" , |
|
|
100 | /* 0x20 */ " " ,"!" ,""","#" ,"$" ,"%" ,"&","'" , |
|
|
101 | /* 0x28 */ "(" ,")" ,"*" ,"+" ,"," ,"-" ,"." ,"/" , |
|
|
102 | /* 0x30 */ "0" ,"1" ,"2" ,"3" ,"4" ,"5" ,"6" ,"7" , |
|
|
103 | /* 0x38 */ "8" ,"9" ,":" ,";" ,"<" ,"=" ,">" ,"?" , |
|
|
104 | /* 0x40 */ "@" ,"A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" , |
|
|
105 | /* 0x48 */ "H" ,"I" ,"J" ,"K" ,"L" ,"M" ,"N" ,"O" , |
|
|
106 | /* 0x50 */ "P" ,"Q" ,"R" ,"S" ,"T" ,"U" ,"V" ,"W" , |
|
|
107 | /* 0x58 */ "X" ,"Y" ,"Z" ,"[" ,"\\" ,"]" ,"^" ,"_" , |
|
|
108 | /* 0x60 */ "`" ,"a" ,"b" ,"c" ,"d" ,"e" ,"f" ,"g" , |
|
|
109 | /* 0x68 */ "h" ,"i" ,"j" ,"k" ,"l" ,"m" ,"n" ,"o" , |
|
|
110 | /* 0x70 */ "p" ,"q" ,"r" ,"s" ,"t" ,"u" ,"v" ,"w" , |
|
|
111 | /* 0x78 */ "x" ,"y" ,"z" ,"{" ,"|" ,"}" ,"~" ,"" , |
|
|
112 | /* 0x80 */ "\x80", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87", |
|
|
113 | /* 0x88 */ "\x88", "\x89", "\x8a", "\x8b", "\x8c", "\x8d", "\x8e", "\x8f", |
|
|
114 | /* 0x90 */ "\x90", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97", |
|
|
115 | /* 0x98 */ "\x98", "\x99", "\x9a", "\x9b", "\x9c", "\x9d", "\x9e", "\x9f", |
|
|
116 | /* 0xa0 */ "\xa0", "\xa1", "\xa2", "\xa3", "\xa4", "\xa5", "\xa6", "\xa7", |
|
|
117 | /* 0xa8 */ "\xa8", "\xa9", "\xaa", "\xab", "\xac", "\xad", "\xae", "\xaf", |
|
|
118 | /* 0xb0 */ "\xb0", "\xb1", "\xb2", "\xb3", "\xb4", "\xb5", "\xb6", "\xb7", |
|
|
119 | /* 0xb8 */ "\xb8", "\xb9", "\xba", "\xbb", "\xbc", "\xbd", "\xbe", "\xbf", |
|
|
120 | /* 0xc0 */ "\xc0", "\xc1", "\xc2", "\xc3", "\xc4", "\xc5", "\xc6", "\xc7", |
|
|
121 | /* 0xc8 */ "\xc8", "\xc9", "\xca", "\xcb", "\xcc", "\xcd", "\xce", "\xcf", |
|
|
122 | /* 0xd0 */ "\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5", "\xd6", "\xd7", |
|
|
123 | /* 0xd8 */ "\xd8", "\xd9", "\xda", "\xdb", "\xdc", "\xdd", "\xde", "\xdf", |
|
|
124 | /* 0xe0 */ "\xe0", "\xe1", "\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7", |
|
|
125 | /* 0xe8 */ "\xe8", "\xe9", "\xea", "\xeb", "\xec", "\xed", "\xee", "\xef", |
|
|
126 | /* 0xf0 */ "\xf0", "\xf1", "\xf2", "\xf3", "\xf4", "\xf5", "\xf6", "\xf7", |
|
|
127 | /* 0xf8 */ "\xf8", "\xf9", "\xfa", "\xfb", "\xfc", "\xfd", "\xfe", "\xff", |
|
|
128 | }; |
|
|
129 | |
35 | |
130 | /* a flag to indicate the use of UTF8 */ |
36 | void character_layout_diffs(const psiconv_config config, psiconv_list list, |
131 | static psiconv_encoding encoding= PSICONV_ENCODING_CP1252; |
|
|
132 | |
|
|
133 | static psiconv_character_layout gen_base_char(const psiconv_font font, |
|
|
134 | const psiconv_color color, |
|
|
135 | const psiconv_color back_color); |
|
|
136 | static void diff_char(FILE *of, const psiconv_character_layout old, |
|
|
137 | const psiconv_character_layout new, int *flags); |
|
|
138 | static void gen_para(FILE *of, const psiconv_paragraph para, |
|
|
139 | const psiconv_character_layout base_char); |
|
|
140 | |
|
|
141 | static void psiconv_gen_html_word(FILE *of,psiconv_word_f wf); |
|
|
142 | static void psiconv_gen_html_texted(FILE *of,psiconv_texted_f tf); |
|
|
143 | |
|
|
144 | /* This is not necessarily the same as returned by basic_character_layout_status |
|
|
145 | This one is specific for the base point of HTML */ |
|
|
146 | psiconv_character_layout gen_base_char(const psiconv_font font, |
|
|
147 | const psiconv_color color, |
|
|
148 | const psiconv_color back_color) |
|
|
149 | { |
|
|
150 | struct psiconv_character_layout_s base_char_struct = |
|
|
151 | { |
|
|
152 | NULL, /* color */ |
|
|
153 | NULL, /* back_color */ |
|
|
154 | 13.0, /* font_size */ |
|
|
155 | psiconv_bool_false, /* italic */ |
|
|
156 | psiconv_bool_false, /* bold */ |
|
|
157 | psiconv_normalscript, /* super_sub */ |
|
|
158 | psiconv_bool_false, /* underline */ |
|
|
159 | psiconv_bool_false, /* strikethrough */ |
|
|
160 | NULL, /* font */ |
|
|
161 | }; |
|
|
162 | base_char_struct.color = color; |
|
|
163 | base_char_struct.back_color = back_color; |
|
|
164 | base_char_struct.font = font; |
|
|
165 | return psiconv_clone_character_layout(&base_char_struct); |
|
|
166 | } |
|
|
167 | |
|
|
168 | /* flags & 1: 0 if no <FONT> was yet generated. |
|
|
169 | flags & 2: 1 if at end-of-paragraph |
|
|
170 | */ |
|
|
171 | void diff_char(FILE *of, const psiconv_character_layout old, |
|
|
172 | const psiconv_character_layout new, |
37 | const psiconv_character_layout new, |
173 | int *flags) |
38 | const psiconv_character_layout base, |
|
|
39 | const encoding enc) |
174 | { |
40 | { |
175 | int font_set = 0; |
41 | if (new->italic != base->italic) { |
|
|
42 | output_simple_chars(config,list,"font-style:",enc); |
|
|
43 | output_simple_chars(config,list,new->italic?"italic":"normal",enc); |
|
|
44 | output_simple_chars(config,list,";",enc); |
|
|
45 | } |
|
|
46 | if ((new->underline != base->underline) || |
|
|
47 | (new->strikethrough != base->strikethrough)) { |
|
|
48 | output_simple_chars(config,list,"text-decoration:",enc); |
|
|
49 | output_simple_chars(config,list,new->underline?"underline": |
|
|
50 | new->strikethrough?"line-through": |
|
|
51 | "none",enc); |
|
|
52 | output_simple_chars(config,list,";",enc); |
|
|
53 | } |
|
|
54 | if (new->bold != base->bold) { |
|
|
55 | output_simple_chars(config,list,"font-weight:",enc); |
|
|
56 | output_simple_chars(config,list,new->bold?"bold":"normal",enc); |
|
|
57 | output_simple_chars(config,list,";",enc); |
|
|
58 | } |
|
|
59 | if (new->super_sub != base->super_sub) { |
|
|
60 | output_simple_chars(config,list,"font-style:",enc); |
|
|
61 | output_simple_chars(config,list, |
|
|
62 | new->super_sub==psiconv_superscript?"super": |
|
|
63 | new->super_sub==psiconv_subscript?"sub": |
|
|
64 | "normal",enc); |
|
|
65 | output_simple_chars(config,list,";",enc); |
|
|
66 | } |
|
|
67 | } |
176 | |
68 | |
177 | if ((old->font_size != new->font_size) || |
69 | void paragraph_layout_diffs(const psiconv_config config, psiconv_list list, |
178 | (old->color->red != new->color->red) || |
70 | const psiconv_paragraph_layout new, |
179 | (old->color->green != new->color->green) || |
71 | const psiconv_paragraph_layout base) |
180 | (old->color->blue != new->color->blue) || |
72 | { |
181 | (strcmp(old->font->name,new->font->name)) || |
73 | } |
182 | (old->font->screenfont != new->font->screenfont) || |
74 | |
183 | ((*flags & 0x03) == 3)) { |
75 | void header(const psiconv_config config, psiconv_list list, |
|
|
76 | output_type type, const encoding enc) |
|
|
77 | { |
|
|
78 | if (type == output_xhtml) |
|
|
79 | output_simple_chars(config,list, |
|
|
80 | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",enc); |
|
|
81 | output_simple_chars(config,list,"<!DOCTYPE html PUBLIC ",enc); |
|
|
82 | output_simple_chars(config,list,type == output_xhtml? |
|
|
83 | "\"-//W3C//DTD XHTML 1.0 Strict//EN\" ": |
|
|
84 | "\"-//W3C//DTD HTML 4.01//EN\" ",enc); |
|
|
85 | output_simple_chars(config,list,type == output_xhtml? |
|
|
86 | "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">": |
|
|
87 | "\"http://www.w3.org/TR/html4/strict.dtd\">",enc); |
|
|
88 | output_simple_chars(config,list,"\n<html",enc); |
|
|
89 | if (type == output_xhtml) |
|
|
90 | output_simple_chars(config,list, |
|
|
91 | " xmlns=\"http://www.w3.org/1999/xhtml\"",enc); |
|
|
92 | output_simple_chars(config,list,">\n",enc); |
|
|
93 | output_simple_chars(config,list,"<head>\n",enc); |
|
|
94 | output_simple_chars(config,list,"<meta http-equiv=\"Content-Type\" " |
|
|
95 | "content=\"text/html; charset=",enc); |
|
|
96 | output_simple_chars(config,list,enc==ENCODING_UTF8?"UTF-8": |
|
|
97 | enc==ENCODING_UCS2?"UTF-16BE": |
|
|
98 | enc==ENCODING_ASCII?"US-ASCII": |
|
|
99 | "",enc); |
|
|
100 | output_simple_chars(config,list,"\">\n",enc); |
|
|
101 | output_simple_chars(config,list,"<meta http-equiv=\"Content-Style-Type\" " |
|
|
102 | "content=\"text/css\">\n",enc); |
|
|
103 | output_simple_chars(config,list,"<title>EPOC32 file " |
|
|
104 | "converted by psiconv</title>\n",enc); |
|
|
105 | output_simple_chars(config,list,"</head>\n",enc); |
|
|
106 | output_simple_chars(config,list,"<body>\n",enc); |
|
|
107 | } |
|
|
108 | |
|
|
109 | void footer(const psiconv_config config, psiconv_list list, |
|
|
110 | output_type type, const encoding enc) |
|
|
111 | { |
|
|
112 | output_simple_chars(config,list,"</body>\n",enc); |
|
|
113 | output_simple_chars(config,list,"</html>\n",enc); |
|
|
114 | } |
|
|
115 | |
|
|
116 | void color(const psiconv_config config, psiconv_list list, |
|
|
117 | psiconv_color color, output_type type, const encoding enc) |
|
|
118 | { |
|
|
119 | char tempstr[TEMPSTR_LEN]; |
|
|
120 | if ((color->red == 0xff) && |
|
|
121 | (color->blue == 0xff) && |
|
|
122 | (color->green == 0xff)) |
|
|
123 | output_simple_chars(config,list,"transparant",enc); |
|
|
124 | else { |
|
|
125 | snprintf(tempstr,TEMPSTR_LEN,"rgb(%d,%d,%d)", |
|
|
126 | color->red, |
|
|
127 | color->green, |
|
|
128 | color->blue); |
|
|
129 | output_simple_chars(config,list,tempstr,enc); |
|
|
130 | } |
|
|
131 | } |
|
|
132 | |
|
|
133 | void charlayout(const psiconv_config config, psiconv_list list, |
|
|
134 | psiconv_string_t text,psiconv_character_layout layout, |
|
|
135 | output_type type, const encoding enc) |
|
|
136 | { |
|
|
137 | char tempstr[TEMPSTR_LEN]; |
184 | if (old->italic) |
138 | if (layout->italic) |
185 | fputs("</I>",of); |
139 | output_simple_chars(config,list,"<i>",enc); |
186 | if (old->bold) |
140 | if (layout->bold) |
187 | fputs("</B>",of); |
141 | output_simple_chars(config,list,"<b>",enc); |
188 | if (old->underline) |
|
|
189 | fputs("</U>",of); |
|
|
190 | if (old->strikethrough) |
|
|
191 | fputs("</STRIKE>",of); |
|
|
192 | if (old->super_sub == psiconv_superscript) |
142 | if (layout->super_sub != psiconv_normalscript) |
193 | fputs("</SUP>",of); |
143 | output_simple_chars(config,list, |
|
|
144 | layout->super_sub == psiconv_superscript?"<sup>": |
|
|
145 | layout->super_sub == psiconv_subscript?"<sub>": |
|
|
146 | "",enc); |
|
|
147 | |
|
|
148 | output_simple_chars(config,list,"<span style=\"",enc); |
|
|
149 | |
|
|
150 | if (layout->underline || layout->strikethrough) { |
|
|
151 | output_simple_chars(config,list,"text-decoration:",enc); |
|
|
152 | output_simple_chars(config,list,layout->underline?"underline": |
|
|
153 | layout->strikethrough?"line-through": |
|
|
154 | "",enc); |
|
|
155 | output_simple_chars(config,list,";",enc); |
|
|
156 | } |
|
|
157 | |
|
|
158 | output_simple_chars(config,list,"color:",enc); |
|
|
159 | color(config,list,layout->color,type,enc); |
|
|
160 | output_simple_chars(config,list,";",enc); |
|
|
161 | |
|
|
162 | output_simple_chars(config,list,"background-color:",enc); |
|
|
163 | color(config,list,layout->back_color,type,enc); |
|
|
164 | output_simple_chars(config,list,";",enc); |
|
|
165 | |
|
|
166 | output_simple_chars(config,list,"font-size:",enc); |
|
|
167 | snprintf(tempstr,TEMPSTR_LEN,"%f",layout->font_size); |
|
|
168 | output_simple_chars(config,list,tempstr,enc); |
|
|
169 | output_simple_chars(config,list,"pt;",enc); |
|
|
170 | |
|
|
171 | output_simple_chars(config,list,"\">",enc); |
|
|
172 | |
|
|
173 | output_string(config,list,text,enc); |
|
|
174 | |
|
|
175 | output_simple_chars(config,list,"</span>",enc); |
194 | if (old->super_sub == psiconv_subscript) |
176 | if (layout->super_sub != psiconv_normalscript) |
195 | fputs("</SUB>",of); |
177 | output_simple_chars(config,list, |
196 | if ((*flags & 1) == 1) |
178 | layout->super_sub == psiconv_superscript?"</sup>": |
197 | fputs("</FONT>",of); |
179 | layout->super_sub == psiconv_subscript?"</sub>": |
198 | if ((*flags & 2) == 0) { |
180 | "",enc); |
199 | *flags |= 1; |
181 | if (layout->bold) |
200 | fputs("<FONT SIZE=",of); |
182 | output_simple_chars(config,list,"</b>",enc); |
201 | if (new->font_size <= 8.0) |
183 | if (layout->italic) |
202 | fputs("1",of); |
184 | output_simple_chars(config,list,"</i>",enc); |
203 | else if (new->font_size <= 10.0) |
185 | } |
204 | fputs("2",of); |
186 | |
205 | else if (new->font_size <= 12.0) |
187 | void paragraph(const psiconv_config config, psiconv_list list, |
206 | fputs("3",of); |
188 | psiconv_paragraph para,output_type type, |
207 | else if (new->font_size <= 14.0) |
189 | const encoding enc) |
208 | fputs("4",of); |
190 | { |
209 | else if (new->font_size <= 18.0) |
191 | char tempstr[TEMPSTR_LEN]; |
210 | fputs("5",of); |
192 | int i,charnr; |
211 | else if (new->font_size <= 24.0) |
193 | psiconv_string_t text; |
212 | fputs("6",of); |
194 | psiconv_in_line_layout layout; |
|
|
195 | |
|
|
196 | output_simple_chars(config,list,"<p style=\"",enc); |
|
|
197 | |
|
|
198 | output_simple_chars(config,list,"background-color:",enc); |
|
|
199 | color(config,list,para->base_paragraph->back_color,type,enc); |
|
|
200 | output_simple_chars(config,list,";",enc); |
|
|
201 | |
|
|
202 | output_simple_chars(config,list,"padding-left:",enc); |
|
|
203 | snprintf(tempstr,TEMPSTR_LEN,"%f",para->base_paragraph->indent_left); |
|
|
204 | output_simple_chars(config,list,tempstr,enc); |
|
|
205 | output_simple_chars(config,list,"cm;",enc); |
|
|
206 | |
|
|
207 | output_simple_chars(config,list,"padding-right:",enc); |
|
|
208 | snprintf(tempstr,TEMPSTR_LEN,"%f",para->base_paragraph->indent_right); |
|
|
209 | output_simple_chars(config,list,tempstr,enc); |
|
|
210 | output_simple_chars(config,list,"cm;",enc); |
|
|
211 | |
|
|
212 | output_simple_chars(config,list,"text-indent:",enc); |
|
|
213 | snprintf(tempstr,TEMPSTR_LEN,"%f",para->base_paragraph->indent_left - para->base_paragraph->indent_first); |
|
|
214 | output_simple_chars(config,list,tempstr,enc); |
|
|
215 | output_simple_chars(config,list,"cm;",enc); |
|
|
216 | |
|
|
217 | output_simple_chars(config,list,"text-align:",enc); |
|
|
218 | output_simple_chars(config,list,para->base_paragraph->justify_hor==psiconv_justify_left?"left": |
|
|
219 | para->base_paragraph->justify_hor==psiconv_justify_centre?"center": |
|
|
220 | para->base_paragraph->justify_hor==psiconv_justify_right?"right": |
|
|
221 | para->base_paragraph->justify_hor==psiconv_justify_full?"justify": |
|
|
222 | "",enc); |
|
|
223 | output_simple_chars(config,list,";",enc); |
|
|
224 | |
|
|
225 | |
|
|
226 | output_simple_chars(config,list,"line-height:",enc); |
|
|
227 | snprintf(tempstr,TEMPSTR_LEN,"%f",para->base_paragraph->linespacing); |
|
|
228 | output_simple_chars(config,list,tempstr,enc); |
|
|
229 | output_simple_chars(config,list,"pt;",enc); |
|
|
230 | |
|
|
231 | output_simple_chars(config,list,"padding-top:",enc); |
|
|
232 | snprintf(tempstr,TEMPSTR_LEN,"%f",para->base_paragraph->space_above); |
|
|
233 | output_simple_chars(config,list,tempstr,enc); |
|
|
234 | output_simple_chars(config,list,"pt;",enc); |
|
|
235 | |
|
|
236 | output_simple_chars(config,list,"padding-bottom:",enc); |
|
|
237 | snprintf(tempstr,TEMPSTR_LEN,"%f",para->base_paragraph->space_below); |
|
|
238 | output_simple_chars(config,list,tempstr,enc); |
|
|
239 | output_simple_chars(config,list,"pt;",enc); |
|
|
240 | |
|
|
241 | output_simple_chars(config,list,"\">",enc); |
|
|
242 | |
|
|
243 | if (psiconv_list_length(para->in_lines) == 0) { |
|
|
244 | charlayout(config,list,para->text,para->base_character,type,enc); |
213 | else |
245 | } else { |
214 | fputs("7",of); |
246 | charnr = 0; |
215 | fprintf(of," COLOR=#%02x%02x%02x",new->color->red,new->color->green, |
247 | for (i = 0; i < psiconv_list_length(para->in_lines); i++) { |
216 | new->color->blue); |
248 | if (!(layout = psiconv_list_get(para->in_lines,i))) { |
217 | if (new->font->screenfont == psiconv_font_sansserif) |
249 | fputs("Internal data structures corruption\n",stderr); |
218 | fprintf(of," FACE=\"%s, Sans-Serif\">",new->font->name); |
250 | exit(1); |
219 | else if (new->font->screenfont == psiconv_font_nonprop) |
251 | } |
220 | fprintf(of," FACE=\"%s, Monospace\">",new->font-> name); |
252 | if (!(text = malloc(sizeof (*text) * (layout->length + 1)))) { |
221 | else if (new->font->screenfont == psiconv_font_serif) |
253 | fputs("Out of memory error\n",stderr); |
222 | fprintf(of," FACE=\"%s, Serif\">",new->font-> name); |
254 | exit(1); |
223 | else |
255 | } |
224 | fprintf(of," FACE=\"%s, Serif\">",new->font-> name); |
256 | memcpy(text,para->text+charnr,layout->length * sizeof(*text)); |
|
|
257 | text[layout->length] = 0; |
|
|
258 | charlayout(config,list,text,layout->layout,type,enc); |
|
|
259 | free(text); |
|
|
260 | charnr += layout->length; |
225 | } |
261 | } |
226 | if (new->italic) |
|
|
227 | fputs("<I>",of); |
|
|
228 | if (new->bold) |
|
|
229 | fputs("<B>",of); |
|
|
230 | if (new->underline) |
|
|
231 | fputs("<U>",of); |
|
|
232 | if (new->strikethrough) |
|
|
233 | fputs("<STRIKE>",of); |
|
|
234 | if (new->super_sub == psiconv_superscript) |
|
|
235 | fputs("<SUP>",of); |
|
|
236 | if (new->super_sub == psiconv_subscript) |
|
|
237 | fputs("<SUB>",of); |
|
|
238 | } else { |
|
|
239 | if (font_set || (old->italic != new->italic)) { |
|
|
240 | if (old->italic) |
|
|
241 | fputs("</I>",of); |
|
|
242 | else |
|
|
243 | fputs("<I>",of); |
|
|
244 | } |
262 | } |
245 | if (old->bold != new->bold) { |
263 | output_simple_chars(config,list,"</p>\n",enc); |
246 | if (old->bold) |
|
|
247 | fputs("</B>",of); |
|
|
248 | else |
|
|
249 | fputs("<B>",of); |
|
|
250 | } |
|
|
251 | if (old->underline != new->underline) { |
|
|
252 | if (old->underline) |
|
|
253 | fputs("</U>",of); |
|
|
254 | else |
|
|
255 | fputs("<U>",of); |
|
|
256 | } |
|
|
257 | if (old->strikethrough != new->strikethrough) { |
|
|
258 | if (old->strikethrough) |
|
|
259 | fputs("</STRIKE>",of); |
|
|
260 | else |
|
|
261 | fputs("<STRIKE>",of); |
|
|
262 | } |
|
|
263 | if (old->super_sub != new->super_sub) { |
|
|
264 | if (old->super_sub == psiconv_superscript) |
|
|
265 | fputs("</SUP>",of); |
|
|
266 | else if (old->super_sub == psiconv_subscript) |
|
|
267 | fputs("</SUB>",of); |
|
|
268 | if (new->super_sub == psiconv_superscript) |
|
|
269 | fputs("<SUP>",of); |
|
|
270 | else if (new->super_sub == psiconv_subscript) |
|
|
271 | fputs("<SUB>",of); |
|
|
272 | } |
|
|
273 | } |
|
|
274 | } |
264 | } |
275 | |
265 | |
276 | void gen_para(FILE *of, const psiconv_paragraph para, |
266 | void paragraphs(const psiconv_config config, psiconv_list list, |
277 | const psiconv_character_layout base_char) |
267 | psiconv_text_and_layout paragraphs,output_type type, |
278 | { |
268 | const encoding enc) |
279 | int i,j,loc; |
|
|
280 | psiconv_character_layout cur_char; |
|
|
281 | psiconv_in_line_layout inl; |
|
|
282 | int flags = 0; |
|
|
283 | |
|
|
284 | char **table; |
|
|
285 | if (encoding == PSICONV_ENCODING_UTF8){ |
|
|
286 | table=(char**)utf_table; |
|
|
287 | }else{ |
|
|
288 | table=(char**)char_table; |
|
|
289 | } |
|
|
290 | |
|
|
291 | |
|
|
292 | |
|
|
293 | fputs("<P",of); |
|
|
294 | if (para->base_paragraph->justify_hor == psiconv_justify_left) |
|
|
295 | fputs(" ALIGN=left",of); |
|
|
296 | else if (para->base_paragraph->justify_hor == psiconv_justify_right) |
|
|
297 | fputs(" ALIGN=right",of); |
|
|
298 | else if (para->base_paragraph->justify_hor == psiconv_justify_centre) |
|
|
299 | fputs(" ALIGN=center",of); |
|
|
300 | else if (para->base_paragraph->justify_hor == psiconv_justify_full) |
|
|
301 | fputs(" ALIGN=left",of); |
|
|
302 | fputs(">",of); |
|
|
303 | if (para->base_paragraph->bullet->on) |
|
|
304 | fputs("<UL><LI>",of); |
|
|
305 | |
|
|
306 | cur_char = base_char; |
|
|
307 | |
|
|
308 | if (psiconv_list_length(para->in_lines) == 0) { |
|
|
309 | diff_char(of,cur_char,para->base_character,&flags); |
|
|
310 | cur_char = para->base_character; |
|
|
311 | } |
|
|
312 | loc = 0; |
|
|
313 | |
|
|
314 | for (i = 0; i < psiconv_list_length(para->in_lines); i++) { |
|
|
315 | inl = psiconv_list_get(para->in_lines,i); |
|
|
316 | diff_char(of,cur_char,inl->layout,&flags); |
|
|
317 | cur_char = inl->layout; |
|
|
318 | for (j = loc; j < inl->length + loc; j ++) { |
|
|
319 | fputs(table[(unsigned char) (para->text[j])],of); |
|
|
320 | } |
|
|
321 | loc = j; |
|
|
322 | } |
|
|
323 | |
|
|
324 | if (loc < strlen(para->text)) { |
|
|
325 | diff_char(of,cur_char,para->base_character,&flags); |
|
|
326 | cur_char = para->base_character; |
|
|
327 | for (j = loc; j < strlen(para->text); j ++) { |
|
|
328 | fputs(table[(unsigned char) (para->text[j])],of); |
|
|
329 | } |
|
|
330 | } |
|
|
331 | |
|
|
332 | if (strlen(para->text) == 0) |
|
|
333 | fputs("<BR>",of); |
|
|
334 | |
|
|
335 | flags |= 2; |
|
|
336 | diff_char(of,cur_char,base_char,&flags); |
|
|
337 | |
|
|
338 | if (para->base_paragraph->bullet->on) |
|
|
339 | fputs("</UL>",of); |
|
|
340 | |
|
|
341 | fputs("</P>\n",of); |
|
|
342 | } |
|
|
343 | |
|
|
344 | int psiconv_gen_html(const char * filename,const psiconv_file file, |
|
|
345 | const char *dest, const psiconv_encoding encoding_type) |
|
|
346 | { |
|
|
347 | FILE *of = fopen(filename,"w"); |
|
|
348 | if (! of) |
|
|
349 | return -1; |
|
|
350 | |
|
|
351 | encoding = encoding_type; |
|
|
352 | |
|
|
353 | if (file->type == psiconv_word_file) { |
|
|
354 | psiconv_gen_html_word(of,(psiconv_word_f) file->file); |
|
|
355 | } else if (file->type == psiconv_texted_file) { |
|
|
356 | psiconv_gen_html_texted(of,(psiconv_texted_f) file->file); |
|
|
357 | } else { |
|
|
358 | fclose(of); |
|
|
359 | return -1; |
|
|
360 | } |
|
|
361 | return fclose(of); |
|
|
362 | } |
|
|
363 | |
|
|
364 | void psiconv_gen_html_texted(FILE *of,psiconv_texted_f tf) |
|
|
365 | { |
|
|
366 | psiconv_character_layout base_char; |
|
|
367 | psiconv_paragraph para; |
|
|
368 | int i; |
|
|
369 | |
|
|
370 | /* We have nothing better */ |
|
|
371 | base_char = psiconv_basic_character_layout(); |
|
|
372 | |
|
|
373 | fputs("<!doctype html public \"-//W3C//DTD HTML 3.2 Final//EN\">", of); |
|
|
374 | fputs("\n<HTML>\n<HEAD>\n <META NAME=\"GENERATOR\"", of); |
|
|
375 | fputs(" CONTENT=\"psiconv-" VERSION "\">\n", of); |
|
|
376 | |
|
|
377 | fputs(" <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html", of); |
|
|
378 | if (encoding == PSICONV_ENCODING_UTF8){ |
|
|
379 | fputs("; CHARSET=UTF-8", of); |
|
|
380 | } |
|
|
381 | fputs("\">\n", of); |
|
|
382 | |
|
|
383 | fputs("</HEAD>\n",of); |
|
|
384 | fputs("<BODY>\n",of); |
|
|
385 | for (i = 0; i < psiconv_list_length(tf->texted_sec->paragraphs); i++) { |
|
|
386 | para = psiconv_list_get(tf->texted_sec->paragraphs,i); |
|
|
387 | gen_para(of,para,base_char); |
|
|
388 | } |
|
|
389 | fputs("</BODY>\n</HTML>\n",of); |
|
|
390 | psiconv_free_character_layout(base_char); |
|
|
391 | } |
|
|
392 | |
|
|
393 | |
|
|
394 | void psiconv_gen_html_word(FILE *of,psiconv_word_f wf) |
|
|
395 | { |
269 | { |
396 | int i; |
270 | int i; |
397 | psiconv_paragraph para; |
271 | psiconv_paragraph para; |
398 | psiconv_color white,black; |
|
|
399 | psiconv_character_layout base_char; |
|
|
400 | |
|
|
401 | white = malloc(sizeof(*white)); |
|
|
402 | black = malloc(sizeof(*black)); |
|
|
403 | white->red = 0x00; |
|
|
404 | white->green = 0x00; |
|
|
405 | white->blue = 0x00; |
|
|
406 | black->red = 0xff; |
|
|
407 | black->green = 0xff; |
|
|
408 | black->blue = 0xff; |
|
|
409 | |
|
|
410 | /* To keep from generating a font desc for each line */ |
|
|
411 | base_char = gen_base_char(wf->styles_sec->normal->character->font, |
|
|
412 | black,white); |
|
|
413 | |
|
|
414 | psiconv_free_color(black); |
|
|
415 | psiconv_free_color(white); |
|
|
416 | |
|
|
417 | fputs("<!doctype html public \"-//W3C//DTD HTML 3.2 Final//EN\">", of); |
|
|
418 | fputs("\n<HTML>\n<HEAD>\n <META NAME=\"GENERATOR\"", of); |
|
|
419 | fputs(" CONTENT=\"psiconv-" VERSION "\">\n", of); |
|
|
420 | |
|
|
421 | fputs(" <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html", of); |
|
|
422 | if (encoding == PSICONV_ENCODING_UTF8) |
|
|
423 | fputs("; CHARSET=UTF-8", of); |
|
|
424 | fputs("\">\n", of); |
|
|
425 | |
|
|
426 | fputs("</HEAD>\n",of); |
|
|
427 | fputs("<BODY>\n",of); |
|
|
428 | |
|
|
429 | for (i = 0; i < psiconv_list_length(wf->paragraphs); i++) { |
272 | for (i = 0; i < psiconv_list_length(paragraphs); i++) { |
430 | para = psiconv_list_get(wf->paragraphs,i); |
273 | if (!(para = psiconv_list_get(paragraphs,i))) { |
431 | gen_para(of,para,base_char); |
274 | fputs("Internal datastructure corruption\n",stderr); |
|
|
275 | exit(1); |
432 | } |
276 | } |
433 | fputs("</BODY>\n</HTML>\n",of); |
277 | paragraph(config,list,para,type,enc); |
434 | psiconv_free_character_layout(base_char); |
278 | } |
435 | } |
279 | } |
436 | |
280 | |
|
|
281 | void gen_html_word(const psiconv_config config, psiconv_list list, |
|
|
282 | const psiconv_word_f file, output_type type, |
|
|
283 | const encoding enc) |
|
|
284 | { |
|
|
285 | if (!file) |
|
|
286 | return; |
|
|
287 | |
|
|
288 | header(config,list,type,enc); |
|
|
289 | paragraphs(config,list,file->paragraphs,type,enc); |
|
|
290 | footer(config,list,type,enc); |
|
|
291 | } |
|
|
292 | |
|
|
293 | |
|
|
294 | void gen_html_texted(const psiconv_config config, psiconv_list list, |
|
|
295 | const psiconv_texted_f file, output_type type, |
|
|
296 | const encoding enc) |
|
|
297 | { |
|
|
298 | header(config,list,type,enc); |
|
|
299 | paragraphs(config,list,file->texted_sec->paragraphs,type,enc); |
|
|
300 | footer(config,list,type,enc); |
|
|
301 | } |
|
|
302 | |
|
|
303 | int gen_html(const psiconv_config config, psiconv_list list, |
|
|
304 | const psiconv_file file, const char *dest, |
|
|
305 | const encoding enc) |
|
|
306 | { |
|
|
307 | output_type type; |
|
|
308 | |
|
|
309 | if (!strcmp("HTML4",dest)) |
|
|
310 | type = output_html; |
|
|
311 | else if (!strcmp("XHTML",dest)) |
|
|
312 | type = output_xhtml; |
|
|
313 | else |
|
|
314 | return -1; |
|
|
315 | |
|
|
316 | if (enc == ENCODING_PSION) { |
|
|
317 | fputs("Unsupported encoding\n",stderr); |
|
|
318 | return -1; |
|
|
319 | } |
|
|
320 | |
|
|
321 | if (file->type == psiconv_word_file) { |
|
|
322 | gen_html_word(config,list,(psiconv_word_f) file->file,type,enc); |
|
|
323 | return 0; |
|
|
324 | } else if (file->type == psiconv_texted_file) { |
|
|
325 | gen_html_texted(config,list,(psiconv_texted_f) file->file,type, enc); |
|
|
326 | return 0; |
|
|
327 | } else |
|
|
328 | return -1; |
|
|
329 | } |
|
|
330 | |
|
|
331 | |
437 | static struct psiconv_fileformat_s ff = |
332 | static struct fileformat_s ffs[] = |
438 | { |
333 | { |
|
|
334 | { |
439 | "HTML3", |
335 | "XHTML", |
440 | "HTML 3.2, not verified so probably not completely compliant", |
336 | "XHTML 1.0 Strict, using CSS for formatting", |
441 | &psiconv_gen_html |
337 | gen_html |
|
|
338 | }, |
|
|
339 | { |
|
|
340 | "HTML4", |
|
|
341 | "HTML 4.01 Strict, using CSS for formatting", |
|
|
342 | gen_html |
|
|
343 | }, |
|
|
344 | { |
|
|
345 | NULL, |
|
|
346 | NULL, |
|
|
347 | NULL |
|
|
348 | } |
442 | }; |
349 | }; |
443 | |
350 | |
|
|
351 | |
444 | void init_html(void) |
352 | void init_html(void) |
445 | { |
353 | { |
|
|
354 | int i; |
|
|
355 | for (i = 0; ffs[i].name; i++) |
446 | psiconv_list_add(fileformat_list,&ff); |
356 | psiconv_list_add(fileformat_list,ffs+i); |
447 | } |
357 | } |