#include "e.h" #define MAXLINE 3600 /* maximum input line */ char *version = "version Oct 24, 1991"; char in[MAXLINE+1]; /* input buffer */ int noeqn; char *cmdname; int yyparse(void); void settype(char *); int getdata(void); int getline(char *); void inlineeq(void); void init(void); void init_tbl(void); void main(int argc, char *argv[]) { char *p, buf[20]; cmdname = argv[0]; if (p = getenv("TYPESETTER")) typesetter = p; while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { case 'd': if (argv[1][2] == '\0') { dbg++; printf("...\teqn %s\n", version); } else { lefteq = argv[1][2]; righteq = argv[1][3]; } break; case 's': szstack[0] = gsize = atoi(&argv[1][2]); break; case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break; case 'm': minsize = atoi(&argv[1][2]); break; case 'f': strcpy(ftstack[0].name,&argv[1][2]); break; case 'e': noeqn++; break; case 'T': typesetter = &argv[1][2]; break; default: fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]); break; } argc--; argv++; } settype(typesetter); sprintf(buf, "\"%s\"", typesetter); install(deftbl, strsave(typesetter), strsave(buf), 0); init_tbl(); /* install other keywords in tables */ curfile = infile; pushsrc(File, curfile->fname); if (argc <= 1) { curfile->fin = stdin; curfile->fname = strsave("-"); getdata(); } else while (argc-- > 1) { if (strcmp(*++argv, "-") == 0) curfile->fin = stdin; else if ((curfile->fin = fopen(*argv, "r")) == NULL) ERROR "can't open file %s", *argv FATAL; curfile->fname = strsave(*argv); getdata(); if (curfile->fin != stdin) fclose(curfile->fin); } exit(0); } void settype(char *s) /* initialize data for particular typesetter */ /* the minsize could profitably come from the */ { /* troff description file /usr/lib/font/dev.../DESC.out */ if (strcmp(s, "202") == 0) { minsize = 5; ttype = DEV202; } else if (strcmp(s, "aps") == 0) { minsize = 5; ttype = DEVAPS; } else if (strcmp(s, "cat") == 0) { minsize = 6; ttype = DEVCAT; } else if (strcmp(s, "post") == 0) { minsize = 4; ttype = DEVPOST; } else { minsize = 5; ttype = DEV202; } } getdata(void) { int i, type, ln; char fname[100]; extern int errno; errno = 0; curfile->lineno = 0; printf(".lf 1 %s\n", curfile->fname); while ((type = getline(in)) != EOF) { if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') { for (i = 11; i < 100; i++) used[i] = 0; printf("%s", in); if (markline) { /* turn off from last time */ printf(".nr MK 0\n"); markline = 0; } display = 1; init(); yyparse(); if (eqnreg > 0) { if (markline) printf(".nr MK %d\n", markline); /* for -ms macros */ printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht); printf(".rn %d 10\n", eqnreg); if (!noeqn) printf("\\&\\*(10\n"); } printf(".EN"); while (putchar(input()) != '\n') ; printf(".lf %d\n", curfile->lineno+1); } else if (type == lefteq) inlineeq(); else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') { if (sscanf(in+3, "%d %s", &ln, fname) == 2) { free(curfile->fname); printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname)); } else printf(".lf %d\n", curfile->lineno = ln); } else printf("%s", in); } return(0); } getline(char *s) { register c; while ((c=input()) != '\n' && c != EOF && c != lefteq) { if (s >= in+MAXLINE) { ERROR "input line too long: %.20s\n", in WARNING; in[MAXLINE] = '\0'; break; } *s++ = c; } if (c != lefteq) *s++ = c; *s = '\0'; return(c); } void inlineeq(void) { int ds, n, sz1 = 0; n = curfile->lineno; if (szstack[0] != 0) printf(".nr %d \\n(.s\n", sz1 = salloc()); ds = salloc(); printf(".rm %d \n", ds); display = 0; do { if (*in) printf(".as %d \"%s\n", ds, in); init(); yyparse(); if (eqnreg > 0) { printf(".as %d \\*(%d\n", ds, eqnreg); sfree(eqnreg); printf(".lf %d\n", curfile->lineno+1); } } while (getline(in) == lefteq); if (*in) printf(".as %d \"%s", ds, in); if (sz1) printf("\\s\\n(%d", sz1); printf("\\*(%d\n", ds); printf(".lf %d\n", curfile->lineno+1); if (curfile->lineno > n+3) fprintf(stderr, "eqn warning: multi-line %c...%c, file %s:%d,%d\n", lefteq, righteq, curfile->fname, n, curfile->lineno); sfree(ds); if (sz1) sfree(sz1); } void putout(int p1) { double before, after; extern double BeforeSub, AfterSub; dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]); eqnht = eht[p1]; before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */ after = ebase[p1] - AfterSub; if (spaceval || before > 0.01 || after > 0.01) { printf(".ds %d ", p1); /* used to be \\x'0' here: why? */ if (spaceval != NULL) printf("\\x'0-%s'", spaceval); else if (before > 0.01) printf("\\x'0-%gm'", before); printf("\\*(%d", p1); if (spaceval == NULL && after > 0.01) printf("\\x'%gm'", after); putchar('\n'); } if (szstack[0] != 0) printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1); eqnreg = p1; if (spaceval != NULL) { free(spaceval); spaceval = NULL; } } void init(void) { synerr = 0; ct = 0; ps = gsize; ftp = ftstack; ft = ftp->ft; nszstack = 0; if (szstack[0] != 0) /* absolute gsize in effect */ printf(".nr 99 \\n(.s\n"); } salloc(void) { int i; for (i = 11; i < 100; i++) if (used[i] == 0) { used[i]++; return(i); } ERROR "no eqn strings left (%d)", i FATAL; return(0); } void sfree(int n) { used[n] = 0; } void nrwid(int n1, int p, int n2) { printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */ } char *ABSPS(int dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */ { static char buf[100], *lb = buf; char *p; if (lb > buf + sizeof(buf) - 10) lb = buf; p = lb; *lb++ = '\\'; *lb++ = 's'; if (dn >= 10) { /* \s(dd only works in new troff */ if (dn >= 40) *lb++ = '('; *lb++ = dn/10 + '0'; *lb++ = dn%10 + '0'; } else { *lb++ = dn + '0'; } *lb++ = '\0'; return p; } char *DPS(int f, int t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */ { static char buf[100], *lb = buf; char *p; int dn; if (lb > buf + sizeof(buf) - 10) lb = buf; p = lb; *lb++ = '\\'; *lb++ = 's'; dn = EFFPS(t) - EFFPS(f); if (szstack[nszstack] != 0) /* absolute */ dn = EFFPS(t); /* should do proper \s(dd */ else if (dn >= 0) *lb++ = '+'; else { *lb++ = '-'; dn = -dn; } if (dn >= 10) { /* \s+(dd only works in new troff */ *lb++ = '('; *lb++ = dn/10 + '0'; *lb++ = dn%10 + '0'; } else { *lb++ = dn + '0'; } *lb++ = '\0'; return p; } EFFPS(int n) /* effective value of n */ { if (n >= minsize) return n; else return minsize; } double EM(double m, int ps) /* convert m to ems in gsize */ { m *= (double) EFFPS(ps) / gsize; if (m <= 0.001 && m >= -0.001) return 0; else return m; } double REL(double m, int ps) /* convert m to ems in ps */ { m *= (double) gsize / EFFPS(ps); if (m <= 0.001 && m >= -0.001) return 0; else return m; }