home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
word2x0a.zip
/
source
/
latex-table.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-20
|
6KB
|
294 lines
/* $Id: latex-table.cc,v 1.8 1997/04/13 13:27:29 dps Exp $ */
/* Latex table layout */
#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 */
char *alloca();
#endif /* _AIX */
#endif /* HAVE_ALLOCA_H */
#endif /* __GNUC__ */
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tblock.h"
#include "latex-table.h"
#define __EXCLUDE_READER_CLASSES
#include "lib.h"
struct rdata
{
struct wd_info w;
const char *data;
};
/* Print row after folding of columns has been done */
static void basic_print_row(int ncols, const struct rdata *cols,
int maxw, FILE *out)
{
const char *s;
int i, nsp, nz;
align_t al;
num_info n;
tblock output, *outp;
/* Print the content */
for (i=0; i<ncols; i++)
{
s=cols[i].data;
al=cols[i].w.align;
if (cols[i].w.dp_col>=0)
{
n=scan_num(s);
if (n.dot_pos!=-1)
{
nz=cols[i].w.dp_col-n.dot_pos;
if ((!n.has_sign) && (cols[i].w.has_sign))
{
output.add("\\phantom{$-$");
if (nz>0)
{
while (nz--)
output.add('0');
}
output.add("}");
}
else
{
if (n.has_sign)
nz++; // - does not count as a digit.
if (nz>0)
{
output.add("\\phantom{");
while (nz--)
output.add('0');
output.add("}");
}
}
if (n.has_sign)
{
/* Typeset the sign in math mode */
output.add('$');
output.add(*s);
output.add('$');
s++;
}
output.add(s);
if (nsp-cols[i].w.dp_col+n.dot_pos>0
&& cols[i].w.align!=ALIGN_LEFT)
output.add("\\hfill");
al=ALIGN_DP;
}
}
switch(al)
{
case ALIGN_DP:
break;
case ALIGN_LEFT:
case ALIGN_CENTER:
case ALIGN_RIGHT:
output.add(s);
break;
default:
fprintf(stderr,"basic_print_row: Invalid alignment\n");
break;
}
if (i<ncols-1)
output.add(" & ", 3); // Seperate columns
}
output.add(" \n"); // converted to \\ \n by word_wrap.
outp=word_wrap((const char *) output, "\n", "\n", maxw, 0);
fputs((const char *) (*outp), out);
delete(outp);
}
extern tblock *__latex_do_map(const char *);
/* Split the elements of a row */
static void print_row(int ncols, const struct rdata *dp, int maxw, FILE *out)
{
static const char null_string[]={'\0'};
struct rdata *rd;
tblock *d;
int i;
/* Allocate structures */
if ((rd=(struct rdata *) alloca(ncols*sizeof(rdata)))==NULL)
{
fprintf(stderr, "print_row: fatal alloca failure\n");
exit(1);
}
/* Convert data to *TeX */
for (i=0; i<ncols; i++)
{
rd[i].w=dp[i].w;
if (dp[i].data==NULL)
{
rd[i].data=null_string; // Avoid complication of null in
// basic_print_row
continue; // Move on to next item
}
d=__latex_do_map(dp[i].data);
if ((rd[i].data=strdup(*d))==NULL)
{
fprintf(stderr, "latex_table::print_row: fatal alloca failure\n");
exit(1);
}
delete(d);
}
basic_print_row(ncols, rd, maxw, out); // Printing the rows is actually
// quite complex.
for (i=0; i<ncols; i++)
{
if (rd[i].data!=null_string)
free((void *) rd[i].data); // Free data
}
}
/* Returns NULL or text message */
const char *latex_table::print_table(int wd, FILE *out, const int ruled=1)
{
int i,j;
struct rdata *d;
const struct col_info *col;
if ((d=(struct rdata *) alloca(cols*sizeof(struct rdata)))==NULL)
{
cerr<<"latex_table::print_table alloca failute (fatal)\n";
return "[Table omitted due to lack of memory]";
}
if (cols==0 || rows==0)
{
fputs("[empty tabel ignored]\n", out);
return "[Ignored empty table]";
}
for (i=0, col=cdata; col!=NULL; i++, col=col->next)
d[i].w=find_width(rows, col->data);
fputs("\\begin{tabular}{", out);
for (i=0; i<cols; i++)
{
if (ruled)
fputc('|', out);
switch(d[i].w.align)
{
default:
cerr<<"Alignment "<<d[i].w.align<<" unsupported\n";
/* Fall through */
case ALIGN_LEFT:
fputc('l', out);
break;
case ALIGN_CENTER:
fputc('c', out);
break;
case ALIGN_RIGHT:
fputc('r', out);
break;
}
}
fprintf(out, "%s}%s\n", (ruled) ? "|" : "", (ruled) ? "\\hline " : "");
for (i=0; i<rows; i++)
{
for (j=0, col=cdata; col!=NULL; j++, col=col->next)
d[j].data=(col->data)[i];
print_row(cols, d, wd, out);
if (i==0)
fputs("\\hline\n", out);
}
fprintf(out, "%s\\end{tabular}\\\\\n", (ruled) ? "\\hline " : "");
return NULL;
}
/* Set */
int latex_table::set(int c, int r, const char *s)
{
struct col_info *col;
int i;
if (c<0 || c>=cols || r<0 || r>=rows)
{
cerr<<"Invalid request to set "<<c<<','<<r<<" in "
<<cols<<'x'<<rows<<" table (value "<<s<<")\n";
return 0;
}
for (col=cdata, i=0; i<c && col!=NULL; i++, col=col->next) ;
if (col!=NULL)
{
if (col->data[r]!=NULL)
free((void *) col->data[r]);
col->data[r]=strdup(s);
}
return 1;
}
/* Constructor */
latex_table::latex_table(int c, int r)
{
int i, j;
struct col_info *col, **nptr;
cols=c;
rows=r;
cdata=NULL; // Hardenning against cols=0
for (nptr=&cdata, i=0; i<cols; i++)
{
col=new(struct col_info);
*nptr=col;
col->next=NULL;
nptr=&(col->next);
if ((col->data=
(const char **) malloc(rows*(sizeof(const char *))))==NULL)
{
cerr<<"latex_table::constructor: malloc failure (fatal)\n";
exit(1);
}
for (j=0; j<rows; j++)
(col->data)[j]=NULL;
}
}
/* Destructor */
latex_table::~latex_table(int c, int r)
{
int i;
struct col_info *col, *nxt;
for (col=cdata; col!=NULL;)
{
for (i=0; i<rows; i++)
if (col->data[i]==NULL)
free((void *) col->data[i]);
nxt=col->next;
free(col);
col=nxt;
}
}