home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / word2x0a.zip / source / text-fmt.cc < prev    next >
C/C++ Source or Header  |  1998-08-08  |  7KB  |  317 lines

  1. /* $Id: text-fmt.cc,v 1.13 1997/04/13 04:15:33 dps Exp $ */
  2.  
  3. /* Everything is declared as static to avoid namespace polution but */
  4. /* is reachable externally via the exported table (and this it the  */
  5. /* only way they get called).                        */
  6. #ifdef __GNUC__
  7. #define alloca __builtin_alloca
  8. #else
  9. #if HAVE_ALLOCA_H
  10. #include <alloca.h>
  11. #else /* Do not have alloca.h */
  12.  #ifdef _AIX
  13. #pragma alloca
  14. #else /* not _AIX */
  15. char *alloca();
  16. #endif /* _AIX */
  17. #endif /* HAVE_ALLOCA_H */
  18. #endif /* __GNUC__ */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include "interface.h"
  23. #include "lib.h"
  24. #include "text-table.h"
  25.  
  26. /* Local data */
  27. struct text_data
  28. {
  29.     text_table *tabl;
  30.     int col;
  31.     int row;
  32.     int margin;
  33.     int l_indent;
  34. };
  35.  
  36. /* Most of these values are thanks to catdoc by
  37.  * Victor B. Wagner <vitus@agropc.msk.su> et al */
  38. static const cmap char_map[]=
  39. {
  40.     { 0x1E, "-" },      // Unbreakable join
  41.     { 0x1F, "" },    // Soft hypen
  42.     { 0x7f, "" },    // Delete 127s
  43.     { 0x85, "..." },    // Dots
  44.     { 0x91, "`" },      // 91 = left quote
  45.     { 0x92, "'" },      // 92 = right quote
  46.     { 0x93, "\"" },     // 93 = opening double quote
  47.     { 0x94, "\"" },     // 94 = closing double quote
  48.     { 0x95, "o" },    // 95 = Bullet
  49.     { 0x96, "-" },      // em-dash
  50.     { 0x97, "-" },      // en-dash
  51.     { 0x99, "(tm)" },   // Trademark
  52.     { 0xA0, " " },      // Unbreakable space
  53.     { 0xA3, "<=" },    // Less than or = came out as A3
  54.     { 0xA9, "(c)" },    // Copyright
  55.     { 0xAB, "<<" },     // Openning << quotes
  56.     { 0xAE, "(R)" },    // Reserved sign
  57.     { 0xB3, ">=" },    // Greater than or = came out as B3
  58.     { 0xBB, ">>" },    // Closing >> quotes
  59.  
  60.  
  61.     /* german stuff (jk) */
  62.     /* missing are: The paragraph sign (⌡) and the euro (???) plus more */
  63.     /* let me know if you find it out joerg@gmx.de */
  64.  
  65. #ifdef OUTPUT_CHARSET_GERMAN_X    /* define for 7bit german umlaut */
  66.                                   /* transscription */
  67.     { 0xC4, "Ae" },         // big a umlault
  68.     { 0xD6, "Oe" },         // big o umlault
  69.     { 0xDC, "Ue" },         // big u umlault
  70.     { 0xDF, "sz" },         // sz
  71.     { 0xE4, "ae" },         // small a umlault
  72.     { 0xF6, "oe" },         // small o umlault
  73.     { 0xFC, "ue" },         // small u umlault
  74. #endif
  75.  
  76. #ifdef OUTPUT_CHARSET_IBM850    /* define this for use under OS/2 */
  77.     { 0xC4, "Ä" },         // big a umlault
  78.     { 0xD6, "Ö" },         // big o umlault
  79.     { 0xDC, "Ü" },         // big u umlault
  80.     { 0xDF, "ß" },         // sz
  81.     { 0xE4, "ä" },         // small a umlault
  82.     { 0xF6, "ö" },         // small o umlault
  83.     { 0xFC, "ü" },         // small u umlault
  84. #endif
  85.  
  86.     /* end of german stuff */
  87.  
  88. };
  89.  
  90. /* Allocate local data */
  91. static void *allocate_txt(void)
  92. {
  93.     struct text_data *tdata;
  94.  
  95.     tdata=new(struct text_data);
  96.     tdata->tabl=NULL;
  97.     tdata->margin=0;
  98.     tdata->l_indent=0;
  99.     return tdata;
  100. }
  101.  
  102. static void txt_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  103.              void *d)
  104. {
  105.     d=d;
  106.     switch(*(t->data.d))
  107.     {
  108.     case CH_PAGE:
  109.     if (fmt->flags.new_pages)
  110.         fputc('\014', out);
  111.     break;
  112.  
  113.     default:
  114.     break;
  115.     }
  116. }
  117.  
  118. /* Free local data */
  119. static void free_txt(void *d)
  120. {
  121.     struct text_data *tdata;
  122.  
  123.     tdata=(struct text_data *) d;
  124.     if (tdata->tabl!=NULL)
  125.     delete(tdata->tabl);
  126. }
  127.  
  128.  
  129. /* list start increases margin */
  130. static void inc_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  131.               void *d)
  132. {
  133.     struct text_data *tdata;
  134.     t=t;
  135.     fmt=fmt;
  136.     out=out;
  137.  
  138.     tdata=(struct text_data *) d;
  139.     tdata->margin+=4;
  140. }
  141.  
  142.  
  143. /* list start decreases margin */
  144. static void dec_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  145.               void *d)
  146. {
  147.     struct text_data *tdata;
  148.     t=t;
  149.     fmt=fmt;
  150.     out=out;
  151.  
  152.     tdata=(struct text_data *) d;
  153.     tdata->margin-=4;
  154. }
  155.  
  156.  
  157. /* items are easy */
  158. static void txt_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  159.               void *d)
  160. {
  161.     tblock *ts;
  162.     const char *s;
  163.     int i, m;
  164.     struct text_data *dp;
  165.  
  166.     fmt=fmt;            // No need for fmt
  167.     dp=(struct text_data *) d;
  168.     ts=map_string(t->data.d, char_map);
  169.     s=*ts;
  170.     fputc('\n', out);
  171.     m=dp->margin-strlen(s)-1;
  172.     for (i=0; i<m; i++)
  173.     fputc(' ', out);
  174.     fputs(s, out);
  175.     fputc(' ', out);
  176.     dp->l_indent=dp->margin;
  177.     delete(ts);
  178. }
  179.  
  180.  
  181. /* Paragraphs are easy */
  182. static void fold_para(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  183.               void *d)
  184. {
  185.     tblock *b, *ts;
  186.     const char *s;
  187.     char *nl;
  188.     struct text_data *dp;
  189.     int i;
  190.  
  191.     dp=(struct text_data *) d;
  192.     if (dp->margin==0 || (nl=(char *) alloca(dp->margin+2))==NULL)
  193.     nl="\n";
  194.     else
  195.     {
  196.     *nl='\n';
  197.     for (i=1; i<=dp->margin; i++)
  198.         *(nl+i)=' ';
  199.     *(nl+dp->margin+1)='\0';
  200.     }
  201.     ts=map_string(t->data.d, char_map);
  202.     b=word_wrap((*ts), nl, nl, fmt->maxline-(dp->margin), 0);
  203.     delete(ts);
  204.     s=*b;
  205.     for (i=dp->l_indent; i<dp->margin; i++)
  206.     fputc(' ', out);
  207.     fputs(s, out);
  208.     fputs("\n\n", out);
  209.     dp->l_indent=0;
  210.     delete(b);
  211. }
  212.  
  213. /* Start a table === allocate table and initialise */
  214. static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  215.               void *d)
  216. {
  217.     struct text_data *tdata;
  218.  
  219.     out=out;
  220.     fmt=fmt;
  221.     tdata=(struct text_data *) d;
  222.     tdata->col=0;
  223.     tdata->row=0;
  224.     tdata->tabl=new(text_table)(t->data.table.cols, t->data.table.rows);
  225. }
  226.  
  227.  
  228. /* End of a table==print the table */
  229. static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  230.                void *d)
  231. {
  232.     struct text_data *tdata;
  233.  
  234.     t=t;
  235.     tdata=(struct text_data *) d;
  236.     tdata->tabl->print_table(fmt->maxline, out); // Print table
  237.     delete(tdata->tabl);
  238.     tdata->tabl=NULL;
  239. }
  240.  
  241. /* start row==set column to 0 */
  242. static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  243.               void *d)
  244.     struct text_data *tdata;
  245.  
  246.     out=out;
  247.     fmt=fmt;
  248.     t=t;
  249.     tdata=(struct text_data *) d;
  250.     tdata->col=0;
  251. }
  252.  
  253. /* end row==add one to row */
  254. static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  255.             void *d)
  256.     struct text_data *tdata;
  257.  
  258.     out=out;
  259.     fmt=fmt;
  260.     t=t;
  261.     tdata=(struct text_data *) d;
  262.     tdata->row++;
  263. }
  264.  
  265.  
  266. /* Start field === set field */
  267. static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  268.               void *d)
  269. {
  270.     struct tblock *ts;
  271.     struct text_data *tdata;
  272.  
  273.     out=out;
  274.     fmt=fmt;
  275.     ts=map_string(t->data.d, char_map);
  276.     tdata=(struct text_data *) d;
  277.     tdata->tabl->set(tdata->col, tdata->row, (*ts));
  278.     delete(ts);
  279. }
  280.  
  281. /* end field==add one to col */
  282. static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  283.             void *d)
  284.     struct text_data *tdata;
  285.  
  286.     out=out;
  287.     fmt=fmt;
  288.     t=t;
  289.     tdata=(struct text_data *) d;
  290.     tdata->col++;
  291. }
  292.  
  293. /* pointers to the functions that do the work */
  294. docfmt txtfmt=
  295. {
  296.     { 0 },                // No page breaks
  297.     76,                    // Width
  298.     "\n",                // Use \n as line ends
  299.     allocate_txt,            // Allocate space
  300.     free_txt,                // Free text
  301.     {
  302.     { null_proc, null_proc },   // End and start of document---do nothing
  303.     { fold_para, null_proc },   // Paragraph
  304.     { alloc_tbl, format_tbl },  // Start/end table
  305.     { set_field, inc_col },        // Start/end field
  306.     { start_row, inc_row },        // Start/end row
  307.     { null_proc, null_proc },   // Throw away embed messages
  308.     { inc_margin, dec_margin }, // list start and end
  309.     { txt_item, null_proc},        // Items
  310.     { txt_code, null_proc},        // Code
  311.     { null_proc, null_proc }    // Do not understanding anything else
  312.     }
  313. };
  314.