diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/word2x/html-fmt.cc |
Initial commit
Diffstat (limited to 'support/word2x/html-fmt.cc')
-rw-r--r-- | support/word2x/html-fmt.cc | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/support/word2x/html-fmt.cc b/support/word2x/html-fmt.cc new file mode 100644 index 0000000000..11344d6530 --- /dev/null +++ b/support/word2x/html-fmt.cc @@ -0,0 +1,487 @@ +/* $Id: html-fmt.cc,v 1.1 1997/04/23 00:45:06 dps Exp dps $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_CTYPE_H +#include <ctype.h> +#endif /* HAVE_CTYPE_H */ +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ +#include "interface.h" +#include "lib.h" +#include "html-table.h" +#include "fmt-html.h" + +static const cmap html_map[]= +{ + { '\n', "<BR>\n" }, // Newline + { 0x1E, "-" }, // Unbreakable join + { 0x1F, "\\-" }, // Soft hypen + { '<', "<" }, // # + { '>', ">" }, // $ + { '&', "&" }, // & + { 0x85, "..." }, // Dots + { 0x91, "`" }, // 91 = left quote (15th element) + { 0x92, "'" }, // 92 = right quote + { 0x93, "``" }, // 93 = opening double quote + { 0x94, "''" }, // 94 = closing double quote + { 0x96, "--" }, // em-dash + { 0x97, "---" }, // en-dash (20th element) + { 0x99, "(TM)" }, // Trademark + { 0xA0, " " }, // Unbreakable space + { 0xA3, "<=" }, // <= came out as A3, also pounds + { 0xA9, "(C)" }, // Copyright + { 0xAB, "<<" }, // Openning << quotes (25th element) + { 0xAE, "(R)" }, // reserved sign + { 0xB3, ">=" }, // Greater than or = came out as B3 + { 0xBB, ">>" }, // Closing >> quotes (28th element) + { 0xDF, "ß" }, // beta + { 0xE4, "ä" }, // a with umlualt + { 0xE9, "è" }, // e grave?? + { 0xF1, "&ntidle" }, // n bar + { 0xF6, "ö" }, // o with umlualt + { 0xFA, "\\.u" }, // u with dot? + { 0xFC, "ü" }, // u with umlualt. +}; + +tblock *__html_do_map(const char *s) +{ + tblock *out; + + out = map_string(s, html_map); + return out; +} + +/* Preamble */ +static void h_preamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + time_t now; + struct stat st; + char *tnow, *tdoc; + + t=t; + d=d; + + now=time(NULL); + tnow=(fmt->date)(now); + + if (fstat(fileno(out), &st)==-1) + st.st_mtime=now; + tdoc=fmt->date(st.st_mtime); + + fprintf(out, + "<!-- Generated by word2x on %s-->\n" + "\n" + "<HTML>\n" + "<HEAD>\n" + " <TITLE>Word document from %s</TITLE>" + "</HEAD>\n" + "<BODY>\n", + tnow, tdoc); + free(tnow); + free(tdoc); +} + +/* Postamble */ +static void h_postamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *dp; + fmt=fmt; + t=t; + dp=(struct html_data *) d; + + fputs("</BODY></HTML>\n", out); +} + +/* Allocate local data */ +static void *allocate_html(void) +{ + struct html_data *tdata; + int i; + + tdata = new(struct html_data); + tdata->tabl = NULL; + tdata->last_tc = NULL; + tdata->unit_d.unit_type = 1; + tdata->list_flg = 0; + for (i=0; i<4; i++) + tdata->unit_d.unit_number[i]=-1; + + return tdata; +} + +/* Free local data */ +static void free_html(void *d) +{ + struct html_data *tdata; + + tdata=(struct html_data *) d; + if (tdata->tabl!=NULL) + delete(tdata->tabl); +} + + +static void html_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + d=d; + switch(*(t->data.d)) + { + case CH_PAGE: + if (fmt->flags.new_pages) + fputs("\n<HR>\n", out); + break; + + default: + break; + } +} + + +struct list_info +{ + const char *ltype; // List type from reader + const char *start; // Start tag + const char *end; // End tag +}; + +static const struct list_info *ltype_info(const char *type) +{ + static const struct list_info list_inf[]= + { + { "listAlpha", "<OL TYPE=\"A\">", "</OL>" }, // Netscape extension + { "listalpha", "<OL TYPE=\"a\">", "</OL>" }, // Netscape extension + { "enumerate", "<OL>", "</OL>" }, // Standard + { "itemize", "<UL>", "</UL>" }, // Standard + }; + + unsigned i; + + for (i=0; i<N(list_inf); i++) + { + if (strcmp(type, list_inf[i].ltype)==0) + return (list_inf+i); + } + return NULL; +} + +/* item */ +static void html_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *dp; + fmt=fmt; + t=t; + out=out; + dp=(struct html_data *) d; + + dp->list_flg=1; +} + + +/* start list, have to convert from *TeX types... */ +static void html_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + const struct list_info *linf; + const char *s; + + fmt=fmt; + d=d; + linf=ltype_info(t->data.d); + if (linf==NULL) + { + cerr<<"Unknown list type "<<t->data.d<<" treated as bulleted list\n"; + s="<UL>"; + } + else + { + s=linf->start; + } + fprintf(out, "\n%s\n", s); +} + +/* end list, have to convert from *TeX types... */ +static void html_end_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + const struct list_info *linf; + const char *s; + + fmt=fmt; + d=d; + fmt=fmt; + d=d; + linf=ltype_info(t->data.d); + if (linf==NULL) + { + cerr<<"Unknown list type "<<t->data.d<<" treated as bulleted list\n"; + s="</UL>"; + } + else + s=linf->end; + fprintf(out, "\n%s\n", s); +} + +/* + * Paragraphs are easy, but get complicated due to need to work out + * which things are actually chapter headings, etc + */ +static void fold_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out, + void *d) +{ + tblock *b, *ts, op; + const char *s, *t, *pt, *unit_html="P"; + struct html_data *dp; + int has_num, i, j; + struct unit_number u_num; + + static const char *const sects[]= + { + "H1", "H2", "H3", "H4" + }; + static const char *const sects_english[]= + { + "chapter", "section", "subsection", "subsubsection" + }; + + dp = (struct html_data *) d; + + /* Even this much is under 100%!! */ + pt=(tok->data.d); + + if (*pt=='\0' && dp->list_flg==1) + return; + + if (dp->last_tc != NULL) + { + if (strcmp(dp->last_tc, pt)==0) + { + unit_html=sects[dp->unit_d.unit_type]; + } + + else + { + s=dp->last_tc+strlen(dp->last_tc)-strlen(pt); + if (strcmp(s, pt)==0) + { + /* Find type */ + for (i=0; i<(int) N(sects_english); i++) + { + if (strncasecmp(dp->last_tc, sects_english[i], + strlen(sects_english[i]))==0) + break; + } + t = dp->last_tc+strlen(sects_english[i]); + has_num = get_part_num(t,s); + unit_html=sects[i]; // Set the section type + + /* Update the control data */ + if (dp->unit_d.unit_number[i]==-1) + { + dp->unit_d.unit_number[i]=(has_num==-1) ? 1 : has_num; + for (j=i+1; j<(int) N(sects); j++) + dp->unit_d.unit_number[j]=0; + } + if (i<(int) N(sects)-1) + dp->unit_d.unit_type=i+1; + else + dp->unit_d.unit_type=i; + } + } + free((void *) dp->last_tc); + dp->last_tc=NULL; + } + else + { + if (dp->list_flg) + { + op.add("<Li>"); + } + else + { + if (strlen(pt)>0 && strlen(pt)<PAR_TRESHOLD_LEN) + { + if (strcasecmp(pt,"Appendix")==0) + { + dp->unit_d.unit_type= + (dp->unit_d.unit_number[0]==-1) ? 1 : 0; + + /* Output the heading level */ + unit_html=sects[dp->unit_d.unit_type]; + for (j=dp->unit_d.unit_type+1; j<(int) N(sects); j++) + dp->unit_d.unit_number[j]=0; + } + else if (strcasecmp(pt,"Bibliography")==0) + { + dp->unit_d.unit_type= + (dp->unit_d.unit_number[0]==-1) ? 1 : 0; + for (j=dp->unit_d.unit_type+1; j<(int) N(sects); j++) + dp->unit_d.unit_number[j]=0; + } + else + { + u_num=n_unit_probe(pt, &(dp->unit_d)); + + if (u_num.unit_num!=-1) + { + i=u_num.offset; + unit_html=sects[u_num.unit_num]; + } + } + } + } + dp->list_flg=0; + } + /* Record the unit type started */ + dp->unit_html=unit_html; + /* Insert the start tag and eneter paragraoh if not in one */ + if (!dp->par_flg) + { + dp->par_flg = 1; + op.add("<"); + op.add(unit_html); + op.add('>'); + } + /* Add the text */ + ts = map_string(pt, html_map); + op.add(*ts); + delete(ts); + /* fold the line */ + b = word_wrap(op, "\n", "\n", fmt->maxline, 0); + fputs((*b), out); + delete(b); +} + +/* End of paragraph, outputs the end tag */ +static void end_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *dp; + + tok=tok; + fmt=fmt; + dp=(struct html_data *) d; + dp->par_flg=0; + + fputs("</",out); + fputs(dp->unit_html, out); + fputs(">\n\n", out); +} + +/* Start a table === allocate table and initialise */ +static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *tdata; + + out=out; + fmt=fmt; + tdata=(struct html_data *) d; + tdata->col=0; + tdata->row=0; + tdata->tabl=new(html_table)(t->data.table.cols, t->data.table.rows); + tdata->par_flg=0; +} + + +/* End of a table==print the table */ +static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *tdata; + + t=t; + tdata=(struct html_data *) d; + tdata->tabl->print_table(fmt->maxline, out); // Print table + delete(tdata->tabl); + tdata->tabl=NULL; +} + +/* start row==set column to 0 */ +static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct html_data *) d; + tdata->col=0; +} + +/* end row==add one to row */ +static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *tdata; + + fmt=fmt; + t=t; + out=out; + tdata=(struct html_data *) d; + tdata->row++; +} + + +/* Start field === set field */ +static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *tdata; + + tdata=(struct html_data *) d; + out=out; + fmt=fmt; + tdata->tabl->set(tdata->col, tdata->row, t->data.d); +} + +/* end field==add one to col */ +static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct html_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct html_data *) d; + tdata->col++; +} + + + +/* pointers to the functions that do the work */ +docfmt htmlfmt= +{ + { 1 }, // Keep page breaks + 76, // Width + "\n", // Use \n as line ends + allocate_html, // Allocate space + free_html, // Free text + { + { h_preamble, h_postamble }, // End and start of document + { fold_para, end_para }, // Paragraph + { alloc_tbl, format_tbl }, // Start/end table + { set_field, inc_col }, // Start/end field + { start_row, inc_row }, // Start/end row + { html_embed, null_proc }, // Throw away embed messages + { html_list, html_end_list }, // Start/end list + { html_item, null_proc }, // Start/end item + { html_code, null_proc }, // Code ends do not occur + { null_proc, null_proc } // Do not understanding anything else + } +} ; + + + |