318 lines
6.1 KiB
C
318 lines
6.1 KiB
C
#
|
|
# define ever (;;)
|
|
# define MAXCHS 2000
|
|
main(argc,argv)
|
|
char *argv[];
|
|
{
|
|
char line[200];
|
|
extern int cin;
|
|
extern char *cspace;
|
|
cspace = getvec(MAXCHS + 100);
|
|
for ever
|
|
{
|
|
if (argc>1)
|
|
{
|
|
argc--;
|
|
argv++;
|
|
if (match(*argv, "-ms"))
|
|
*argv = "/usr/lib/tmac.s";
|
|
cin = copen(*argv, 'r');
|
|
if (cin < 0)
|
|
{
|
|
printf(2,"where is input file %s\n",*argv);
|
|
cexit();
|
|
}
|
|
}
|
|
while (gets(line))
|
|
if (match(line, ".TS"))
|
|
tableput();
|
|
else
|
|
puts(line);
|
|
if (argc <= 1) break;
|
|
}
|
|
cexit();
|
|
}
|
|
# define MAXCOL 35
|
|
# define MAXLIN 220
|
|
# define ONELINE 250
|
|
char *tabentry[MAXLIN][MAXCOL];
|
|
char extra[MAXCHS];
|
|
char *cspace, *cstore;
|
|
char *exstore extra;
|
|
int sep[MAXCOL], dwide[MAXCOL];
|
|
char *instead[MAXLIN];
|
|
int newtab[MAXLIN];
|
|
char *style[MAXCOL];
|
|
tableput()
|
|
{
|
|
/* read input, write output, make tables on the way */
|
|
char st[ONELINE], *format;
|
|
int ilin, nlin, icol, ncol, k, ch, ws, cs, ns;
|
|
int maxchnge, ct;
|
|
printf(".TS\n");
|
|
/* get command line */
|
|
cstore = cspace;
|
|
exstore = extra;
|
|
ncol = 0;
|
|
for (ilin=0; ilin<MAXLIN; ilin++)
|
|
newtab[ilin]=0;
|
|
gets (st);
|
|
for (k=0; k<ONELINE && st[k] != '\0'; k++)
|
|
if (!space(st[k]))
|
|
{
|
|
style[ncol] = st+k;
|
|
dwide[ncol] =0;
|
|
for(; letter(st[k]); k++)
|
|
{
|
|
if ((st[k]=='n' || st[k] == 'N') &&
|
|
!dwide[ncol])
|
|
{
|
|
dwide[ncol]=1;
|
|
sep[ncol++] = 0;
|
|
style[ncol] = style[ncol-1];
|
|
dwide [ncol] = 0;
|
|
}
|
|
}
|
|
if (digit(st[k]))
|
|
sep[ncol] = numb(st+k);
|
|
else
|
|
sep[ncol] = 3;
|
|
ncol++;
|
|
while (digit(st[k]))
|
|
st[k++] = '\0';
|
|
if (st[k] == '\0')
|
|
break;
|
|
st[k] = '\0';
|
|
}
|
|
/* now get input lines */
|
|
for (nlin=0; gets(cstore) && !match(cstore, ".TE"); nlin++)
|
|
{
|
|
if (cstore[0] == '.' && letter(cstore[1]))
|
|
{
|
|
instead[nlin] = cstore;
|
|
while (*cstore) cstore++;
|
|
}
|
|
else instead[nlin] = 0;
|
|
for (icol = 0; icol <ncol; icol++)
|
|
{
|
|
tabentry[nlin][icol] = cstore;
|
|
for(; (ch= *cstore) != '\0' && ch != '\t'; cstore++)
|
|
;
|
|
*cstore++ = '\0';
|
|
if (dwide[icol] )
|
|
if (broken(style[icol],nlin))
|
|
{
|
|
tabentry[nlin][icol+1]=maknew(tabentry[nlin][icol]);
|
|
icol++;
|
|
if (tabentry[nlin][icol] ==0)
|
|
newtab[nlin]=newtab[nlin+1]=1;
|
|
}
|
|
else
|
|
tabentry[nlin][++icol] = 0;
|
|
while (span(style[icol+1],nlin) )
|
|
tabentry[nlin][++icol] = "";
|
|
if (ch == '\0') break;
|
|
}
|
|
while (++icol <ncol)
|
|
tabentry[nlin][icol] = "";
|
|
while (*cstore != '\0')
|
|
*cstore++;
|
|
if (cstore-cspace > MAXCHS)
|
|
cstore = cspace = getvec(MAXCHS+100);
|
|
}
|
|
/* find longest command string */
|
|
for (icol=maxchnge=0; icol<ncol; icol++)
|
|
if (slen(style[icol]) >maxchnge)
|
|
maxchnge = slen(style[icol]);
|
|
/* set tab stops */
|
|
printf(".nr 49 0\n");
|
|
for (icol = 0; icol<ncol; icol++)
|
|
{
|
|
ct = 1 + (icol>0 ? sep[icol-1] : 0);
|
|
printf(".nr %2d 0\n", icol+50);
|
|
for (ilin=0; ilin < nlin; ilin++)
|
|
{
|
|
if (icol>0 && dwide[icol-1]>0 && tabentry[ilin][icol]==0)
|
|
{
|
|
printf(".nr 48 \\n(%2d+\\w'%s'+%dn\n",
|
|
icol+48, tabentry[ilin][icol-1], sep[icol-1]);
|
|
printf(".if \\n(48-\\n(%2d .nr %2d \\n(48\n",
|
|
icol+50,icol+50);
|
|
}
|
|
if ( !span(style[icol],ilin) && /* not part of span */
|
|
(dwide[icol] == 0 || tabentry[ilin][icol+1]!= 0)
|
|
/* not a double item */
|
|
&& (!span(style[icol+1],ilin) || icol==ncol))
|
|
{
|
|
printf(".nr 47 \\n(%2d+\\w'%s'+%dn\n",
|
|
icol+49,tabentry[ilin][icol], ct);
|
|
printf(".if \\n(47-\\n(%2d .nr %2d \\n(47\n",
|
|
icol+50,icol+50);
|
|
}
|
|
}
|
|
/* clean up spanned headings */
|
|
for(ilin=0; ilin<maxchnge; ilin++)
|
|
{
|
|
if( !(span(style[icol],ilin)) &&
|
|
(icol ==1 || dwide[icol-1] == 0) &&
|
|
span(style[icol+(dwide[icol]?2:1)],ilin))
|
|
printf(".nr %d \\n(%2d+\\w'%s'+%dn\n",
|
|
ilin+30, icol+49, tabentry[ilin][icol], ct);
|
|
else if (span(style[icol],ilin) &&
|
|
(icol+1==ncol || !span(style[icol+1],ilin)))
|
|
printf(".if \\n(%d-\\n(%d .nr %d \\n(%d\n",
|
|
30+ilin, icol+50, icol+50, ilin+30);
|
|
}
|
|
}
|
|
/* run out table, put field characters in */
|
|
printf (".fc @\n");
|
|
for (ilin=0; ilin<nlin; ilin++)
|
|
{
|
|
if (instead[ilin])
|
|
{
|
|
printf("%s\n",instead[ilin]);
|
|
continue;
|
|
}
|
|
/* is a new set of tab stops needed */
|
|
if (ilin < maxchnge || newtab[ilin])
|
|
settab(ncol, ilin);
|
|
for (icol=0; icol<ncol; icol++)
|
|
{
|
|
switch ( ylet(style[icol],ilin))
|
|
{
|
|
default:
|
|
case 'L': case 'l':
|
|
format = "%s@"; break;
|
|
case 'R': case 'r':
|
|
format= "@%s"; break;
|
|
case 'n': case 'N':
|
|
if (!dwide[icol] || tabentry[ilin][icol+1] != 0)
|
|
{
|
|
format=dwide[icol]? "@%s" : "%s@";
|
|
break;
|
|
}
|
|
case 'c': case 'C':
|
|
format = "@%s@"; break;
|
|
case 's': case 'S':
|
|
format= "";
|
|
break;
|
|
}
|
|
if (! (dwide [icol-1]>0 && tabentry[ilin][icol] == 0 ))
|
|
printf(format, tabentry[ilin][icol]);
|
|
if (!span(style[icol+1],ilin))
|
|
for (k=sep[icol]; k>0; k--)
|
|
printf(" ");
|
|
}
|
|
printf("\n");
|
|
}
|
|
printf(".fc\n");
|
|
printf(".TE\n");
|
|
}
|
|
match (s1, s2)
|
|
char *s1, *s2;
|
|
{
|
|
while (*s1 == *s2)
|
|
if (*s1++ == '\0')
|
|
return(1);
|
|
else
|
|
*s2++;
|
|
return(0);
|
|
}
|
|
slen(str)
|
|
char *str;
|
|
{
|
|
int k;
|
|
for (k=0; *str++ != '\0'; k++);
|
|
return(k);
|
|
}
|
|
space(ch)
|
|
{
|
|
switch (ch)
|
|
{
|
|
case ' ': case '\t':
|
|
return(1);
|
|
}
|
|
return(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);
|
|
}
|
|
broken(str, nlin)
|
|
{
|
|
switch(ylet(str,nlin))
|
|
{
|
|
case 'n': case 'N':
|
|
return(1);
|
|
}
|
|
return(0);
|
|
}
|
|
ylet (str, k)
|
|
char *str;
|
|
{
|
|
k++;
|
|
while (*str &&k--)
|
|
str++;
|
|
return(*--str);
|
|
}
|
|
span(str, k)
|
|
{
|
|
switch(ylet(str,k))
|
|
{
|
|
case 's': case 'S':
|
|
return(1);
|
|
}
|
|
return(0);
|
|
}
|
|
maknew(str)
|
|
char *str;
|
|
{
|
|
/* make two numerical fields */
|
|
int point;
|
|
char *p, *q;
|
|
p = str;
|
|
for (point=0; *str; str++)
|
|
if (*str=='.')
|
|
point=1;
|
|
if (!point && *(str-1)== '$')
|
|
return(0);
|
|
for(; str>p; str--)
|
|
if ( (point && *str == '.') ||
|
|
(!point && digit(*(str-1)) ) )
|
|
break;
|
|
if (!point && p==str) /* not numerical, don't split */
|
|
return(0);
|
|
p= str;
|
|
q = exstore;
|
|
while (*exstore++ = *str++);
|
|
*p = 0;
|
|
return(q);
|
|
}
|
|
digit(x)
|
|
{
|
|
return(x>= '0' && x<= '9');
|
|
}
|
|
settab(ncol, ilin)
|
|
{
|
|
int k, icol;
|
|
printf(".ta ");
|
|
for (icol = 0; icol<ncol; icol++)
|
|
if ((dwide[icol] == 0 || tabentry[ilin][icol+1] != 0)
|
|
&& !span(style[icol+1],ilin))
|
|
printf("\\n(%du ",icol+50);
|
|
printf("\n");
|
|
}
|