From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/word2x/latex-fmt.cc | 537 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 537 insertions(+) create mode 100644 support/word2x/latex-fmt.cc (limited to 'support/word2x/latex-fmt.cc') diff --git a/support/word2x/latex-fmt.cc b/support/word2x/latex-fmt.cc new file mode 100644 index 0000000000..1caf7fb4e2 --- /dev/null +++ b/support/word2x/latex-fmt.cc @@ -0,0 +1,537 @@ +/* $Id: latex-fmt.cc,v 1.15 1997/04/13 13:26:38 dps Exp dps $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_CTYPE_H +#include +#endif /* HAVE_CTYPE_H */ +#ifdef HAVE_SYS_STAT_H +#include +#endif /* HAVE_SYS_STAT_H */ +#include "interface.h" +#include "lib.h" +#include "latex-table.h" +#include "fmt-latex.h" + +static const cmap tex_map[]= +{ + { '\n', "\\\\\n" }, // Newline + { 0x1E, "-" }, // Unbreakable join + { 0x1F, "\\-" }, // Soft hypen + { '#', "{\\#}" }, // # + { '$', "{\\$}" }, // $ + { '%', "{\\%}" }, // % (5th element) + { '&', "{\\&}" }, // & + { '@', "{\\@}" }, // @ + { '\\', "$\\backslash$" }, // backslash + { '^', "{\\^}" }, // ^ + { '_', "{\\_}" }, // _ (10th element) + { '{', "{\\{}" }, // { + { '}', "{\\}}" }, // } + { '~', "{\\~}" }, // ~ + { CH_SUSPECT, "" }, // Delete suspect data markers + { 0x85, "\\unskip\\ldots" }, // 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, "${}^{\\rm TM}$" }, // Trademark + { 0xA0, "~" }, // Unbreakable space + { 0xA3, "$\\leq$" }, // <= came out as A3, also pounds + { 0xA9, "{\\copyright}" }, // Copyright + { 0xAB, "$<\\!\\!<$" }, // Openning << quotes (25th element) + { 0xAE, "{\\reg}" }, // reserved sign + { 0xB3, "$\\geq$" }, // Greater than or = came out as B3 + { 0xBB, "$>\\!\\!>$" }, // Closing >> quotes (28th element) + { 0xDF, "{\\ss}" }, // beta + { 0xE4, "\\\"a" }, // a with umlualt + { 0xE9, "\\'e" }, // e grave?? + { 0xF1, "\\=n" }, // n bar + { 0xF6, "\\\"o" }, // o with umlualt + { 0xFA, "\\.u" }, // u with dot? + { 0xFC, "\\\"u" }, // u with umlualt. + +}; + +tblock *__latex_do_map(const char *s) +{ + tblock *out; + + out=map_string(s, tex_map); + return out; +} + +/* Preamble */ +static void preamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + time_t now; +#ifdef HAVE_FSTAT + struct stat st; +#endif + char *tnow, *tdoc; + + t=t; + d=d; + + now=time(NULL); + tnow=(fmt->date)(now); + +#ifdef HAVE_FSTAT + if (fstat(fileno(out), &st)==-1) + { + fprintf(stderr, "Warning: fstat failed\n"); + st.st_mtime=now; + } + tdoc=fmt->date(st.st_mtime); +#else + tdoc="date not known"; +#endif + + fprintf(out, + "%% Generated by word2x on %s\n" + "%%\n" + "\\date{%s}\n" + "\\documentclass{article}\n" + "\\usepackage{amstext}\n" + "\\def\\reg{\\setbox0\\hbox{$\\mathchar\"20D$}%%\n" + "\\hbox to 0pt{\\hbox to \\wd0{\\hfill\\,\\rm R\\hfill}\\hss}%%\n" + "$\\mathchar\"20D$}\n" + "\\usepackage[latin1]{inputenc}\n" + "\\begin{document}\n", + tnow, tdoc); + free(tnow); + free(tdoc); +} + +/* Postamble */ +static void postamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct latex_data *dp; + fmt=fmt; + t=t; + dp=(struct latex_data *) d; + + fputs("\\end{document}\n", out); +} + +/* Allocate local data */ +static void *allocate_latex(void) +{ + struct latex_data *tdata; + int i; + + tdata=new(struct latex_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_latex(void *d) +{ + struct latex_data *tdata; + + tdata=(struct latex_data *) d; + if (tdata->tabl!=NULL) + delete(tdata->tabl); + +} + +static void ltx_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\\newpage%\n", out); + break; + + default: + break; + } +} + +/* item */ +static void ltx_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct latex_data *dp; + fmt=fmt; + t=t; + out=out; + dp=(struct latex_data *) d; + + dp->list_flg=1; +} + + +/* start list */ +static void ltx_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + fmt=fmt; + d=d; + + fprintf(out, "\n\\begin{%s}\n", t->data.d); // Prior argement with reader +} + +/* end list */ +static void ltx_end_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + fmt=fmt; + d=d; + + fprintf(out, "\n\\end{%s}\n", t->data.d); // Prior argement with reader +} + + +/* Find part number and return it or -1 if no number */ +int get_part_num(const char *st, const char *fence) +{ + int n; + + while (stpar_flg=1; + + /* Even this much is under 100%!! */ + pt=(tok->data.d); + + if (*pt=='\0') + return; + + if (dp->last_tc!=NULL) + { + if (strcmp(dp->last_tc, pt)==0) + { + op.add("\\addcontentsline{toc}{"); + op.add(sects[dp->unit_d.unit_type]); op.add("}{"); + op.add(dp->last_tc); op.add("}\n\\"); + op.add(sects[dp->unit_d.unit_type]); + op.add("*{"); + do_add=1; + } + + 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)-1; i++) + { + if (strncasecmp(dp->last_tc, sects[i], + strlen(sects[i]))==0) + break; + } + t=dp->last_tc+strlen(sects[i]); + has_num=get_part_num(t,s); + if (has_num==-1) + { + op.add("\\addcontentsline{toc}{"); + op.add(sects[i]); op.add("}{"); + op.add(dp->last_tc); + op.add("}\n"); + } + op.add('\\'); + op.add(sects[i]); + op.add((has_num!=-1) ? "{" : "*{"); + 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; + do_add=1; + } + } + free((void *) dp->last_tc); + dp->last_tc=NULL; + } + else + { + if (dp->list_flg) + { + op.add("\\item "); + } + else + { + if (strlen(pt)>0 && strlen(pt)unit_d.unit_type=(dp->unit_d.unit_number[0]==-1) ? 1:0; + op.add(sects[dp->unit_d.unit_type]); + op.add("{"); + do_add=1; + 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; + op.add('\\'); + op.add(sects[dp->unit_d.unit_type]); + op.add("*{"); + do_add=1; + for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++) + dp->unit_d.unit_number[j]=0; + } + else + { + int i,n,c,l, unit; + + unit=dp->unit_d.unit_type-1; + l=strlen(pt); + i=0; + while(1) + { + n=0; + for (c=0; i= (int) N(sects)) + { + unit=N(sects)-1; + break; + } + if (dp->unit_d.unit_number[unit]==-1) + { + if (n>MAX_START_NUM) + goto out_normal; + + dp->unit_d.unit_number[unit]=n; + for (j=unit+1; j< (int) N(sects); j++) + dp->unit_d.unit_number[j]=0; + } + else if (dp->unit_d.unit_number[unit]+1==n) + { + dp->unit_d.unit_number[unit]++; + for (j=unit+1; j< (int) N(sects); j++) + dp->unit_d.unit_number[j]=0; + } + else if (dp->unit_d.unit_number[unit]!=n) + goto out_normal; + + if (pt[i]!='.') + break; + i++; + } + + if (unit==dp->unit_d.unit_type-1) + goto out_normal; + op.add('\\'); + op.add(sects[unit]); + op.add((i>0) ? "{" : "*{"); + while(isspace(pt[i])) i++; + pt+=i; + do_add=1; + } + } + out_normal: ; + } + dp->list_flg=0; + } + + ts=map_string(pt, tex_map); + op.add(*ts); + if (do_add) + op.add('}'); + delete(ts); + + b=word_wrap(op, "\n", "\n", fmt->maxline, 0); + fputs((*b), out); + delete(b); +} + +/* End of paragraph */ +static void end_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out, + void *d) +{ + struct latex_data *dp; + + tok=tok; + fmt=fmt; + dp=(struct latex_data *) d; + dp->par_flg=0; + + 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 latex_data *tdata; + + out=out; + fmt=fmt; + tdata=(struct latex_data *) d; + tdata->col=0; + tdata->row=0; + tdata->tabl=new(latex_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 latex_data *tdata; + + t=t; + tdata=(struct latex_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 latex_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct latex_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 latex_data *tdata; + + fmt=fmt; + t=t; + out=out; + tdata=(struct latex_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 latex_data *tdata; + + tdata=(struct latex_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 latex_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct latex_data *) d; + tdata->col++; +} + +/* pointers to the functions that do the work */ +docfmt latexfmt= +{ + { 0 }, // Ignore page breaks + 76, // Width + "\n", // Use \n as line ends + allocate_latex, // Allocate space + free_latex, // Free text + { + { preamble, postamble }, // End and start of document---do nothing + { 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 + { ltx_embed, null_proc }, // Throw away embed messages + { ltx_list, ltx_end_list }, // Start/end list + { ltx_item, null_proc }, // Start/end item + { ltx_code, null_proc }, // Codes end do not happen + { null_proc, null_proc } // Do not understanding anything else + } +}; -- cgit v1.2.3