123930Sjaap #ifndef lint
2*30728Sjaap static char sccsid[] = "@(#)main.c 2.4 (CWI) 87/04/01";
323930Sjaap #endif lint
423930Sjaap # include "e.h"
523930Sjaap #define MAXLINE 3600 /* maximum input line */
623930Sjaap
723930Sjaap char in[MAXLINE]; /* input buffer */
823930Sjaap int noeqn;
923930Sjaap char *cmdname;
1023930Sjaap
main(argc,argv)1123930Sjaap main(argc,argv)
1223930Sjaap int argc;
1323930Sjaap char *argv[];
1423930Sjaap {
1530727Sjaap exit(eqn(argc, argv));
1623930Sjaap }
1723930Sjaap
eqn(argc,argv)1823930Sjaap eqn(argc,argv)
1923930Sjaap int argc;
2023930Sjaap char *argv[];
2123930Sjaap {
2223930Sjaap int i, type;
2330727Sjaap char *p, *getenv(), buf[20];
2423930Sjaap
2523930Sjaap cmdname = argv[0];
2623930Sjaap if (p = getenv("TYPESETTER"))
2723930Sjaap typesetter = p;
2823930Sjaap while (argc > 1 && argv[1][0] == '-') {
2923930Sjaap switch (argv[1][1]) {
3023930Sjaap
3123930Sjaap case 'd':
3223930Sjaap if (argv[1][2] == '\0')
3323930Sjaap dbg++;
3423930Sjaap else {
3523930Sjaap lefteq = argv[1][2];
3623930Sjaap righteq = argv[1][3];
3723930Sjaap }
3823930Sjaap break;
3930727Sjaap case 's': szstack[0] = gsize = atoi(&argv[1][2]); break;
4030727Sjaap case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break;
4123930Sjaap case 'm': minsize = atoi(&argv[1][2]); break;
4223930Sjaap case 'f': strcpy(ftstack[0].name,&argv[1][2]); break;
4323930Sjaap case 'e': noeqn++; break;
4430727Sjaap case 'T': typesetter = &argv[1][2]; break;
4530727Sjaap default:
4630727Sjaap fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]);
4723930Sjaap break;
4823930Sjaap }
4923930Sjaap argc--;
5023930Sjaap argv++;
5123930Sjaap }
5223930Sjaap settype(typesetter);
5330727Sjaap sprintf(buf, "\"%s\"", typesetter);
5430727Sjaap lookup(deftbl, strsave(typesetter), strsave(buf));
5523930Sjaap init_tbl(); /* install other keywords in tables */
5623930Sjaap curfile = infile;
5723930Sjaap pushsrc(File, curfile);
5823930Sjaap if (argc <= 1) {
5923930Sjaap curfile->fin = stdin;
6023930Sjaap curfile->fname = strsave("-");
6123930Sjaap getdata();
6223930Sjaap } else
6323930Sjaap while (argc-- > 1) {
6423930Sjaap if (strcmp(*++argv, "-") == 0)
6523930Sjaap curfile->fin = stdin;
6623930Sjaap else if ((curfile->fin = fopen(*argv, "r")) == NULL)
6723930Sjaap fatal("can't open file %s", *argv);
6823930Sjaap curfile->fname = strsave(*argv);
6923930Sjaap getdata();
7023930Sjaap if (curfile->fin != stdin)
7123930Sjaap fclose(curfile->fin);
7223930Sjaap }
7323930Sjaap return 0;
7423930Sjaap }
7523930Sjaap
settype(s)7623930Sjaap settype(s) /* initialize data for particular typesetter */
7730727Sjaap char *s; /* the minsize could profitably come from the */
7830727Sjaap { /* troff description file /usr/lib/font/dev.../DESC.out */
7923930Sjaap if (strcmp(s, "202") == 0)
8030727Sjaap { minsize = 5; ttype = DEV202; }
8123930Sjaap else if (strcmp(s, "aps") == 0)
8230727Sjaap { minsize = 5; ttype = DEVAPS; }
8323930Sjaap else if (strcmp(s, "cat") == 0)
8430727Sjaap { minsize = 6; ttype = DEVCAT; }
85*30728Sjaap else if (strcmp(s, "har") == 0)
86*30728Sjaap { minsize = 4; ttype = DEVHAR; }
87*30728Sjaap else if (strcmp(s, "ver") == 0)
88*30728Sjaap { minsize = 6; ttype = DEVVER; }
89*30728Sjaap else if (strcmp(s, "psc") == 0)
90*30728Sjaap {/* Postscript printer (Laserwriter) using transcript */
91*30728Sjaap minsize = 4; /* troff believes 2, but that's so small */
92*30728Sjaap ttype = DEVPSC; }
9323930Sjaap else
9430727Sjaap { minsize = 6; ttype = DEVCAT; }
9523930Sjaap }
9623930Sjaap
getdata()9723930Sjaap getdata()
9823930Sjaap {
9923930Sjaap register FILE *fin;
10023930Sjaap int i, type, ln;
10123930Sjaap char fname[100];
10223930Sjaap extern int errno;
10323930Sjaap
10423930Sjaap errno = 0;
10523930Sjaap fin = curfile->fin;
10623930Sjaap curfile->lineno = 0;
10723930Sjaap printf(".lf 1 %s\n", curfile->fname);
10823930Sjaap while ((type = getline(in)) != EOF) {
10923930Sjaap if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
11023930Sjaap for (i = 11; i < 100; i++)
11123930Sjaap used[i] = 0;
11223930Sjaap printf("%s", in);
11323930Sjaap if (markline) { /* turn off from last time */
11423930Sjaap printf(".nr MK 0\n");
11523930Sjaap markline = 0;
11623930Sjaap }
11723930Sjaap display = 1;
11823930Sjaap init();
11923930Sjaap yyparse();
12023930Sjaap if (eqnreg > 0) {
12123930Sjaap if (markline)
12223930Sjaap printf(".nr MK %d\n", markline); /* for -ms macros */
12323930Sjaap printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht);
12423930Sjaap printf(".rn %d 10\n", eqnreg);
12523930Sjaap if (!noeqn)
12630727Sjaap printf("\\&\\*(10\n");
12723930Sjaap }
12823930Sjaap printf(".EN");
12923930Sjaap while (putchar(input()) != '\n')
13023930Sjaap ;
13123930Sjaap printf(".lf %d\n", curfile->lineno+1);
13223930Sjaap }
13323930Sjaap else if (type == lefteq)
13423930Sjaap inline();
13523930Sjaap else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') {
13623930Sjaap if (sscanf(in+3, "%d %s", &ln, fname) == 2) {
13723930Sjaap free(curfile->fname);
13823930Sjaap printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname));
13923930Sjaap } else
14023930Sjaap printf(".lf %d\n", curfile->lineno = ln);
14123930Sjaap } else
14223930Sjaap printf("%s", in);
14323930Sjaap }
14423930Sjaap return(0);
14523930Sjaap }
14623930Sjaap
getline(s)14723930Sjaap getline(s)
14823930Sjaap register char *s;
14923930Sjaap {
15023930Sjaap register c;
15123930Sjaap
15223930Sjaap while ((c=input()) != '\n' && c != EOF && c != lefteq) {
15323930Sjaap if (s >= in+MAXLINE) {
15423930Sjaap error("input line too long: %.20s\n", in);
15523930Sjaap in[MAXLINE] = '\0';
15623930Sjaap break;
15723930Sjaap }
15823930Sjaap *s++ = c;
15923930Sjaap }
16023930Sjaap if (c != lefteq)
16123930Sjaap *s++ = c;
16223930Sjaap *s = '\0';
16323930Sjaap return(c);
16423930Sjaap }
16523930Sjaap
16623930Sjaap inline()
16723930Sjaap {
16823930Sjaap int ds, n, sz1 = 0;
16923930Sjaap
17023930Sjaap n = curfile->lineno;
17123930Sjaap if (szstack[0] != 0)
17223930Sjaap printf(".nr %d \\n(.s\n", sz1 = salloc());
17323930Sjaap ds = salloc();
17423930Sjaap printf(".rm %d \n", ds);
17523930Sjaap display = 0;
17623930Sjaap do {
17723930Sjaap if (*in)
17823930Sjaap printf(".as %d \"%s\n", ds, in);
17923930Sjaap init();
18023930Sjaap yyparse();
18123930Sjaap if (eqnreg > 0) {
18223930Sjaap printf(".as %d \\*(%d\n", ds, eqnreg);
18323930Sjaap sfree(eqnreg);
18423930Sjaap printf(".lf %d\n", curfile->lineno+1);
18523930Sjaap }
18623930Sjaap } while (getline(in) == lefteq);
18723930Sjaap if (*in)
18823930Sjaap printf(".as %d \"%s", ds, in);
18923930Sjaap if (sz1)
19023930Sjaap printf("\\s\\n(%d", sz1);
19123930Sjaap printf("\\*(%d\n", ds);
19223930Sjaap printf(".lf %d\n", curfile->lineno+1);
19323930Sjaap if (curfile->lineno > n+3)
19423930Sjaap fprintf(stderr, "eqn warning: multi-line %c...%c, lines %d-%d, file %s\n",
19523930Sjaap lefteq, righteq, n, curfile->lineno, curfile->fname);
19623930Sjaap sfree(ds);
19723930Sjaap if (sz1) sfree(sz1);
19823930Sjaap }
19923930Sjaap
putout(p1)20023930Sjaap putout(p1)
20123930Sjaap int p1;
20223930Sjaap {
20323930Sjaap float before, after;
20430727Sjaap extern float BeforeSub, AfterSub;
20523930Sjaap
20623930Sjaap dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]);
20723930Sjaap eqnht = eht[p1];
20830727Sjaap before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */
20930727Sjaap after = ebase[p1] - AfterSub;
21023930Sjaap if (spaceval || before > 0.01 || after > 0.01) {
21123930Sjaap printf(".ds %d ", p1); /* used to be \\x'0' here: why? */
21223930Sjaap if (spaceval != NULL)
21323930Sjaap printf("\\x'0-%s'", spaceval);
21423930Sjaap else if (before > 0.01)
21523930Sjaap printf("\\x'0-%gm'", before);
21623930Sjaap printf("\\*(%d", p1);
21723930Sjaap if (spaceval == NULL && after > 0.01)
21823930Sjaap printf("\\x'%gm'", after);
21923930Sjaap putchar('\n');
22023930Sjaap }
22123930Sjaap if (szstack[0] != 0)
22223930Sjaap printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1);
22323930Sjaap eqnreg = p1;
22423930Sjaap if (spaceval != NULL) {
22523930Sjaap free(spaceval);
22623930Sjaap spaceval = NULL;
22723930Sjaap }
22823930Sjaap }
22923930Sjaap
init()23023930Sjaap init()
23123930Sjaap {
23223930Sjaap synerr = 0;
23323930Sjaap ct = 0;
23423930Sjaap ps = gsize;
23523930Sjaap ftp = ftstack;
23623930Sjaap ft = ftp->ft;
23723930Sjaap nszstack = 0;
23823930Sjaap if (szstack[0] != 0) /* absolute gsize in effect */
23923930Sjaap printf(".nr 99 \\n(.s\n");
24023930Sjaap }
24123930Sjaap
salloc()24223930Sjaap salloc()
24323930Sjaap {
24423930Sjaap int i;
24523930Sjaap
24623930Sjaap for (i = 11; i < 100; i++)
24723930Sjaap if (used[i] == 0) {
24823930Sjaap used[i]++;
24923930Sjaap return(i);
25023930Sjaap }
25123930Sjaap error(FATAL, "no eqn strings left (%d)", i);
25223930Sjaap return(0);
25323930Sjaap }
25423930Sjaap
sfree(n)25523930Sjaap sfree(n)
25623930Sjaap int n;
25723930Sjaap {
25823930Sjaap used[n] = 0;
25923930Sjaap }
26023930Sjaap
nrwid(n1,p,n2)26123930Sjaap nrwid(n1, p, n2)
26223930Sjaap int n1, p, n2;
26323930Sjaap {
26423930Sjaap printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */
26523930Sjaap }
26623930Sjaap
ABSPS(dn)26730727Sjaap char *ABSPS(dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */
26830727Sjaap int dn;
26930727Sjaap {
27030727Sjaap static char buf[100], *lb = buf;
27130727Sjaap char *p;
27230727Sjaap
27330727Sjaap if (lb > buf + sizeof(buf) - 10)
27430727Sjaap lb = buf;
27530727Sjaap p = lb;
27630727Sjaap *lb++ = '\\';
27730727Sjaap *lb++ = 's';
27830727Sjaap if (dn >= 10) { /* \s(dd only works in new troff */
27930727Sjaap if (dn >= 40)
28030727Sjaap *lb++ = '(';
28130727Sjaap *lb++ = dn/10 + '0';
28230727Sjaap *lb++ = dn%10 + '0';
28330727Sjaap } else {
28430727Sjaap *lb++ = dn + '0';
28530727Sjaap }
28630727Sjaap *lb++ = '\0';
28730727Sjaap return p;
28830727Sjaap }
28930727Sjaap
DPS(f,t)29023930Sjaap char *DPS(f, t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */
29123930Sjaap int f, t;
29223930Sjaap {
29323930Sjaap static char buf[100], *lb = buf;
29423930Sjaap char *p;
29523930Sjaap int dn;
29623930Sjaap
29723930Sjaap if (lb > buf + sizeof(buf) - 10)
29823930Sjaap lb = buf;
29923930Sjaap p = lb;
30023930Sjaap *lb++ = '\\';
30123930Sjaap *lb++ = 's';
30223930Sjaap dn = EFFPS(t) - EFFPS(f);
30323930Sjaap if (szstack[nszstack] != 0) /* absolute */
30423930Sjaap dn = EFFPS(t); /* should do proper \s(dd */
30523930Sjaap else if (dn >= 0)
30623930Sjaap *lb++ = '+';
30723930Sjaap else {
30823930Sjaap *lb++ = '-';
30923930Sjaap dn = -dn;
31023930Sjaap }
31123930Sjaap if (dn >= 10) { /* \s+(dd only works in new troff */
31223930Sjaap *lb++ = '(';
31323930Sjaap *lb++ = dn/10 + '0';
31423930Sjaap *lb++ = dn%10 + '0';
31523930Sjaap } else {
31623930Sjaap *lb++ = dn + '0';
31723930Sjaap }
31823930Sjaap *lb++ = '\0';
31923930Sjaap return p;
32023930Sjaap }
32123930Sjaap
EFFPS(n)32223930Sjaap EFFPS(n) /* effective value of n */
32323930Sjaap int n;
32423930Sjaap {
32523930Sjaap if (n >= minsize)
32623930Sjaap return n;
32723930Sjaap else
32823930Sjaap return minsize;
32923930Sjaap }
33023930Sjaap
EM(m,ps)33123930Sjaap double EM(m, ps) /* convert m to ems in gsize */
33223930Sjaap double m;
33323930Sjaap int ps;
33423930Sjaap {
33523930Sjaap m *= (float) EFFPS(ps) / gsize;
33623930Sjaap if (m <= 0.001 && m >= -0.001)
33723930Sjaap return 0;
33823930Sjaap else
33923930Sjaap return m;
34023930Sjaap }
34123930Sjaap
REL(m,ps)34223930Sjaap double REL(m, ps) /* convert m to ems in ps */
34323930Sjaap double m;
34423930Sjaap int ps;
34523930Sjaap {
34623930Sjaap m *= (float) gsize / EFFPS(ps);
34723930Sjaap if (m <= 0.001 && m >= -0.001)
34823930Sjaap return 0;
34923930Sjaap else
35023930Sjaap return m;
35123930Sjaap }
352