#ifdef DMALLOC
#include "dmalloc.h"
@@ -31,6 +33,60 @@
#define TEMPSTR_LEN 100
+static void text(const psiconv_config config,psiconv_list list,
+ psiconv_string_t data,const encoding enc);
+static void color(const psiconv_config config, psiconv_list list,
+ psiconv_color color,int may_be_transparant, const encoding enc);
+static void border(const psiconv_config config, psiconv_list list,
+ psiconv_border_kind_t border,const encoding enc);
+static void style_name(const psiconv_config config, psiconv_list list,
+ const psiconv_string_t name,const encoding enc);
+static int character_layout_equal(const psiconv_character_layout l1,
+ const psiconv_character_layout l2);
+static void character_layout_diffs(const psiconv_config config,
+ psiconv_list list,
+ const psiconv_character_layout new,
+ const psiconv_character_layout base,
+ const encoding enc);
+static void paragraph_layout_diffs(const psiconv_config config,
+ psiconv_list list,
+ const psiconv_paragraph_layout new,
+ const psiconv_paragraph_layout base,
+ const encoding enc);
+static void style(const psiconv_config config, psiconv_list list,
+ const psiconv_word_style style,
+ const psiconv_paragraph_layout base_para,
+ const psiconv_character_layout base_char,
+ const encoding enc);
+static void styles(const psiconv_config config, psiconv_list list,
+ const psiconv_word_styles_section styles_sec,const encoding enc);
+static void header(const psiconv_config config, psiconv_list list,
+ const psiconv_word_styles_section styles_sec,const encoding enc);
+static void footer(const psiconv_config config, psiconv_list list,
+ const encoding enc);
+static void characters(const psiconv_config config, psiconv_list list,
+ const psiconv_string_t textstr,
+ const psiconv_character_layout layout,
+ const psiconv_character_layout base,
+ const encoding enc);
+static void paragraphs(const psiconv_config config, psiconv_list list,
+ psiconv_text_and_layout paragraphs,
+ const psiconv_word_styles_section styles,
+ const encoding enc);
+static void paragraph(const psiconv_config config, psiconv_list list,
+ const psiconv_paragraph para,
+ const psiconv_word_styles_section styles_sec,
+ const encoding enc);
+static void gen_word(const psiconv_config config, psiconv_list list,
+ const psiconv_word_f file, const encoding enc);
+static void gen_texted(const psiconv_config config, psiconv_list list,
+ const psiconv_texted_f file, const encoding enc);
+static int gen_xhtml(const psiconv_config config, psiconv_list list,
+ const psiconv_file file, const char *dest,
+ const encoding enc);
+
+
+
void text(const psiconv_config config,psiconv_list list,
psiconv_string_t data,const encoding enc)
{
@@ -40,7 +96,7 @@
output_simple_chars(config,list,"
",enc);
else if ((data[i] == 0x0b) || (data[i] == 0x0c))
output_simple_chars(config,list,"-",enc);
- else if (data[i] == 0x0f)
+ else if ((data[i] == 0x0f) || (data[i] == 0x09) || (data[i] == 0x0a))
output_simple_chars(config,list," ",enc);
else if (data[i] >= 0x20)
output_char(config,list,data[i],enc);
@@ -100,6 +156,26 @@
free(name_copy);
}
+/* Check whether the same layout information would be generated */
+int character_layout_equal(const psiconv_character_layout l1,
+ const psiconv_character_layout l2)
+{
+ return (l1 && l2 &&
+ (l1->color->red == l2->color->red) &&
+ (l1->color->green == l2->color->green) &&
+ (l1->color->blue == l2->color->blue) &&
+ (l1->back_color->red == l2->back_color->red) &&
+ (l1->back_color->green == l2->back_color->green) &&
+ (l1->back_color->blue == l2->back_color->blue) &&
+ (l1->font_size == l2->font_size) &&
+ (l1->italic == l2->italic) &&
+ (l1->bold == l2->bold) &&
+ (l1->super_sub == l2->super_sub) &&
+ (l1->underline == l2->underline) &&
+ (l1->strikethrough == l2->strikethrough) &&
+ (l1->font->screenfont == l2->font->screenfont));
+}
+
void character_layout_diffs(const psiconv_config config, psiconv_list list,
const psiconv_character_layout new,
const psiconv_character_layout base,
@@ -235,12 +311,15 @@
output_simple_chars(config,list,";",enc);
}
+#if 0
+ /* This gave bad output... */
if (!base || (new->linespacing != base->linespacing)) {
output_simple_chars(config,list,"line-height:",enc);
snprintf(tempstr,TEMPSTR_LEN,"%f",new->linespacing);
output_simple_chars(config,list,tempstr,enc);
output_simple_chars(config,list,"pt;",enc);
}
+#endif
if (!base || (new->space_above != base->space_above)) {
output_simple_chars(config,list,"padding-top:",enc);
@@ -477,9 +556,9 @@
const psiconv_word_styles_section styles_sec,
const encoding enc)
{
- int i,charnr;
+ int i,charnr,start,len;
psiconv_string_t text;
- psiconv_in_line_layout layout;
+ psiconv_in_line_layout layout,next_layout;
psiconv_word_style style = NULL;
psiconv_paragraph_layout base_para;
psiconv_character_layout base_char;
@@ -530,28 +609,49 @@
output_simple_chars(config,list,">",enc);
if (psiconv_list_length(para->in_lines) == 0) {
- characters(config,list,para->text,para->base_character,
- para->base_character,enc);
+ if (psiconv_unicode_strlen(para->text))
+ characters(config,list,para->text,para->base_character,
+ para->base_character,enc);
} else {
charnr = 0;
+ start = -1;
for (i = 0; i < psiconv_list_length(para->in_lines); i++) {
+ if (start < 0)
+ start = charnr;
if (!(layout = psiconv_list_get(para->in_lines,i))) {
fputs("Internal data structures corruption\n",stderr);
exit(1);
}
- if (!(text = malloc(sizeof (*text) * (layout->length + 1)))) {
- fputs("Out of memory error\n",stderr);
- exit(1);
+ if (i+1 < psiconv_list_length(para->in_lines)) {
+ if (!(next_layout = psiconv_list_get(para->in_lines,i+1))) {
+ fputs("Internal data structures corruption\n",stderr);
+ exit(1);
+ }
+ } else {
+ next_layout = NULL;
+ }
+ if (next_layout &&
+ character_layout_equal(layout->layout,next_layout->layout)) {
+ charnr += layout->length;
+ continue;
+ }
+ len = charnr - start + layout->length;
+ if (len) {
+ if (!(text = malloc(sizeof (*text) * (len + 1)))) {
+ fputs("Out of memory error\n",stderr);
+ exit(1);
+ }
+ memcpy(text,para->text+start,len * sizeof(*text));
+ text[len] = 0;
+ characters(config,list,text,layout->layout,para->base_character,enc);
+ free(text);
}
- memcpy(text,para->text+charnr,layout->length * sizeof(*text));
- text[layout->length] = 0;
- characters(config,list,text,layout->layout,para->base_character,enc);
- free(text);
charnr += layout->length;
+ start = -1;
}
}
output_simple_chars(config, list,
- para->base_paragraph->bullet->on?"\n":"\n",
+ para->base_paragraph->bullet->on?"\n":"
\n",
enc);
if (!styles_sec) {
psiconv_free_paragraph_layout(base_para);
@@ -576,7 +676,7 @@
}
}
-void gen_html_word(const psiconv_config config, psiconv_list list,
+void gen_word(const psiconv_config config, psiconv_list list,
const psiconv_word_f file, const encoding enc)
{
if (!file)
@@ -588,7 +688,7 @@
}
-void gen_html_texted(const psiconv_config config, psiconv_list list,
+void gen_texted(const psiconv_config config, psiconv_list list,
const psiconv_texted_f file, const encoding enc)
{
header(config,list,NULL,enc);
@@ -596,44 +696,49 @@
footer(config,list,enc);
}
-int gen_html(const psiconv_config config, psiconv_list list,
+int gen_xhtml(const psiconv_config config, psiconv_list list,
const psiconv_file file, const char *dest,
const encoding enc)
{
+ encoding enc1 = enc;
+
if (enc == ENCODING_PSION) {
fputs("Unsupported encoding\n",stderr);
return -1;
- }
+ } else if (enc == ENCODING_ASCII)
+ enc1 = ENCODING_ASCII_HTML;
if (file->type == psiconv_word_file) {
- gen_html_word(config,list,(psiconv_word_f) file->file,enc);
+ gen_word(config,list,(psiconv_word_f) file->file,enc1);
return 0;
} else if (file->type == psiconv_texted_file) {
- gen_html_texted(config,list,(psiconv_texted_f) file->file,enc);
+ gen_texted(config,list,(psiconv_texted_f) file->file,enc1);
return 0;
} else
return -1;
}
-static struct fileformat_s ffs[] =
+static struct fileformat_s fileformats[] =
{
{
"XHTML",
"XHTML 1.0 Strict, using CSS for formatting",
- gen_html
+ FORMAT_WORD | FORMAT_TEXTED,
+ gen_xhtml
},
{
NULL,
NULL,
+ 0,
NULL
}
};
-void init_html(void)
+void init_xhtml(void)
{
int i;
- for (i = 0; ffs[i].name; i++)
- psiconv_list_add(fileformat_list,ffs+i);
+ for (i = 0; fileformats[i].name; i++)
+ psiconv_list_add(fileformat_list,fileformats+i);
}