13e12c5d1SDavid du Colombier #include "e.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier #define MAXLINE 3600 /* maximum input line */
43e12c5d1SDavid du Colombier
53e12c5d1SDavid du Colombier char *version = "version Oct 24, 1991";
63e12c5d1SDavid du Colombier
7*9f2726c3SDavid du Colombier char in[MAXLINE+1]; /* input buffer */
83e12c5d1SDavid du Colombier int noeqn;
93e12c5d1SDavid du Colombier char *cmdname;
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier int yyparse(void);
123e12c5d1SDavid du Colombier void settype(char *);
133e12c5d1SDavid du Colombier int getdata(void);
143e12c5d1SDavid du Colombier int getline(char *);
15824682f6SDavid du Colombier void inlineeq(void);
163e12c5d1SDavid du Colombier void init(void);
173e12c5d1SDavid du Colombier void init_tbl(void);
183e12c5d1SDavid du Colombier
193e12c5d1SDavid du Colombier void
main(int argc,char * argv[])203e12c5d1SDavid du Colombier main(int argc, char *argv[])
213e12c5d1SDavid du Colombier {
223e12c5d1SDavid du Colombier char *p, buf[20];
233e12c5d1SDavid du Colombier
243e12c5d1SDavid du Colombier cmdname = argv[0];
253e12c5d1SDavid du Colombier if (p = getenv("TYPESETTER"))
263e12c5d1SDavid du Colombier typesetter = p;
273e12c5d1SDavid du Colombier while (argc > 1 && argv[1][0] == '-') {
283e12c5d1SDavid du Colombier switch (argv[1][1]) {
293e12c5d1SDavid du Colombier
303e12c5d1SDavid du Colombier case 'd':
313e12c5d1SDavid du Colombier if (argv[1][2] == '\0') {
323e12c5d1SDavid du Colombier dbg++;
333e12c5d1SDavid du Colombier printf("...\teqn %s\n", version);
343e12c5d1SDavid du Colombier } else {
353e12c5d1SDavid du Colombier lefteq = argv[1][2];
363e12c5d1SDavid du Colombier righteq = argv[1][3];
373e12c5d1SDavid du Colombier }
383e12c5d1SDavid du Colombier break;
393e12c5d1SDavid du Colombier case 's': szstack[0] = gsize = atoi(&argv[1][2]); break;
403e12c5d1SDavid du Colombier case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break;
413e12c5d1SDavid du Colombier case 'm': minsize = atoi(&argv[1][2]); break;
423e12c5d1SDavid du Colombier case 'f': strcpy(ftstack[0].name,&argv[1][2]); break;
433e12c5d1SDavid du Colombier case 'e': noeqn++; break;
443e12c5d1SDavid du Colombier case 'T': typesetter = &argv[1][2]; break;
453e12c5d1SDavid du Colombier default:
463e12c5d1SDavid du Colombier fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]);
473e12c5d1SDavid du Colombier break;
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier argc--;
503e12c5d1SDavid du Colombier argv++;
513e12c5d1SDavid du Colombier }
523e12c5d1SDavid du Colombier settype(typesetter);
533e12c5d1SDavid du Colombier sprintf(buf, "\"%s\"", typesetter);
543e12c5d1SDavid du Colombier install(deftbl, strsave(typesetter), strsave(buf), 0);
553e12c5d1SDavid du Colombier init_tbl(); /* install other keywords in tables */
563e12c5d1SDavid du Colombier curfile = infile;
573e12c5d1SDavid du Colombier pushsrc(File, curfile->fname);
583e12c5d1SDavid du Colombier if (argc <= 1) {
593e12c5d1SDavid du Colombier curfile->fin = stdin;
603e12c5d1SDavid du Colombier curfile->fname = strsave("-");
613e12c5d1SDavid du Colombier getdata();
623e12c5d1SDavid du Colombier } else
633e12c5d1SDavid du Colombier while (argc-- > 1) {
643e12c5d1SDavid du Colombier if (strcmp(*++argv, "-") == 0)
653e12c5d1SDavid du Colombier curfile->fin = stdin;
663e12c5d1SDavid du Colombier else if ((curfile->fin = fopen(*argv, "r")) == NULL)
673e12c5d1SDavid du Colombier ERROR "can't open file %s", *argv FATAL;
683e12c5d1SDavid du Colombier curfile->fname = strsave(*argv);
693e12c5d1SDavid du Colombier getdata();
703e12c5d1SDavid du Colombier if (curfile->fin != stdin)
713e12c5d1SDavid du Colombier fclose(curfile->fin);
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier exit(0);
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier
settype(char * s)763e12c5d1SDavid du Colombier void settype(char *s) /* initialize data for particular typesetter */
773e12c5d1SDavid du Colombier /* the minsize could profitably come from the */
783e12c5d1SDavid du Colombier { /* troff description file /usr/lib/font/dev.../DESC.out */
793e12c5d1SDavid du Colombier if (strcmp(s, "202") == 0)
803e12c5d1SDavid du Colombier { minsize = 5; ttype = DEV202; }
813e12c5d1SDavid du Colombier else if (strcmp(s, "aps") == 0)
823e12c5d1SDavid du Colombier { minsize = 5; ttype = DEVAPS; }
833e12c5d1SDavid du Colombier else if (strcmp(s, "cat") == 0)
843e12c5d1SDavid du Colombier { minsize = 6; ttype = DEVCAT; }
853e12c5d1SDavid du Colombier else if (strcmp(s, "post") == 0)
863e12c5d1SDavid du Colombier { minsize = 4; ttype = DEVPOST; }
873e12c5d1SDavid du Colombier else
883e12c5d1SDavid du Colombier { minsize = 5; ttype = DEV202; }
893e12c5d1SDavid du Colombier }
903e12c5d1SDavid du Colombier
getdata(void)913e12c5d1SDavid du Colombier getdata(void)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier int i, type, ln;
943e12c5d1SDavid du Colombier char fname[100];
953e12c5d1SDavid du Colombier extern int errno;
963e12c5d1SDavid du Colombier
973e12c5d1SDavid du Colombier errno = 0;
983e12c5d1SDavid du Colombier curfile->lineno = 0;
993e12c5d1SDavid du Colombier printf(".lf 1 %s\n", curfile->fname);
1003e12c5d1SDavid du Colombier while ((type = getline(in)) != EOF) {
1013e12c5d1SDavid du Colombier if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
1023e12c5d1SDavid du Colombier for (i = 11; i < 100; i++)
1033e12c5d1SDavid du Colombier used[i] = 0;
1043e12c5d1SDavid du Colombier printf("%s", in);
1053e12c5d1SDavid du Colombier if (markline) { /* turn off from last time */
1063e12c5d1SDavid du Colombier printf(".nr MK 0\n");
1073e12c5d1SDavid du Colombier markline = 0;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier display = 1;
1103e12c5d1SDavid du Colombier init();
1113e12c5d1SDavid du Colombier yyparse();
1123e12c5d1SDavid du Colombier if (eqnreg > 0) {
1133e12c5d1SDavid du Colombier if (markline)
1143e12c5d1SDavid du Colombier printf(".nr MK %d\n", markline); /* for -ms macros */
1153e12c5d1SDavid du Colombier printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht);
1163e12c5d1SDavid du Colombier printf(".rn %d 10\n", eqnreg);
1173e12c5d1SDavid du Colombier if (!noeqn)
1183e12c5d1SDavid du Colombier printf("\\&\\*(10\n");
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier printf(".EN");
1213e12c5d1SDavid du Colombier while (putchar(input()) != '\n')
1223e12c5d1SDavid du Colombier ;
1233e12c5d1SDavid du Colombier printf(".lf %d\n", curfile->lineno+1);
1243e12c5d1SDavid du Colombier }
1253e12c5d1SDavid du Colombier else if (type == lefteq)
126824682f6SDavid du Colombier inlineeq();
1273e12c5d1SDavid du Colombier else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') {
1283e12c5d1SDavid du Colombier if (sscanf(in+3, "%d %s", &ln, fname) == 2) {
1293e12c5d1SDavid du Colombier free(curfile->fname);
1303e12c5d1SDavid du Colombier printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname));
1313e12c5d1SDavid du Colombier } else
1323e12c5d1SDavid du Colombier printf(".lf %d\n", curfile->lineno = ln);
1333e12c5d1SDavid du Colombier } else
1343e12c5d1SDavid du Colombier printf("%s", in);
1353e12c5d1SDavid du Colombier }
1363e12c5d1SDavid du Colombier return(0);
1373e12c5d1SDavid du Colombier }
1383e12c5d1SDavid du Colombier
getline(char * s)1393e12c5d1SDavid du Colombier getline(char *s)
1403e12c5d1SDavid du Colombier {
1413e12c5d1SDavid du Colombier register c;
1423e12c5d1SDavid du Colombier
1433e12c5d1SDavid du Colombier while ((c=input()) != '\n' && c != EOF && c != lefteq) {
1443e12c5d1SDavid du Colombier if (s >= in+MAXLINE) {
1453e12c5d1SDavid du Colombier ERROR "input line too long: %.20s\n", in WARNING;
1463e12c5d1SDavid du Colombier in[MAXLINE] = '\0';
1473e12c5d1SDavid du Colombier break;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier *s++ = c;
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier if (c != lefteq)
1523e12c5d1SDavid du Colombier *s++ = c;
1533e12c5d1SDavid du Colombier *s = '\0';
1543e12c5d1SDavid du Colombier return(c);
1553e12c5d1SDavid du Colombier }
1563e12c5d1SDavid du Colombier
inlineeq(void)157824682f6SDavid du Colombier void inlineeq(void)
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier int ds, n, sz1 = 0;
1603e12c5d1SDavid du Colombier
1613e12c5d1SDavid du Colombier n = curfile->lineno;
1623e12c5d1SDavid du Colombier if (szstack[0] != 0)
1633e12c5d1SDavid du Colombier printf(".nr %d \\n(.s\n", sz1 = salloc());
1643e12c5d1SDavid du Colombier ds = salloc();
1653e12c5d1SDavid du Colombier printf(".rm %d \n", ds);
1663e12c5d1SDavid du Colombier display = 0;
1673e12c5d1SDavid du Colombier do {
1683e12c5d1SDavid du Colombier if (*in)
1693e12c5d1SDavid du Colombier printf(".as %d \"%s\n", ds, in);
1703e12c5d1SDavid du Colombier init();
1713e12c5d1SDavid du Colombier yyparse();
1723e12c5d1SDavid du Colombier if (eqnreg > 0) {
1733e12c5d1SDavid du Colombier printf(".as %d \\*(%d\n", ds, eqnreg);
1743e12c5d1SDavid du Colombier sfree(eqnreg);
1753e12c5d1SDavid du Colombier printf(".lf %d\n", curfile->lineno+1);
1763e12c5d1SDavid du Colombier }
1773e12c5d1SDavid du Colombier } while (getline(in) == lefteq);
1783e12c5d1SDavid du Colombier if (*in)
1793e12c5d1SDavid du Colombier printf(".as %d \"%s", ds, in);
1803e12c5d1SDavid du Colombier if (sz1)
1813e12c5d1SDavid du Colombier printf("\\s\\n(%d", sz1);
1823e12c5d1SDavid du Colombier printf("\\*(%d\n", ds);
1833e12c5d1SDavid du Colombier printf(".lf %d\n", curfile->lineno+1);
1843e12c5d1SDavid du Colombier if (curfile->lineno > n+3)
1857dd7cddfSDavid du Colombier fprintf(stderr, "eqn warning: multi-line %c...%c, file %s:%d,%d\n",
1867dd7cddfSDavid du Colombier lefteq, righteq, curfile->fname, n, curfile->lineno);
1873e12c5d1SDavid du Colombier sfree(ds);
1883e12c5d1SDavid du Colombier if (sz1) sfree(sz1);
1893e12c5d1SDavid du Colombier }
1903e12c5d1SDavid du Colombier
putout(int p1)1913e12c5d1SDavid du Colombier void putout(int p1)
1923e12c5d1SDavid du Colombier {
1933e12c5d1SDavid du Colombier double before, after;
1943e12c5d1SDavid du Colombier extern double BeforeSub, AfterSub;
1953e12c5d1SDavid du Colombier
1963e12c5d1SDavid du Colombier dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]);
1973e12c5d1SDavid du Colombier eqnht = eht[p1];
1983e12c5d1SDavid du Colombier before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */
1993e12c5d1SDavid du Colombier after = ebase[p1] - AfterSub;
2003e12c5d1SDavid du Colombier if (spaceval || before > 0.01 || after > 0.01) {
2013e12c5d1SDavid du Colombier printf(".ds %d ", p1); /* used to be \\x'0' here: why? */
2023e12c5d1SDavid du Colombier if (spaceval != NULL)
2033e12c5d1SDavid du Colombier printf("\\x'0-%s'", spaceval);
2043e12c5d1SDavid du Colombier else if (before > 0.01)
2053e12c5d1SDavid du Colombier printf("\\x'0-%gm'", before);
2063e12c5d1SDavid du Colombier printf("\\*(%d", p1);
2073e12c5d1SDavid du Colombier if (spaceval == NULL && after > 0.01)
2083e12c5d1SDavid du Colombier printf("\\x'%gm'", after);
2093e12c5d1SDavid du Colombier putchar('\n');
2103e12c5d1SDavid du Colombier }
2113e12c5d1SDavid du Colombier if (szstack[0] != 0)
2123e12c5d1SDavid du Colombier printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1);
2133e12c5d1SDavid du Colombier eqnreg = p1;
2143e12c5d1SDavid du Colombier if (spaceval != NULL) {
2153e12c5d1SDavid du Colombier free(spaceval);
2163e12c5d1SDavid du Colombier spaceval = NULL;
2173e12c5d1SDavid du Colombier }
2183e12c5d1SDavid du Colombier }
2193e12c5d1SDavid du Colombier
init(void)2203e12c5d1SDavid du Colombier void init(void)
2213e12c5d1SDavid du Colombier {
2223e12c5d1SDavid du Colombier synerr = 0;
2233e12c5d1SDavid du Colombier ct = 0;
2243e12c5d1SDavid du Colombier ps = gsize;
2253e12c5d1SDavid du Colombier ftp = ftstack;
2263e12c5d1SDavid du Colombier ft = ftp->ft;
2273e12c5d1SDavid du Colombier nszstack = 0;
2283e12c5d1SDavid du Colombier if (szstack[0] != 0) /* absolute gsize in effect */
2293e12c5d1SDavid du Colombier printf(".nr 99 \\n(.s\n");
2303e12c5d1SDavid du Colombier }
2313e12c5d1SDavid du Colombier
salloc(void)2323e12c5d1SDavid du Colombier salloc(void)
2333e12c5d1SDavid du Colombier {
2343e12c5d1SDavid du Colombier int i;
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier for (i = 11; i < 100; i++)
2373e12c5d1SDavid du Colombier if (used[i] == 0) {
2383e12c5d1SDavid du Colombier used[i]++;
2393e12c5d1SDavid du Colombier return(i);
2403e12c5d1SDavid du Colombier }
2413e12c5d1SDavid du Colombier ERROR "no eqn strings left (%d)", i FATAL;
2423e12c5d1SDavid du Colombier return(0);
2433e12c5d1SDavid du Colombier }
2443e12c5d1SDavid du Colombier
sfree(int n)2453e12c5d1SDavid du Colombier void sfree(int n)
2463e12c5d1SDavid du Colombier {
2473e12c5d1SDavid du Colombier used[n] = 0;
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier
nrwid(int n1,int p,int n2)2503e12c5d1SDavid du Colombier void nrwid(int n1, int p, int n2)
2513e12c5d1SDavid du Colombier {
2523e12c5d1SDavid du Colombier printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier
ABSPS(int dn)2553e12c5d1SDavid du Colombier char *ABSPS(int dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */
2563e12c5d1SDavid du Colombier {
2573e12c5d1SDavid du Colombier static char buf[100], *lb = buf;
2583e12c5d1SDavid du Colombier char *p;
2593e12c5d1SDavid du Colombier
2603e12c5d1SDavid du Colombier if (lb > buf + sizeof(buf) - 10)
2613e12c5d1SDavid du Colombier lb = buf;
2623e12c5d1SDavid du Colombier p = lb;
2633e12c5d1SDavid du Colombier *lb++ = '\\';
2643e12c5d1SDavid du Colombier *lb++ = 's';
2653e12c5d1SDavid du Colombier if (dn >= 10) { /* \s(dd only works in new troff */
2663e12c5d1SDavid du Colombier if (dn >= 40)
2673e12c5d1SDavid du Colombier *lb++ = '(';
2683e12c5d1SDavid du Colombier *lb++ = dn/10 + '0';
2693e12c5d1SDavid du Colombier *lb++ = dn%10 + '0';
2703e12c5d1SDavid du Colombier } else {
2713e12c5d1SDavid du Colombier *lb++ = dn + '0';
2723e12c5d1SDavid du Colombier }
2733e12c5d1SDavid du Colombier *lb++ = '\0';
2743e12c5d1SDavid du Colombier return p;
2753e12c5d1SDavid du Colombier }
2763e12c5d1SDavid du Colombier
DPS(int f,int t)2773e12c5d1SDavid du Colombier char *DPS(int f, int t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */
2783e12c5d1SDavid du Colombier {
2793e12c5d1SDavid du Colombier static char buf[100], *lb = buf;
2803e12c5d1SDavid du Colombier char *p;
2813e12c5d1SDavid du Colombier int dn;
2823e12c5d1SDavid du Colombier
2833e12c5d1SDavid du Colombier if (lb > buf + sizeof(buf) - 10)
2843e12c5d1SDavid du Colombier lb = buf;
2853e12c5d1SDavid du Colombier p = lb;
2863e12c5d1SDavid du Colombier *lb++ = '\\';
2873e12c5d1SDavid du Colombier *lb++ = 's';
2883e12c5d1SDavid du Colombier dn = EFFPS(t) - EFFPS(f);
2893e12c5d1SDavid du Colombier if (szstack[nszstack] != 0) /* absolute */
2903e12c5d1SDavid du Colombier dn = EFFPS(t); /* should do proper \s(dd */
2913e12c5d1SDavid du Colombier else if (dn >= 0)
2923e12c5d1SDavid du Colombier *lb++ = '+';
2933e12c5d1SDavid du Colombier else {
2943e12c5d1SDavid du Colombier *lb++ = '-';
2953e12c5d1SDavid du Colombier dn = -dn;
2963e12c5d1SDavid du Colombier }
2973e12c5d1SDavid du Colombier if (dn >= 10) { /* \s+(dd only works in new troff */
2983e12c5d1SDavid du Colombier *lb++ = '(';
2993e12c5d1SDavid du Colombier *lb++ = dn/10 + '0';
3003e12c5d1SDavid du Colombier *lb++ = dn%10 + '0';
3013e12c5d1SDavid du Colombier } else {
3023e12c5d1SDavid du Colombier *lb++ = dn + '0';
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier *lb++ = '\0';
3053e12c5d1SDavid du Colombier return p;
3063e12c5d1SDavid du Colombier }
3073e12c5d1SDavid du Colombier
EFFPS(int n)3083e12c5d1SDavid du Colombier EFFPS(int n) /* effective value of n */
3093e12c5d1SDavid du Colombier {
3103e12c5d1SDavid du Colombier if (n >= minsize)
3113e12c5d1SDavid du Colombier return n;
3123e12c5d1SDavid du Colombier else
3133e12c5d1SDavid du Colombier return minsize;
3143e12c5d1SDavid du Colombier }
3153e12c5d1SDavid du Colombier
EM(double m,int ps)3163e12c5d1SDavid du Colombier double EM(double m, int ps) /* convert m to ems in gsize */
3173e12c5d1SDavid du Colombier {
3183e12c5d1SDavid du Colombier m *= (double) EFFPS(ps) / gsize;
3193e12c5d1SDavid du Colombier if (m <= 0.001 && m >= -0.001)
3203e12c5d1SDavid du Colombier return 0;
3213e12c5d1SDavid du Colombier else
3223e12c5d1SDavid du Colombier return m;
3233e12c5d1SDavid du Colombier }
3243e12c5d1SDavid du Colombier
REL(double m,int ps)3253e12c5d1SDavid du Colombier double REL(double m, int ps) /* convert m to ems in ps */
3263e12c5d1SDavid du Colombier {
3273e12c5d1SDavid du Colombier m *= (double) gsize / EFFPS(ps);
3283e12c5d1SDavid du Colombier if (m <= 0.001 && m >= -0.001)
3293e12c5d1SDavid du Colombier return 0;
3303e12c5d1SDavid du Colombier else
3313e12c5d1SDavid du Colombier return m;
3323e12c5d1SDavid du Colombier }
333