--- /dev/null
+/* t..c : external declarations */
+
+# include "stdio.h"
+# include "ctype.h"
+
+# define MAXLIN 200
+# define MAXHEAD 30
+# define MAXCOL 20
+# define MAXCHS 2000
+# define MAXRPT 100
+# define CLLEN 10
+# define SHORTLINE 4
+extern int nlin, ncol, iline, nclin, nslin;
+extern int style[MAXHEAD][MAXCOL];
+extern int ctop[MAXHEAD][MAXCOL];
+extern char font[MAXHEAD][MAXCOL][2];
+extern char csize[MAXHEAD][MAXCOL][4];
+extern char vsize[MAXHEAD][MAXCOL][4];
+extern char cll[MAXCOL][CLLEN];
+extern int stynum[];
+extern int F1, F2;
+extern int lefline[MAXHEAD][MAXCOL];
+extern int fullbot[];
+extern char *instead[];
+extern int expflg;
+extern int ctrflg;
+extern int evenflg;
+extern int evenup[];
+extern int boxflg;
+extern int dboxflg;
+extern int linsize;
+extern int tab;
+extern int pr1403;
+extern int linsize, delim1, delim2;
+extern int allflg;
+extern int textflg;
+extern int left1flg;
+extern int rightl;
+struct colstr {char *col, *rcol;};
+extern struct colstr *table[];
+extern char *cspace, *cstore;
+extern char *exstore, *exlim;
+extern int sep[];
+extern int used[], lused[], rused[];
+extern int linestop[];
+extern int leftover;
+extern char *last, *ifile;
+extern int texname;
+extern int texct, texmax;
+extern char texstr[];
+extern int linstart;
+
+
+extern FILE *tabin, *tabout;
+# define CRIGHT 80
+# define CLEFT 40
+# define CMID 60
+# define S1 31
+# define S2 32
+# define TMP 38
+# define SF 35
+# define SL 34
+# define LSIZE 33
+# define SIND 37
+# define SVS 36
+/* this refers to the relative position of lines */
+# define LEFT 1
+# define RIGHT 2
+# define THRU 3
+# define TOP 1
+# define BOT 2
--- /dev/null
+ /* t0.c: storage allocation */
+#
+# include "t..c"
+int expflg = 0;
+int ctrflg = 0;
+int boxflg = 0;
+int dboxflg = 0;
+int tab = '\t';
+int linsize;
+int pr1403;
+int delim1, delim2;
+int evenup[MAXCOL], evenflg;
+int F1 = 0;
+int F2 = 0;
+int allflg = 0;
+int leftover = 0;
+int textflg = 0;
+int left1flg = 0;
+int rightl = 0;
+char *cstore, *cspace;
+char *last;
+struct colstr *table[MAXLIN];
+int style[MAXHEAD][MAXCOL];
+int ctop[MAXHEAD][MAXCOL];
+char font[MAXHEAD][MAXCOL][2];
+char csize[MAXHEAD][MAXCOL][4];
+char vsize[MAXHEAD][MAXCOL][4];
+int lefline[MAXHEAD][MAXCOL];
+char cll[MAXCOL][CLLEN];
+/*char *rpt[MAXHEAD][MAXCOL];*/
+/*char rpttx[MAXRPT];*/
+int stynum[MAXLIN+1];
+int nslin, nclin;
+int sep[MAXCOL];
+int fullbot[MAXLIN];
+char *instead[MAXLIN];
+int used[MAXCOL], lused[MAXCOL], rused[MAXCOL];
+int linestop[MAXLIN];
+int nlin, ncol;
+int iline = 1;
+char *ifile = "Input";
+int texname = 'a';
+int texct = 0;
+char texstr[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ0123456789";
+int linstart;
+char *exstore, *exlim;
+FILE *tabin /*= stdin */;
+FILE *tabout /* = stdout */;
--- /dev/null
+ /* t1.c: main control and input switching */
+#
+# include "t..c"
+#include <signal.h>
+# ifdef gcos
+/* required by GCOS because file is passed to "tbl" by troff preprocessor */
+# define _f1 _f
+extern FILE *_f[];
+# endif
+
+# ifdef unix
+# define MACROS "/usr/lib/tmac.s"
+# define PYMACS "/usr/lib/tmac.m"
+# endif
+
+# ifdef gcos
+# define MACROS "cc/troff/smac"
+# define PYMACS "cc/troff/mmac"
+# endif
+
+# define ever (;;)
+
+main(argc,argv)
+ char *argv[];
+{
+# ifdef unix
+int badsig();
+signal(SIGPIPE, badsig);
+# endif
+# ifdef gcos
+if(!intss()) tabout = fopen("qq", "w"); /* default media code is type 5 */
+# endif
+exit(tbl(argc,argv));
+}
+
+
+tbl(argc,argv)
+ char *argv[];
+{
+char line[512];
+/* required by GCOS because "stdout" is set by troff preprocessor */
+tabin=stdin; tabout=stdout;
+setinp(argc,argv);
+while (gets1(line))
+ {
+ fprintf(tabout, "%s\n",line);
+ if (prefix(".TS", line))
+ tableput();
+ }
+fclose(tabin);
+return(0);
+}
+int sargc;
+char **sargv;
+setinp(argc,argv)
+ char **argv;
+{
+ sargc = argc;
+ sargv = argv;
+ sargc--; sargv++;
+ if (sargc>0)
+ swapin();
+}
+swapin()
+{
+ while (sargc>0 && **sargv=='-') /* Mem fault if no test on sargc */
+ {
+ if (sargc<=0) return(0);
+ if (match("-ms", *sargv))
+ {
+ *sargv = MACROS;
+ break;
+ }
+ if (match("-mm", *sargv))
+ {
+ *sargv = PYMACS;
+ break;
+ }
+ if (match("-TX", *sargv))
+ pr1403=1;
+ sargc--; sargv++;
+ }
+ if (sargc<=0) return(0);
+# ifdef unix
+/* file closing is done by GCOS troff preprocessor */
+ if (tabin!=stdin) fclose(tabin);
+# endif
+ tabin = fopen(ifile= *sargv, "r");
+ iline=1;
+# ifdef unix
+/* file names are all put into f. by the GCOS troff preprocessor */
+ fprintf(tabout, ".ds f. %s\n",ifile);
+# endif
+ if (tabin==NULL)
+ error("Can't open file");
+ sargc--;
+ sargv++;
+ return(1);
+}
+# ifdef unix
+badsig()
+{
+signal(SIGPIPE, SIG_IGN);
+ exit(0);
+}
+# endif
--- /dev/null
+ /* t2.c: subroutine sequencing for one table */
+# include "t..c"
+tableput()
+{
+saveline();
+savefill();
+ifdivert();
+cleanfc();
+getcomm();
+getspec();
+gettbl();
+getstop();
+checkuse();
+choochar();
+maktab();
+runout();
+release();
+rstofill();
+endoff();
+restline();
+}
--- /dev/null
+ /* t3.c: interpret commands affecting whole table */
+# include "t..c"
+struct optstr {char *optnam; int *optadd;} options [] = {
+ "expand", &expflg,
+ "EXPAND", &expflg,
+ "center", &ctrflg,
+ "CENTER", &ctrflg,
+ "box", &boxflg,
+ "BOX", &boxflg,
+ "allbox", &allflg,
+ "ALLBOX", &allflg,
+ "doublebox", &dboxflg,
+ "DOUBLEBOX", &dboxflg,
+ "frame", &boxflg,
+ "FRAME", &boxflg,
+ "doubleframe", &dboxflg,
+ "DOUBLEFRAME", &dboxflg,
+ "tab", &tab,
+ "TAB", &tab,
+ "linesize", &linsize,
+ "LINESIZE", &linsize,
+ "delim", &delim1,
+ "DELIM", &delim1,
+ 0,0};
+getcomm()
+{
+char line[200], *cp, nb[25], *t;
+struct optstr *lp;
+int c, ci, found;
+for(lp= options; lp->optnam; lp++)
+ *(lp->optadd) = 0;
+texname = texstr[texct=0];
+tab = '\t';
+printf(".nr %d \\n(.s\n", LSIZE);
+gets1(line);
+/* see if this is a command line */
+if (index(line,';') == NULL)
+ {
+ backrest(line);
+ return;
+ }
+for(cp=line; (c = *cp) != ';'; cp++)
+ {
+ if (!letter(c)) continue;
+ found=0;
+ for(lp= options; lp->optadd; lp++)
+ {
+ if (prefix(lp->optnam, cp))
+ {
+ *(lp->optadd) = 1;
+ cp += strlen(lp->optnam);
+ if (letter(*cp))
+ error("Misspelled global option");
+ while (*cp==' ')cp++;
+ t=nb;
+ if ( *cp == '(')
+ while ((ci= *++cp) != ')')
+ *t++ = ci;
+ else cp--;
+ *t++ = 0; *t=0;
+ if (lp->optadd == &tab)
+ {
+ if (nb[0])
+ *(lp->optadd) = nb[0];
+ }
+ if (lp->optadd == &linsize)
+ printf(".nr %d %s\n", LSIZE, nb);
+ if (lp->optadd == &delim1)
+ {
+ delim1 = nb[0];
+ delim2 = nb[1];
+ }
+ found=1;
+ break;
+ }
+ }
+ if (!found)
+ error("Illegal option");
+ }
+cp++;
+backrest(cp);
+return;
+}
+backrest(cp)
+ char *cp;
+{
+char *s;
+for(s=cp; *s; s++);
+un1getc('\n');
+while (s>cp)
+ un1getc(*--s);
+return;
+}
--- /dev/null
+ /* t5.c: read data for table */
+# include "t..c"
+gettbl()
+{
+int icol, ch;
+cstore=cspace= chspace();
+textflg=0;
+for (nlin=nslin=0; gets1(cstore); nlin++)
+ {
+ stynum[nlin]=nslin;
+ if (prefix(".TE", cstore))
+ {
+ leftover=0;
+ break;
+ }
+ if (prefix(".TC", cstore) || prefix(".T&", cstore))
+ {
+ readspec();
+ nslin++;
+ }
+ if (nlin>=MAXLIN)
+ {
+ leftover=cstore;
+ break;
+ }
+ fullbot[nlin]=0;
+ if (cstore[0] == '.' && !isdigit(cstore[1]))
+ {
+ instead[nlin] = cstore;
+ while (*cstore++);
+ continue;
+ }
+ else instead[nlin] = 0;
+ if (nodata(nlin))
+ {
+ if (ch = oneh(nlin))
+ fullbot[nlin]= ch;
+ nlin++;
+ nslin++;
+ instead[nlin]=fullbot[nlin]=0;
+ }
+ table[nlin] = alocv((ncol+2)*sizeof(table[0][0]));
+ if (cstore[1]==0)
+ switch(cstore[0])
+ {
+ case '_': fullbot[nlin]= '-'; continue;
+ case '=': fullbot[nlin]= '='; continue;
+ }
+ stynum[nlin] = nslin;
+ nslin = min(nslin+1, nclin-1);
+ for (icol = 0; icol <ncol; icol++)
+ {
+ table[nlin][icol].col = cstore;
+ table[nlin][icol].rcol=0;
+ ch=1;
+ if (match(cstore, "T{")) /* text follows */
+ table[nlin][icol].col =
+ gettext(cstore, nlin, icol,
+ font[stynum[nlin]][icol],
+ csize[stynum[nlin]][icol]);
+ else
+ {
+ for(; (ch= *cstore) != '\0' && ch != tab; cstore++)
+ ;
+ *cstore++ = '\0';
+ switch(ctype(nlin,icol)) /* numerical or alpha, subcol */
+ {
+ case 'n':
+ table[nlin][icol].rcol = maknew(table[nlin][icol].col);
+ break;
+ case 'a':
+ table[nlin][icol].rcol = table[nlin][icol].col;
+ table[nlin][icol].col = "";
+ break;
+ }
+ }
+ while (ctype(nlin,icol+1)== 's') /* spanning */
+ table[nlin][++icol].col = "";
+ if (ch == '\0') break;
+ }
+ while (++icol <ncol+2)
+ {
+ table[nlin][icol].col = "";
+ table [nlin][icol].rcol=0;
+ }
+ while (*cstore != '\0')
+ cstore++;
+ if (cstore-cspace > MAXCHS)
+ cstore = cspace = chspace();
+ }
+last = cstore;
+permute();
+if (textflg) untext();
+return;
+}
+nodata(il)
+{
+int c;
+for (c=0; c<ncol;c++)
+ {
+ switch(ctype(il,c))
+ {
+ case 'c': case 'n': case 'r': case 'l': case 's': case 'a':
+ return(0);
+ }
+ }
+return(1);
+}
+oneh(lin)
+{
+int k, icol;
+k = ctype(lin,0);
+for(icol=1; icol<ncol; icol++)
+ {
+ if (k != ctype(lin,icol))
+ return(0);
+ }
+return(k);
+}
+# define SPAN "\\^"
+permute()
+{
+int irow, jcol, is;
+char *start, *strig;
+for(jcol=0; jcol<ncol; jcol++)
+ {
+ for(irow=1; irow<nlin; irow++)
+ {
+ if (vspand(irow,jcol,0))
+ {
+ is = prev(irow);
+ if (is<0)
+ error("Vertical spanning in first row not allowed");
+ start = table[is][jcol].col;
+ strig = table[is][jcol].rcol;
+ while (irow<nlin &&vspand(irow,jcol,0))
+ irow++;
+ table[--irow][jcol].col = start;
+ table[irow][jcol].rcol = strig;
+ while (is<irow)
+ {
+ table[is][jcol].rcol =0;
+ table[is][jcol].col= SPAN;
+ is = next(is);
+ }
+ }
+ }
+ }
+}
+vspand(ir,ij,ifform)
+{
+if (ir<0) return(0);
+if (ir>=nlin)return(0);
+if (instead[ir]) return(0);
+if (ifform==0 && ctype(ir,ij)=='^') return(1);
+if (table[ir][ij].rcol!=0) return(0);
+if (fullbot[ir]) return(0);
+return(vspen(table[ir][ij].col));
+}
+vspen(s)
+ char *s;
+{
+if (s==0) return(0);
+if (!point(s)) return(0);
+return(match(s, SPAN));
+}
--- /dev/null
+ /* t6.c: compute tab stops */
+# define tx(a) (a>0 && a<128)
+# include "t..c"
+maktab()
+{
+# define FN(i,c) font[stynum[i]][c]
+# define SZ(i,c) csize[stynum[i]][c]
+/* define the tab stops of the table */
+int icol, ilin, tsep, k, ik, vforml, il, text;
+int doubled[MAXCOL], acase[MAXCOL];
+char *s;
+for(icol=0; icol <ncol; icol++)
+ {
+ doubled[icol] = acase[icol] = 0;
+ fprintf(tabout, ".nr %d 0\n", icol+CRIGHT);
+ for(text=0; text<2; text++)
+ {
+ if (text)
+ fprintf(tabout, ".%02d\n.rm %02d\n", icol+80, icol+80);
+ for(ilin=0; ilin<nlin; ilin++)
+ {
+ if (instead[ilin]|| fullbot[ilin]) continue;
+ vforml=ilin;
+ for(il=prev(ilin); il>=0 && vspen(table[il][icol].col); il=prev(il))
+ vforml=il;
+ if (fspan(vforml,icol)) continue;
+ if (filler(table[ilin][icol].col)) continue;
+ switch(ctype(vforml,icol))
+ {
+ case 'a':
+ acase[icol]=1;
+ s = table[ilin][icol].col;
+ if (s>0 && s<128 && text)
+ {
+ if (doubled[icol]==0)
+ fprintf(tabout, ".nr %d 0\n.nr %d 0\n",S1,S2);
+ doubled[icol]=1;
+ fprintf(tabout, ".if \\n(%c->\\n(%d .nr %d \\n(%c-\n",s,S2,S2,s);
+ }
+ case 'n':
+ if (table[ilin][icol].rcol!=0)
+ {
+ if (doubled[icol]==0 && text==0)
+ fprintf(tabout, ".nr %d 0\n.nr %d 0\n", S1, S2);
+ doubled[icol]=1;
+ if (real(s=table[ilin][icol].col) && !vspen(s))
+ {
+ if (tx(s) != text) continue;
+ fprintf(tabout, ".nr %d ", TMP);
+ wide(s, FN(vforml,icol), SZ(vforml,icol)); fprintf(tabout, "\n");
+ fprintf(tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n", S1, TMP, S1, TMP);
+ }
+ if (text==0 && real(s=table[ilin][icol].rcol) && !vspen(s) && !barent(s))
+ {
+ fprintf(tabout, ".nr %d \\w%c%s%c\n",TMP, F1, s, F1);
+ fprintf(tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n",S2,TMP,S2,TMP);
+ }
+ continue;
+ }
+ case 'r':
+ case 'c':
+ case 'l':
+ if (real(s=table[ilin][icol].col) && !vspen(s))
+ {
+ if (tx(s) != text) continue;
+ fprintf(tabout, ".nr %d ", TMP);
+ wide(s, FN(vforml,icol), SZ(vforml,icol)); fprintf(tabout, "\n");
+ fprintf(tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n", icol+CRIGHT, TMP, icol+CRIGHT, TMP);
+ }
+ }
+ }
+ }
+ if (acase[icol])
+ {
+ fprintf(tabout, ".if \\n(%d>=\\n(%d .nr %d \\n(%du+2n\n",S2,icol+CRIGHT,icol+CRIGHT,S2);
+ }
+ if (doubled[icol])
+ {
+ fprintf(tabout, ".nr %d \\n(%d\n", icol+CMID, S1);
+ fprintf(tabout, ".nr %d \\n(%d+\\n(%d\n",TMP,icol+CMID,S2);
+ fprintf(tabout, ".if \\n(%d>\\n(%d .nr %d \\n(%d\n",TMP,icol+CRIGHT,icol+CRIGHT,TMP);
+ fprintf(tabout, ".if \\n(%d<\\n(%d .nr %d +(\\n(%d-\\n(%d)/2\n",TMP,icol+CRIGHT,icol+CMID,icol+CRIGHT,TMP);
+ }
+ if (cll[icol][0])
+ {
+ fprintf(tabout, ".nr %d %sn\n", TMP, cll[icol]);
+ fprintf(tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n",icol+CRIGHT, TMP, icol+CRIGHT, TMP);
+ }
+ for(ilin=0; ilin<nlin; ilin++)
+ if (k=lspan(ilin, icol))
+ {
+ s=table[ilin][icol-k].col;
+ if (!real(s) || barent(s) || vspen(s) ) continue;
+ fprintf(tabout, ".nr %d ", TMP);
+ wide(table[ilin][icol-k].col, FN(ilin,icol-k), SZ(ilin,icol-k));
+ for(ik=k; ik>=0; ik--)
+ {
+ fprintf(tabout, "-\\n(%d",CRIGHT+icol-ik);
+ if (!expflg && ik>0) fprintf(tabout, "-%dn", sep[icol-ik]);
+ }
+ fprintf(tabout, "\n");
+ fprintf(tabout, ".if \\n(%d>0 .nr %d \\n(%d/%d\n", TMP, TMP, TMP, k);
+ fprintf(tabout, ".if \\n(%d<0 .nr %d 0\n", TMP, TMP);
+ for(ik=1; ik<=k; ik++)
+ {
+ if (doubled[icol-k+ik])
+ fprintf(tabout, ".nr %d +\\n(%d/2\n", icol-k+ik+CMID, TMP);
+ fprintf(tabout, ".nr %d +\\n(%d\n", icol-k+ik+CRIGHT, TMP);
+ }
+ }
+ }
+if (textflg) untext();
+/* if even requested, make all columns widest width */
+# define TMP1 S1
+# define TMP2 S2
+if (evenflg)
+ {
+ fprintf(tabout, ".nr %d 0\n", TMP);
+ for(icol=0; icol<ncol; icol++)
+ {
+ if (evenup[icol]==0) continue;
+ fprintf(tabout, ".if \\n(%d>\\n(%d .nr %d \\n(%d\n",
+ icol+CRIGHT, TMP, TMP, icol+CRIGHT);
+ }
+ for(icol=0; icol<ncol; icol++)
+ {
+ if (evenup[icol]==0)
+ /* if column not evened just retain old interval */
+ continue;
+ if (doubled[icol])
+ fprintf(tabout, ".nr %d (100*\\n(%d/\\n(%d)*\\n(%d/100\n",
+ icol+CMID, icol+CMID, icol+CRIGHT, TMP);
+ /* that nonsense with the 100's and parens tries
+ to avoid overflow while proportionally shifting
+ the middle of the number */
+ fprintf(tabout, ".nr %d \\n(%d\n", icol+CRIGHT, TMP);
+ }
+ }
+/* now adjust for total table width */
+for(tsep=icol=0; icol<ncol; icol++)
+ tsep+= sep[icol];
+if (expflg)
+ {
+ fprintf(tabout, ".nr %d 0", TMP);
+ for(icol=0; icol<ncol; icol++)
+ fprintf(tabout, "+\\n(%d", icol+CRIGHT);
+ fprintf(tabout, "\n");
+ fprintf(tabout, ".nr %d \\n(.l-\\n(%d\n", TMP, TMP);
+ if (boxflg || dboxflg || allflg)
+ tsep += 1;
+ else
+ tsep -= sep[ncol-1];
+ fprintf(tabout, ".nr %d \\n(%d/%d\n", TMP, TMP, tsep);
+ fprintf(tabout, ".if \\n(%d<0 .nr %d 0\n", TMP, TMP);
+ }
+else
+ fprintf(tabout, ".nr %d 1n\n", TMP);
+fprintf(tabout, ".nr %d 0\n",CRIGHT-1);
+tsep= (boxflg || allflg || dboxflg || left1flg) ? 1 : 0;
+for(icol=0; icol<ncol; icol++)
+ {
+ fprintf(tabout, ".nr %d \\n(%d+(%d*\\n(%d)\n",icol+CLEFT, icol+CRIGHT-1, tsep, TMP);
+ fprintf(tabout, ".nr %d +\\n(%d\n",icol+CRIGHT, icol+CLEFT);
+ if (doubled[icol])
+ {
+ /* the next line is last-ditch effort to avoid zero field width */
+ /*fprintf(tabout, ".if \\n(%d=0 .nr %d 1\n",icol+CMID, icol+CMID);*/
+ fprintf(tabout, ".nr %d +\\n(%d\n", icol+CMID, icol+CLEFT);
+ /* fprintf(tabout, ".if n .if \\n(%d%%24>0 .nr %d +12u\n",icol+CMID, icol+CMID); */
+ }
+ tsep=sep[icol];
+ }
+if (rightl)
+ fprintf(tabout, ".nr %d (\\n(%d+\\n(%d)/2\n",ncol+CRIGHT-1, ncol+CLEFT-1, ncol+CRIGHT-2);
+fprintf(tabout, ".nr TW \\n(%d\n", ncol+CRIGHT-1);
+if (boxflg || allflg || dboxflg)
+ fprintf(tabout, ".nr TW +%d*\\n(%d\n", sep[ncol-1], TMP);
+fprintf(tabout,
+ ".if t .if (\\n(TW+\\n(.o)>7.65i .tm Table at line %d file %s is too wide - \\n(TW units\n", iline-1, ifile);
+return;
+}
+wide(s, fn, size)
+ char *s, *size, *fn;
+{
+if (point(s))
+ {
+ fprintf(tabout, "\\w%c", F1);
+ if (*fn>0) putfont(fn);
+ if (*size) putsize(size);
+ fprintf(tabout, "%s", s);
+ if (*fn>0) putfont("P");
+ if (*size) putsize("0");
+ fprintf(tabout, "%c",F1);
+ }
+else
+ fprintf(tabout, "\\n(%c-", s);
+}
+filler(s)
+ char *s;
+{
+return (point(s) && s[0]=='\\' && s[1] == 'R');
+}
--- /dev/null
+ /* t7.c: control to write table entries */
+# include "t..c"
+# define realsplit ((ct=='a'||ct=='n') && table[ldata][c].rcol)
+runout()
+{
+int i;
+if (boxflg || allflg || dboxflg) need();
+if (ctrflg)
+ {
+ fprintf(tabout, ".nr #I \\n(.i\n");
+ fprintf(tabout, ".in +(\\n(.lu-\\n(TWu-\\n(.iu)/2u\n");
+ }
+fprintf(tabout, ".fc %c %c\n", F1, F2);
+fprintf(tabout, ".nr #T 0-1\n");
+deftail();
+for(i=0; i<nlin; i++)
+ putline(i,i);
+if (leftover)
+ yetmore();
+fprintf(tabout, ".fc\n");
+fprintf(tabout, ".nr T. 1\n");
+fprintf(tabout, ".T# 1\n");
+if (ctrflg)
+ fprintf(tabout, ".in \\n(#Iu\n");
+}
+runtabs(lform, ldata)
+{
+int c, ct, vforml, lf;
+fprintf(tabout, ".ta ");
+for(c=0; c<ncol; c++)
+ {
+ vforml=lform;
+ for(lf=prev(lform); lf>=0 && vspen(table[lf][c].col); lf=prev(lf))
+ vforml=lf;
+ if (fspan(vforml,c))
+ continue;
+ switch(ct=ctype(vforml,c))
+ {
+ case 'n':
+ case 'a':
+ if (table[ldata][c].rcol)
+ if (lused[c]) /*Zero field width*/
+ fprintf(tabout, "\\n(%du ",c+CMID);
+ case 'c':
+ case 'l':
+ case 'r':
+ if (realsplit? rused[c]: (used[c]+lused[c]))
+ fprintf(tabout, "\\n(%du ",c+CRIGHT);
+ continue;
+ case 's':
+ if (lspan(lform, c))
+ fprintf(tabout, "\\n(%du ", c+CRIGHT);
+ continue;
+ }
+ }
+fprintf(tabout, "\n");
+}
+ifline(s)
+ char *s;
+{
+if (s[0] == '\\') s++;
+if (s[1] ) return(0);
+if (s[0] == '_') return('-');
+if (s[0] == '=') return('=');
+return(0);
+}
+need()
+{
+int texlin, horlin, i;
+for(texlin=horlin=i=0; i<nlin; i++)
+ {
+ if (fullbot[i]!=0)
+ horlin++;
+ else
+ if (instead[i]!=0)
+ continue;
+ else
+ texlin++;
+ }
+fprintf(tabout, ".ne %dv+%dp\n",texlin,2*horlin);
+}
+deftail()
+{
+int i, c, lf, lwid;
+for(i=0; i<MAXHEAD; i++)
+ if (linestop[i])
+ fprintf(tabout, ".nr #%c 0-1\n", linestop[i]+'a'-1);
+fprintf(tabout, ".nr #a 0-1\n");
+fprintf(tabout, ".eo\n");
+fprintf(tabout, ".de T#\n");
+fprintf(tabout, ".ds #d .d\n");
+fprintf(tabout, ".if \\(ts\\n(.z\\(ts\\(ts .ds #d nl\n");
+ fprintf(tabout, ".mk ##\n");
+ fprintf(tabout, ".nr ## -1v\n");
+ fprintf(tabout, ".ls 1\n");
+ for(i=0; i<MAXHEAD; i++)
+ if (linestop[i])
+ fprintf(tabout, ".if \\n(#T>=0 .nr #%c \\n(#T\n",linestop[i]+'a'-1);
+if (boxflg || allflg || dboxflg) /* bottom of table line */
+ if (fullbot[nlin-1]==0)
+ {
+ if (!pr1403)
+ fprintf(tabout, ".if \\n(T. .vs \\n(.vu-\\n(.sp\n");
+ fprintf(tabout, ".if \\n(T. ");
+ drawline(nlin,0,ncol, dboxflg ? '=' : '-',1,0);
+ fprintf(tabout, "\n.if \\n(T. .vs\n");
+ /* T. is really an argument to a macro but because of
+ eqn we don't dare pass it as an argument and reference by $1 */
+ }
+ for(c=0; c<ncol; c++)
+ {
+ if ((lf=left(nlin-1,c, &lwid))>=0)
+ {
+ fprintf(tabout, ".if \\n(#%c>=0 .sp -1\n",linestop[lf]+'a'-1);
+ fprintf(tabout, ".if \\n(#%c>=0 ", linestop[lf]+'a'-1);
+ tohcol(c);
+ drawvert(lf, nlin-1, c, lwid);
+ fprintf(tabout, "\\h'|\\n(TWu'\n");
+ }
+ }
+ if (boxflg || allflg || dboxflg) /* right hand line */
+ {
+ fprintf(tabout, ".if \\n(#a>=0 .sp -1\n");
+ fprintf(tabout, ".if \\n(#a>=0 \\h'|\\n(TWu'");
+ drawvert (0, nlin-1, ncol, dboxflg? 2 : 1);
+ fprintf(tabout, "\n");
+ }
+fprintf(tabout, ".ls\n");
+fprintf(tabout, "..\n");
+fprintf(tabout, ".ec\n");
+}
--- /dev/null
+ /* t9.c: write lines for tables over 200 lines */
+# include "t..c"
+static useln;
+yetmore()
+{
+for(useln=0; useln<MAXLIN && table[useln]==0; useln++);
+if (useln>=MAXLIN)
+ error("Wierd. No data in table.");
+table[0]=table[useln];
+for(useln=nlin-1; useln>=0 && (fullbot[useln] || instead[useln]); useln--);
+if (useln<0)
+ error("Wierd. No real lines in table.");
+domore(leftover);
+while (gets1(cstore=cspace) && domore(cstore))
+ ;
+last =cstore;
+return;
+}
+domore(dataln)
+ char *dataln;
+{
+ int icol, ch;
+if (prefix(".TE", dataln))
+ return(0);
+if (dataln[0] == '.' && !isdigit(dataln[1]))
+ {
+ puts(dataln);
+ return(1);
+ }
+instead[0]=fullbot[0]=0;
+if (dataln[1]==0)
+switch(dataln[0])
+ {
+ case '_': fullbot[0]= '-'; putline(useln,0); return(1);
+ case '=': fullbot[0]= '='; putline(useln, 0); return(1);
+ }
+for (icol = 0; icol <ncol; icol++)
+ {
+ table[0][icol].col = dataln;
+ table[0][icol].rcol=0;
+ for(; (ch= *dataln) != '\0' && ch != tab; dataln++)
+ ;
+ *dataln++ = '\0';
+ switch(ctype(useln,icol))
+ {
+ case 'n':
+ table[0][icol].rcol = maknew(table[0][icol].col);
+ break;
+ case 'a':
+ table[0][icol].rcol = table[0][icol].col;
+ table[0][icol].col= "";
+ break;
+ }
+ while (ctype(useln,icol+1)== 's') /* spanning */
+ table[0][++icol].col = "";
+ if (ch == '\0') break;
+ }
+while (++icol <ncol)
+ table[0][icol].col = "";
+putline(useln,0);
+return(1);
+}
--- /dev/null
+ /* tc.c: find character not in table to delimit fields */
+# include "t..c"
+choochar()
+{
+/* choose funny characters to delimit fields */
+int had[128], ilin,icol, k;
+char *s;
+for(icol=0; icol<128; icol++)
+ had[icol]=0;
+F1 = F2 = 0;
+for(ilin=0;ilin<nlin;ilin++)
+ {
+ if (instead[ilin]) continue;
+ if (fullbot[ilin]) continue;
+ for(icol=0; icol<ncol; icol++)
+ {
+ k = ctype(ilin, icol);
+ if (k==0 || k == '-' || k == '=')
+ continue;
+ s = table[ilin][icol].col;
+ if (point(s))
+ while (*s)
+ had[*s++]=1;
+ s=table[ilin][icol].rcol;
+ if (point(s))
+ while (*s)
+ had[*s++]=1;
+ }
+ }
+/* choose first funny character */
+for(
+ s="\002\003\005\006\007!%&#/?,:;<=>@`^~_{}+-*ABCDEFGHIJKMNOPQRSTUVWXYZabcdefgjkoqrstwxyz";
+ *s; s++)
+ {
+ if (had[*s]==0)
+ {
+ F1= *s;
+ had[F1]=1;
+ break;
+ }
+ }
+/* choose second funny character */
+for(
+ s="\002\003\005\006\007:_~^`@;,<=>#%&!/?{}+-*ABCDEFGHIJKMNOPQRSTUVWXZabcdefgjkoqrstuwxyz";
+ *s; s++)
+ {
+ if (had[*s]==0)
+ {
+ F2= *s;
+ break;
+ }
+ }
+if (F1==0 || F2==0)
+ error("couldn't find characters to use for delimiters");
+return;
+}
+point(s)
+{
+return(s>= 128 || s<0);
+}
--- /dev/null
+ /* te.c: error message control, input line count */
+# include "t..c"
+error(s)
+ char *s;
+{
+fprintf(stderr, "\n%s: line %d: %s\n", ifile, iline, s);
+# ifdef unix
+fprintf(stderr, "tbl quits\n");
+exit(1);
+# endif
+# ifdef gcos
+fprintf(stderr, "run terminated due to error condition detected by tbl preprocessor\n");
+exit(0);
+# endif
+}
+gets1(s)
+ char *s;
+{
+char *p;
+int nbl = 0;
+iline++;
+p=fgets(s,512,tabin);
+while (p==0)
+ {
+ if (swapin()==0)
+ return(0);
+ p = fgets(s,512,tabin);
+ }
+
+while (*s) s++;
+s--;
+if (*s == '\n') *s-- =0;
+for(nbl=0; *s == '\\' && s>p; s--)
+ nbl++;
+if (linstart && nbl % 2) /* fold escaped nl if in table */
+ gets1(s+1);
+
+return(p);
+}
+# define BACKMAX 500
+char backup[BACKMAX];
+char *backp = backup;
+un1getc(c)
+{
+if (c=='\n')
+ iline--;
+*backp++ = c;
+if (backp >= backup+BACKMAX)
+ error("too much backup");
+}
+get1char()
+{
+int c;
+if (backp>backup)
+ c = *--backp;
+else
+ c=getc(tabin);
+if (c== EOF) /* EOF */
+ {
+ if (swapin() ==0)
+ error("unexpected EOF");
+ c = getc(tabin);
+ }
+if (c== '\n')
+ iline++;
+return(c);
+}
--- /dev/null
+ /* tf.c: save and restore fill mode around table */
+# include "t..c"
+savefill()
+{
+/* remembers various things: fill mode, vs, ps in mac 35 (SF) */
+fprintf(tabout, ".de %d\n",SF);
+fprintf(tabout, ".ps \\n(.s\n");
+fprintf(tabout, ".vs \\n(.vu\n");
+fprintf(tabout, ".in \\n(.iu\n");
+fprintf(tabout, ".if \\n(.u .fi\n");
+fprintf(tabout, ".if \\n(.j .ad\n");
+fprintf(tabout, ".if \\n(.j=0 .na\n");
+fprintf(tabout, "..\n");
+fprintf(tabout, ".nf\n");
+/* set obx offset if useful */
+fprintf(tabout, ".nr #~ 0\n");
+fprintf(tabout, ".if n .nr #~ 0.6n\n");
+}
+rstofill()
+{
+fprintf(tabout, ".%d\n",SF);
+}
+endoff()
+{
+int i;
+ for(i=0; i<MAXHEAD; i++)
+ if (linestop[i])
+ fprintf(tabout, ".nr #%c 0\n", 'a'+i);
+ for(i=0; i<texct; i++)
+ fprintf(tabout, ".rm %c+\n",texstr[i]);
+fprintf(tabout, "%s\n", last);
+}
+ifdivert()
+{
+fprintf(tabout, ".ds #d .d\n");
+fprintf(tabout, ".if \\(ts\\n(.z\\(ts\\(ts .ds #d nl\n");
+}
+saveline()
+{
+fprintf(tabout, ".if \\n+(b.=1 .nr d. \\n(.c-\\n(c.-1\n");
+linstart=iline;
+}
+restline()
+{
+fprintf(tabout,".if \\n-(b.=0 .nr c. \\n(.c-\\n(d.-%d\n", iline-linstart);
+linstart = 0;
+}
+cleanfc()
+{
+fprintf(tabout, ".fc\n");
+}
--- /dev/null
+ /* tg.c: process included text blocks */
+# include "t..c"
+gettext(sp, ilin,icol, fn, sz)
+ char *sp, *fn, *sz;
+{
+/* get a section of text */
+char line[256];
+int oname;
+char *vs;
+if (texname==0) error("Too many text block diversions");
+if (textflg==0)
+ {
+ fprintf(tabout, ".nr %d \\n(.lu\n", SL); /* remember old line length */
+ textflg=1;
+ }
+fprintf(tabout, ".eo\n");
+fprintf(tabout, ".am %02d\n", icol+80);
+fprintf(tabout, ".br\n");
+fprintf(tabout, ".di %c+\n", texname);
+rstofill();
+if (fn && *fn) fprintf(tabout, ".nr %d \\n(.f\n.ft %s\n", S1, fn);
+fprintf(tabout, ".ft \\n(.f\n"); /* protect font */
+vs = vsize[stynum[ilin]][icol];
+if ((sz && *sz) || (vs && *vs))
+ {
+ fprintf(tabout, ".nr %d \\n(.v\n", S2);
+ if (vs==0 || *vs==0) vs= "\\n(.s+2";
+ if (sz && *sz)
+ fprintf(tabout, ".ps %s\n",sz);
+ fprintf(tabout, ".vs %s\n",vs);
+ fprintf(tabout, ".if \\n(%du>\\n(.vu .sp \\n(%du-\\n(.vu\n", S2,S2);
+ }
+if (cll[icol][0])
+ fprintf(tabout, ".ll %sn\n", cll[icol]);
+else
+ fprintf(tabout, ".ll \\n(%du*%du/%du\n",SL,ctspan(ilin,icol),ncol+1);
+fprintf(tabout,".if \\n(.l<\\n(%d .ll \\n(%du\n", icol+CRIGHT, icol+CRIGHT);
+if (ctype(ilin,icol)=='a')
+ fprintf(tabout, ".ll -2n\n");
+fprintf(tabout, ".in 0\n");
+while (gets1(line))
+ {
+ if (line[0]=='T' && line[1]=='}' && line[2]== tab) break;
+ if (match("T}", line)) break;
+ fprintf(tabout, "%s\n", line);
+ }
+if (fn && *fn) fprintf(tabout, ".ft \\n(%d\n", S1);
+if (sz && *sz) fprintf(tabout, ".br\n.ps\n.vs\n");
+fprintf(tabout, ".br\n");
+fprintf(tabout, ".di\n");
+fprintf(tabout, ".nr %c| \\n(dn\n", texname);
+fprintf(tabout, ".nr %c- \\n(dl\n", texname);
+fprintf(tabout, "..\n");
+fprintf(tabout, ".ec \\\n");
+/* copy remainder of line */
+if (line[2])
+ tcopy (sp, line+3);
+else
+ *sp=0;
+oname=texname;
+texname = texstr[++texct];
+return(oname);
+}
+untext()
+{
+rstofill();
+fprintf(tabout, ".nf\n");
+fprintf(tabout, ".ll \\n(%du\n", SL);
+}
--- /dev/null
+ /* ti.c: classify line intersections */
+# include "t..c"
+/* determine local environment for intersections */
+interv(i,c)
+{
+int ku, kl;
+if (c>=ncol || c == 0)
+ {
+ if (dboxflg)
+ {
+ if (i==0) return(BOT);
+ if (i>=nlin) return(TOP);
+ return(THRU);
+ }
+ if (c>=ncol)
+ return(0);
+ }
+ku = i>0 ? lefdata(i-1,c) : 0;
+if (i+1 >= nlin)
+ kl=0;
+else
+kl = lefdata(allh(i) ? i+1 : i, c);
+if (ku==2 && kl==2) return(THRU);
+if (ku ==2) return(TOP);
+if (kl==BOT) return(2);
+return(0);
+}
+interh(i,c)
+{
+int kl, kr;
+if (fullbot[i]== '=' || (dboxflg && (i==0 || i>= nlin-1)))
+ {
+ if (c==ncol)
+ return(LEFT);
+ if (c==0)
+ return(RIGHT);
+ return(THRU);
+ }
+if (i>=nlin) return(0);
+kl = c>0 ? thish (i,c-1) : 0;
+if (kl<=1 && i>0 && allh(up1(i)))
+ kl = c>0 ? thish(up1(i),c-1) : 0;
+kr = thish(i,c);
+if (kr<=1 && i>0 && allh(up1(i)))
+ kr = c>0 ? thish(up1(i), c) : 0;
+if (kl== '=' && kr == '=') return(THRU);
+if (kl== '=') return(LEFT);
+if (kr== '=') return(RIGHT);
+return(0);
+}
+up1(i)
+{
+i--;
+while (instead[i] && i>0) i--;
+return(i);
+}
--- /dev/null
+ /* tm.c: split numerical fields */
+# include "t..c"
+maknew(str)
+ char *str;
+{
+ /* make two numerical fields */
+ int dpoint, c;
+ char *p, *q, *ba;
+ p = str;
+ for (ba= 0; c = *str; str++)
+ if (c == '\\' && *(str+1)== '&')
+ ba=str;
+ str=p;
+ if (ba==0)
+ {
+ for (dpoint=0; *str; str++)
+ {
+ if (*str=='.' && !ineqn(str,p) &&
+ (str>p && digit(*(str-1)) ||
+ digit(*(str+1))))
+ dpoint=str;
+ }
+ if (dpoint==0)
+ for(; str>p; str--)
+ {
+ if (digit( * (str-1) ) && !ineqn(str, p))
+ break;
+ }
+ if (!dpoint && p==str) /* not numerical, don't split */
+ return(0);
+ if (dpoint) str=dpoint;
+ }
+ else
+ str = ba;
+ p =str;
+ if (exstore ==0 || exstore >exlim)
+ {
+ exstore = chspace();
+ exlim= exstore+MAXCHS;
+ }
+ q = exstore;
+ while (*exstore++ = *str++);
+ *p = 0;
+ return(q);
+ }
+ineqn (s, p)
+ char *s, *p;
+{
+/* true if s is in a eqn within p */
+int ineq = 0, c;
+while (c = *p)
+ {
+ if (s == p)
+ return(ineq);
+ p++;
+ if ((ineq == 0) && (c == delim1))
+ ineq = 1;
+ else
+ if ((ineq == 1) && (c == delim2))
+ ineq = 0;
+ }
+return(0);
+}
--- /dev/null
+ /* ts.c: minor string processing subroutines */
+match (s1, s2)
+ char *s1, *s2;
+{
+ while (*s1 == *s2)
+ if (*s1++ == '\0')
+ return(1);
+ else
+ s2++;
+ return(0);
+}
+prefix(small, big)
+ char *small, *big;
+{
+int c;
+while ((c= *small++) == *big++)
+ if (c==0) return(1);
+return(c==0);
+}
+letter (ch)
+ {
+ if (ch >= 'a' && ch <= 'z')
+ return(1);
+ if (ch >= 'A' && ch <= 'Z')
+ return(1);
+ return(0);
+ }
+numb(str)
+ char *str;
+ {
+ /* convert to integer */
+ int k;
+ for (k=0; *str >= '0' && *str <= '9'; str++)
+ k = k*10 + *str - '0';
+ return(k);
+ }
+digit(x)
+ {
+ return(x>= '0' && x<= '9');
+ }
+max(a,b)
+{
+return( a>b ? a : b);
+}
+tcopy (s,t)
+ char *s, *t;
+{
+ while (*s++ = *t++);
+}
--- /dev/null
+ /* tt.c: subroutines for drawing horizontal lines */
+# include "t..c"
+ctype(il, ic)
+{
+if (instead[il])
+ return(0);
+if (fullbot[il])
+ return(0);
+il = stynum[il];
+return(style[il][ic]);
+}
+min(a,b)
+{
+return(a<b ? a : b);
+}
+fspan(i,c)
+{
+c++;
+return(c<ncol && ctype(i,c)=='s');
+}
+lspan(i,c)
+{
+int k;
+if (ctype(i,c) != 's') return(0);
+c++;
+if (c < ncol && ctype(i,c)== 's')
+ return(0);
+for(k=0; ctype(i,--c) == 's'; k++);
+return(k);
+}
+ctspan(i,c)
+{
+int k;
+c++;
+for(k=1; c<ncol && ctype(i,c)=='s'; k++)
+ c++;
+return(k);
+}
+tohcol(ic)
+{
+ if (ic==0)
+ fprintf(tabout, "\\h'|0'");
+ else
+ fprintf(tabout, "\\h'(|\\n(%du+|\\n(%du)/2u'", ic+CLEFT, ic+CRIGHT-1);
+}
+allh(i)
+{
+/* return true if every element in line i is horizontal */
+/* also at least one must be horizontl */
+int c, one, k;
+if (fullbot[i]) return(1);
+for(one=c=0; c<ncol; c++)
+ {
+ k = thish(i,c);
+ if (k==0) return(0);
+ if (k==1) continue;
+ one=1;
+ }
+return(one);
+}
+thish(i,c)
+{
+ int t;
+ char *s;
+ struct colstr *pc;
+ if (c<0)return(0);
+ if (i<0) return(0);
+ t = ctype(i,c);
+ if (t=='_' || t == '-')
+ return('-');
+ if (t=='=')return('=');
+ if (t=='^') return(1);
+ if (fullbot[i] )
+ return(fullbot[i]);
+ if (t=='s') return(thish(i,c-1));
+ if (t==0) return(1);
+ pc = &table[i][c];
+ s = (t=='a' ? pc->rcol : pc->col);
+ if (s==0 || (point(s) && *s==0))
+ return(1);
+ if (vspen(s)) return(1);
+ if (t=barent( s))
+ return(t);
+ return(0);
+}
--- /dev/null
+ /* tu.c: draws horizontal lines */
+# include "t..c"
+makeline(i,c,lintype)
+{
+int cr, type, shortl;
+type = thish(i,c);
+if (type==0) return;
+cr=c;
+shortl = (table[i][c].col[0]=='\\');
+if (c>0 && !shortl && thish(i,c-1) == type)return;
+if (shortl==0)
+ for(cr=c; cr < ncol && (ctype(i,cr)=='s'||type==thish(i,cr)); cr++);
+else
+ for(cr=c+1; cr<ncol && ctype(i,cr)=='s'; cr++);
+drawline(i, c, cr-1, lintype, 0, shortl);
+}
+fullwide(i, lintype)
+{
+int cr, cl;
+if (!pr1403)
+ fprintf(tabout, ".nr %d \\n(.v\n.vs \\n(.vu-\\n(.sp\n", SVS);
+cr= 0;
+while (cr<ncol)
+ {
+ cl=cr;
+ while (i>0 && vspand(prev(i),cl,1))
+ cl++;
+ for(cr=cl; cr<ncol; cr++)
+ if (i>0 && vspand(prev(i),cr,1))
+ break;
+ if (cl<ncol)
+ drawline(i,cl,(cr<ncol?cr-1:cr),lintype,1,0);
+ }
+fprintf(tabout, "\n");
+if (!pr1403)
+ fprintf(tabout, ".vs \\n(%du\n", SVS);
+}
+
+drawline(i, cl, cr, lintype, noheight, shortl)
+{
+ char *exhr, *exhl;
+ int lcount, ln, linpos, oldpos, nodata, lnch;
+lcount=0;
+exhr=exhl= "";
+switch(lintype)
+ {
+ case '-': lcount=1;break;
+ case '=': lcount = pr1403? 1 : 2; break;
+ case SHORTLINE: lcount=1; break;
+ }
+if (lcount<=0) return;
+nodata = cr-cl>=ncol || noheight || allh(i);
+ if (!nodata)
+ fprintf(tabout, "\\v'-.5m'");
+for(ln=oldpos=0; ln<lcount; ln++)
+ {
+ linpos = 2*ln - lcount +1;
+ if (linpos != oldpos)
+ fprintf(tabout, "\\v'%dp'", linpos-oldpos);
+ oldpos=linpos;
+ if (shortl==0)
+ {
+ tohcol(cl);
+ if (lcount>1)
+ {
+ switch(interv(i,cl))
+ {
+ case TOP: exhl = ln==0 ? "1p" : "-1p"; break;
+ case BOT: exhl = ln==1 ? "1p" : "-1p"; break;
+ case THRU: exhl = "1p"; break;
+ }
+ if (exhl[0])
+ fprintf(tabout, "\\h'%s'", exhl);
+ }
+ else if (lcount==1)
+ {
+ switch(interv(i,cl))
+ {
+ case TOP: case BOT: exhl = "-1p"; break;
+ case THRU: exhl = "1p"; break;
+ }
+ if (exhl[0])
+ fprintf(tabout, "\\h'%s'", exhl);
+ }
+ if (lcount>1)
+ {
+ switch(interv(i,cr+1))
+ {
+ case TOP: exhr = ln==0 ? "-1p" : "+1p"; break;
+ case BOT: exhr = ln==1 ? "-1p" : "+1p"; break;
+ case THRU: exhr = "-1p"; break;
+ }
+ }
+ else if (lcount==1)
+ {
+ switch(interv(i,cr+1))
+ {
+ case TOP: case BOT: exhr = "+1p"; break;
+ case THRU: exhr = "-1p"; break;
+ }
+ }
+ }
+ else
+ fprintf(tabout, "\\h'|\\n(%du'", cl+CLEFT);
+ fprintf(tabout, "\\s\\n(%d",LSIZE);
+ if (linsize)
+ fprintf(tabout, "\\v'-\\n(%dp/6u'", LSIZE);
+ if (shortl)
+ fprintf(tabout, "\\l'|\\n(%du'", cr+CRIGHT);
+ else
+ {
+ lnch = "\\(ul";
+ if (pr1403)
+ lnch = lintype==2 ? "=" : "\\(ru";
+ if (cr+1>=ncol)
+ fprintf(tabout, "\\l'|\\n(TWu%s%s'", exhr,lnch);
+ else
+ fprintf(tabout, "\\l'(|\\n(%du+|\\n(%du)/2u%s%s'", cr+CRIGHT,
+ cr+1+CLEFT, exhr, lnch);
+ }
+ if (linsize)
+ fprintf(tabout, "\\v'\\n(%dp/6u'", LSIZE);
+ fprintf(tabout, "\\s0");
+ }
+if (oldpos!=0)
+ fprintf(tabout, "\\v'%dp'", -oldpos);
+if (!nodata)
+ fprintf(tabout, "\\v'+.5m'");
+}
+getstop()
+{
+int i,c,k,junk, stopp;
+stopp=1;
+for(i=0; i<MAXLIN; i++)
+ linestop[i]=0;
+for(i=0; i<nlin; i++)
+ for(c=0; c<ncol; c++)
+ {
+ k = left(i,c,&junk);
+ if (k>=0 && linestop[k]==0)
+ linestop[k]= ++stopp;
+ }
+if (boxflg || allflg || dboxflg)
+ linestop[0]=1;
+}
+left(i,c, lwidp)
+ int *lwidp;
+{
+int kind, li, lj;
+ /* returns -1 if no line to left */
+ /* returns number of line where it starts */
+ /* stores into lwid the kind of line */
+*lwidp=0;
+kind = lefdata(i,c);
+if (kind==0) return(-1);
+if (i+1<nlin)
+if (lefdata(next(i),c)== kind) return(-1);
+while (i>=0 && lefdata(i,c)==kind)
+ i=prev(li=i);
+if (prev(li)== -1) li=0;
+*lwidp=kind;
+for(lj= i+1; lj<li; lj++)
+ if (instead[lj] && strcmp(instead[lj], ".TH")==0)
+ return(li);
+for(i= i+1; i<li; i++)
+ if (fullbot[i])
+ li=i;
+return(li);
+}
+lefdata(i,c)
+{
+int ck;
+if (i>=nlin) i=nlin-1;
+if (ctype(i,c) == 's')
+ {
+ for(ck=c; ctype(i,ck)=='s'; ck--);
+ if (thish(i,ck)==0)
+ return(0);
+ }
+i =stynum[i];
+i = lefline[i][c];
+if (i>0) return(i);
+if (dboxflg && c==0) return(2);
+if (allflg)return(1);
+if (boxflg && c==0) return(1);
+return(0);
+}
+next(i)
+{
+while (i+1 <nlin)
+ {
+ i++;
+ if (!fullbot[i] && !instead[i]) break;
+ }
+return(i);
+}
+prev(i)
+{
+while (--i >=0 && (fullbot[i] || instead[i]))
+ ;
+return(i);
+}