home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / word2x0a.zip / source / latex-table.cc < prev    next >
C/C++ Source or Header  |  1998-04-20  |  6KB  |  294 lines

  1. /* $Id: latex-table.cc,v 1.8 1997/04/13 13:27:29 dps Exp $ */
  2. /* Latex table layout */
  3. #ifdef __GNUC__
  4. #define alloca __builtin_alloca
  5. #else
  6. #if HAVE_ALLOCA_H
  7. #include <alloca.h>
  8. #else /* Do not have alloca.h */
  9. #ifdef _AIX
  10.  #pragma alloca
  11. #else /* not _AIX */
  12. char *alloca();
  13. #endif /* _AIX */
  14. #endif /* HAVE_ALLOCA_H */
  15. #endif /* __GNUC__ */
  16.  
  17. #include <iostream.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "tblock.h"
  22. #include "latex-table.h"
  23. #define __EXCLUDE_READER_CLASSES
  24. #include "lib.h"
  25.  
  26. struct rdata
  27. {
  28.     struct wd_info w;
  29.     const char *data;
  30. };
  31.  
  32.  
  33.  
  34. /* Print row after folding of columns has been done */
  35. static void basic_print_row(int ncols, const struct rdata *cols,
  36.                 int maxw, FILE *out)
  37. {    
  38.     const char *s;
  39.     int i, nsp, nz;
  40.     align_t al;
  41.     num_info n;
  42.     tblock output, *outp;
  43.  
  44.     /* Print the content */
  45.     for (i=0; i<ncols; i++)
  46.     {
  47.  
  48.     s=cols[i].data;
  49.     al=cols[i].w.align;
  50.     if (cols[i].w.dp_col>=0)
  51.     {
  52.         n=scan_num(s);
  53.         if (n.dot_pos!=-1)
  54.         {
  55.         nz=cols[i].w.dp_col-n.dot_pos;
  56.         if ((!n.has_sign) && (cols[i].w.has_sign))
  57.         {
  58.             output.add("\\phantom{$-$");
  59.             if (nz>0)
  60.             {
  61.             while (nz--)
  62.                 output.add('0');
  63.             }
  64.             output.add("}");
  65.         }
  66.         else
  67.         {
  68.             if (n.has_sign)
  69.             nz++;    // - does not count as a digit.
  70.             if (nz>0)
  71.             {
  72.             output.add("\\phantom{");
  73.             while (nz--)
  74.                 output.add('0');
  75.             output.add("}");
  76.             }
  77.         }
  78.         if (n.has_sign)
  79.         {
  80.             /* Typeset the sign in math mode */
  81.             output.add('$');
  82.             output.add(*s);
  83.             output.add('$');
  84.             s++;
  85.         }
  86.         output.add(s);
  87.         if (nsp-cols[i].w.dp_col+n.dot_pos>0
  88.             && cols[i].w.align!=ALIGN_LEFT)
  89.             output.add("\\hfill");
  90.         al=ALIGN_DP;
  91.         }
  92.         }
  93.  
  94.     switch(al)
  95.     {
  96.     case ALIGN_DP:
  97.         break;
  98.         
  99.     case ALIGN_LEFT:
  100.     case ALIGN_CENTER:
  101.     case ALIGN_RIGHT:
  102.         output.add(s);
  103.         break;
  104.         
  105.     default:
  106.         fprintf(stderr,"basic_print_row: Invalid alignment\n");
  107.         break;
  108.     }
  109.     
  110.     if (i<ncols-1)
  111.         output.add(" & ", 3); // Seperate columns
  112.     }
  113.     output.add(" \n");        // converted to \\ \n by word_wrap.
  114.     outp=word_wrap((const char *) output, "\n", "\n", maxw, 0);
  115.     fputs((const char *) (*outp), out);
  116.     delete(outp);
  117. }
  118.  
  119. extern tblock *__latex_do_map(const char *);
  120. /* Split the elements of a row */
  121. static void print_row(int ncols, const struct rdata *dp, int maxw, FILE *out)
  122. {
  123.     static const char null_string[]={'\0'};
  124.     struct rdata *rd; 
  125.     tblock *d;
  126.     int i;
  127.  
  128.     /* Allocate structures */
  129.     if ((rd=(struct rdata *) alloca(ncols*sizeof(rdata)))==NULL)
  130.     {
  131.     fprintf(stderr, "print_row: fatal alloca failure\n");
  132.     exit(1);
  133.     }
  134.     
  135.     /* Convert data to *TeX */
  136.     for (i=0; i<ncols; i++)
  137.     {
  138.     rd[i].w=dp[i].w;
  139.     if (dp[i].data==NULL)
  140.     {
  141.         rd[i].data=null_string; // Avoid complication of null in
  142.                     // basic_print_row
  143.         continue;            // Move on to next item
  144.     }
  145.  
  146.     d=__latex_do_map(dp[i].data);
  147.     if ((rd[i].data=strdup(*d))==NULL)
  148.     {
  149.         fprintf(stderr, "latex_table::print_row: fatal alloca failure\n");
  150.         exit(1);
  151.     }
  152.     delete(d);
  153.     }
  154.     basic_print_row(ncols, rd, maxw, out); // Printing the rows is actually
  155.                        // quite complex.
  156.     for (i=0; i<ncols; i++)
  157.     {
  158.     if (rd[i].data!=null_string)
  159.         free((void *) rd[i].data);    // Free data
  160.     }
  161. }
  162.  
  163.  
  164.     
  165. /* Returns NULL or text message */
  166. const char *latex_table::print_table(int wd, FILE *out, const int ruled=1)
  167. {
  168.     int i,j;
  169.     struct rdata *d;
  170.     const struct col_info *col;
  171.  
  172.     if ((d=(struct rdata *) alloca(cols*sizeof(struct rdata)))==NULL)
  173.     {
  174.     cerr<<"latex_table::print_table alloca failute (fatal)\n";
  175.     return "[Table omitted due to lack of memory]";
  176.     }
  177.     if (cols==0 || rows==0)
  178.     {
  179.     fputs("[empty tabel ignored]\n", out);
  180.     return "[Ignored empty table]";
  181.     }
  182.  
  183.     for (i=0, col=cdata; col!=NULL; i++, col=col->next)
  184.     d[i].w=find_width(rows, col->data);
  185.  
  186.     fputs("\\begin{tabular}{", out);
  187.     for (i=0; i<cols; i++)
  188.     {
  189.     if (ruled)
  190.         fputc('|', out);
  191.     switch(d[i].w.align)
  192.     {
  193.     default:
  194.        cerr<<"Alignment "<<d[i].w.align<<" unsupported\n";
  195.        /* Fall through */
  196.  
  197.        case ALIGN_LEFT:
  198.        fputc('l', out);
  199.        break;
  200.  
  201.        case ALIGN_CENTER:
  202.        fputc('c', out);
  203.        break;
  204.  
  205.        case ALIGN_RIGHT:
  206.        fputc('r', out);
  207.        break;
  208.        }
  209.     }
  210.     fprintf(out, "%s}%s\n", (ruled) ? "|" : "", (ruled) ? "\\hline " : "");
  211.  
  212.     for (i=0; i<rows; i++)
  213.     {
  214.     for (j=0, col=cdata; col!=NULL; j++, col=col->next)
  215.         d[j].data=(col->data)[i];
  216.     print_row(cols, d, wd, out);
  217.     if (i==0)
  218.         fputs("\\hline\n", out);
  219.     }
  220.  
  221.     fprintf(out, "%s\\end{tabular}\\\\\n", (ruled) ? "\\hline " : "");
  222.     return NULL;
  223. }
  224.  
  225. /* Set */
  226. int latex_table::set(int c, int r, const char *s)
  227. {
  228.     struct col_info *col;
  229.     int i;
  230.  
  231.     if (c<0 || c>=cols || r<0 || r>=rows)
  232.     {
  233.     cerr<<"Invalid request to set "<<c<<','<<r<<" in "
  234.         <<cols<<'x'<<rows<<" table (value "<<s<<")\n";
  235.     return 0;
  236.     }
  237.  
  238.     for (col=cdata, i=0; i<c && col!=NULL; i++, col=col->next) ;   
  239.     if (col!=NULL)
  240.     {
  241.     if (col->data[r]!=NULL)
  242.         free((void *) col->data[r]);
  243.     col->data[r]=strdup(s);
  244.     }
  245.     return 1;
  246. }
  247.  
  248.     
  249. /* Constructor */
  250. latex_table::latex_table(int c, int r)
  251. {
  252.     int i, j;
  253.     struct col_info *col, **nptr;
  254.  
  255.     cols=c;
  256.     rows=r;
  257.     cdata=NULL;            // Hardenning against cols=0
  258.     for (nptr=&cdata, i=0; i<cols; i++)
  259.     {
  260.     col=new(struct col_info);
  261.     *nptr=col;
  262.     col->next=NULL;
  263.     nptr=&(col->next);
  264.     if ((col->data=
  265.          (const char **) malloc(rows*(sizeof(const char *))))==NULL)
  266.     {
  267.         cerr<<"latex_table::constructor: malloc failure (fatal)\n";
  268.         exit(1);
  269.     }
  270.     for (j=0; j<rows; j++)
  271.         (col->data)[j]=NULL;
  272.     }
  273. }
  274.  
  275. /* Destructor */
  276. latex_table::~latex_table(int c, int r)
  277. {
  278.     int i;
  279.     struct col_info *col, *nxt;
  280.     
  281.     for (col=cdata; col!=NULL;)
  282.     {
  283.     for (i=0; i<rows; i++)
  284.         if (col->data[i]==NULL)
  285.         free((void *) col->data[i]);
  286.     nxt=col->next;
  287.     free(col);
  288.     col=nxt;
  289.     }
  290. }
  291.  
  292.  
  293.  
  294.