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/text-fmt.cc |
Initial commit
Diffstat (limited to 'support/word2x/text-fmt.cc')
-rw-r--r-- | support/word2x/text-fmt.cc | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/support/word2x/text-fmt.cc b/support/word2x/text-fmt.cc new file mode 100644 index 0000000000..3d032462b9 --- /dev/null +++ b/support/word2x/text-fmt.cc @@ -0,0 +1,287 @@ +/* $Id: text-fmt.cc,v 1.13 1997/04/13 04:15:33 dps Exp $ */ + +/* Everything is declared as static to avoid namespace polution but */ +/* is reachable externally via the exported table (and this it the */ +/* only way they get called). */ +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else +#if HAVE_ALLOCA_H +#include <alloca.h> +#else /* Do not have alloca.h */ + #ifdef _AIX +#pragma alloca +#else /* not _AIX */ +extern "C" char *alloca(int); +#endif /* _AIX */ +#endif /* HAVE_ALLOCA_H */ +#endif /* __GNUC__ */ + +#include <stdio.h> +#include <stdlib.h> +#include "interface.h" +#include "lib.h" +#include "text-table.h" + +/* Local data */ +struct text_data +{ + text_table *tabl; + int col; + int row; + int margin; + int l_indent; +}; + +/* Most of these values are thanks to catdoc by + * Victor B. Wagner <vitus@agropc.msk.su> et al */ +static const cmap char_map[]= +{ + { 0x1E, "-" }, // Unbreakable join + { 0x1F, "" }, // Soft hypen + { 0x7f, "" }, // Delete 127s + { 0x85, "..." }, // Dots + { 0x91, "`" }, // 91 = left quote + { 0x92, "'" }, // 92 = right quote + { 0x93, "\"" }, // 93 = opening double quote + { 0x94, "\"" }, // 94 = closing double quote + { 0x95, "o" }, // 95 = Bullet + { 0x96, "-" }, // em-dash + { 0x97, "-" }, // en-dash + { 0x99, "(tm)" }, // Trademark + { 0xA0, " " }, // Unbreakable space + { 0xA3, "<=" }, // Less than or = came out as A3 + { 0xA9, "(c)" }, // Copyright + { 0xAB, "<<" }, // Openning << quotes + { 0xAE, "(R)" }, // Reserved sign + { 0xB3, ">=" }, // Greater than or = came out as B3 + { 0xBB, ">>" }, // Closing >> quotes +}; + +/* Allocate local data */ +static void *allocate_txt(void) +{ + struct text_data *tdata; + + tdata=new(struct text_data); + tdata->tabl=NULL; + tdata->margin=0; + tdata->l_indent=0; + return tdata; +} + +static void txt_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) + fputc('\014', out); + break; + + default: + break; + } +} + +/* Free local data */ +static void free_txt(void *d) +{ + struct text_data *tdata; + + tdata=(struct text_data *) d; + if (tdata->tabl!=NULL) + delete(tdata->tabl); +} + + +/* list start increases margin */ +static void inc_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct text_data *tdata; + t=t; + fmt=fmt; + out=out; + + tdata=(struct text_data *) d; + tdata->margin+=4; +} + + +/* list start decreases margin */ +static void dec_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct text_data *tdata; + t=t; + fmt=fmt; + out=out; + + tdata=(struct text_data *) d; + tdata->margin-=4; +} + + +/* items are easy */ +static void txt_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + tblock *ts; + const char *s; + int i, m; + struct text_data *dp; + + fmt=fmt; // No need for fmt + dp=(struct text_data *) d; + ts=map_string(t->data.d, char_map); + s=*ts; + fputc('\n', out); + m=dp->margin-strlen(s)-1; + for (i=0; i<m; i++) + fputc(' ', out); + fputs(s, out); + fputc(' ', out); + dp->l_indent=dp->margin; + delete(ts); +} + + +/* Paragraphs are easy */ +static void fold_para(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + tblock *b, *ts; + const char *s; + char *nl; + struct text_data *dp; + int i; + + dp=(struct text_data *) d; + if (dp->margin==0 || (nl=(char *) alloca(dp->margin+2))==NULL) + nl="\n"; + else + { + *nl='\n'; + for (i=1; i<=dp->margin; i++) + *(nl+i)=' '; + *(nl+dp->margin+1)='\0'; + } + ts=map_string(t->data.d, char_map); + b=word_wrap((*ts), nl, nl, fmt->maxline-(dp->margin), 0); + delete(ts); + s=*b; + for (i=dp->l_indent; i<dp->margin; i++) + fputc(' ', out); + fputs(s, out); + fputs("\n\n", out); + dp->l_indent=0; + delete(b); +} + +/* Start a table === allocate table and initialise */ +static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct text_data *tdata; + + out=out; + fmt=fmt; + tdata=(struct text_data *) d; + tdata->col=0; + tdata->row=0; + tdata->tabl=new(text_table)(t->data.table.cols, t->data.table.rows); +} + + +/* End of a table==print the table */ +static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct text_data *tdata; + + t=t; + tdata=(struct text_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 text_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct text_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 text_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct text_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 tblock *ts; + struct text_data *tdata; + + out=out; + fmt=fmt; + ts=map_string(t->data.d, char_map); + tdata=(struct text_data *) d; + tdata->tabl->set(tdata->col, tdata->row, (*ts)); + delete(ts); +} + +/* end field==add one to col */ +static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out, + void *d) +{ + struct text_data *tdata; + + out=out; + fmt=fmt; + t=t; + tdata=(struct text_data *) d; + tdata->col++; +} + +/* pointers to the functions that do the work */ +docfmt txtfmt= +{ + { 0 }, // No page breaks + 76, // Width + "\n", // Use \n as line ends + allocate_txt, // Allocate space + free_txt, // Free text + { + { null_proc, null_proc }, // End and start of document---do nothing + { fold_para, null_proc }, // Paragraph + { alloc_tbl, format_tbl }, // Start/end table + { set_field, inc_col }, // Start/end field + { start_row, inc_row }, // Start/end row + { null_proc, null_proc }, // Throw away embed messages + { inc_margin, dec_margin }, // list start and end + { txt_item, null_proc}, // Items + { txt_code, null_proc}, // Code + { null_proc, null_proc } // Do not understanding anything else + } +}; |