1 #ifndef lint
2 static char sccsid[] = "@(#)main.c 2.4 (CWI) 87/04/01";
3 #endif lint
4 # include "e.h"
5 #define MAXLINE 3600 /* maximum input line */
6
7 char in[MAXLINE]; /* input buffer */
8 int noeqn;
9 char *cmdname;
10
main(argc,argv)11 main(argc,argv)
12 int argc;
13 char *argv[];
14 {
15 exit(eqn(argc, argv));
16 }
17
eqn(argc,argv)18 eqn(argc,argv)
19 int argc;
20 char *argv[];
21 {
22 int i, type;
23 char *p, *getenv(), buf[20];
24
25 cmdname = argv[0];
26 if (p = getenv("TYPESETTER"))
27 typesetter = p;
28 while (argc > 1 && argv[1][0] == '-') {
29 switch (argv[1][1]) {
30
31 case 'd':
32 if (argv[1][2] == '\0')
33 dbg++;
34 else {
35 lefteq = argv[1][2];
36 righteq = argv[1][3];
37 }
38 break;
39 case 's': szstack[0] = gsize = atoi(&argv[1][2]); break;
40 case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break;
41 case 'm': minsize = atoi(&argv[1][2]); break;
42 case 'f': strcpy(ftstack[0].name,&argv[1][2]); break;
43 case 'e': noeqn++; break;
44 case 'T': typesetter = &argv[1][2]; break;
45 default:
46 fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]);
47 break;
48 }
49 argc--;
50 argv++;
51 }
52 settype(typesetter);
53 sprintf(buf, "\"%s\"", typesetter);
54 lookup(deftbl, strsave(typesetter), strsave(buf));
55 init_tbl(); /* install other keywords in tables */
56 curfile = infile;
57 pushsrc(File, curfile);
58 if (argc <= 1) {
59 curfile->fin = stdin;
60 curfile->fname = strsave("-");
61 getdata();
62 } else
63 while (argc-- > 1) {
64 if (strcmp(*++argv, "-") == 0)
65 curfile->fin = stdin;
66 else if ((curfile->fin = fopen(*argv, "r")) == NULL)
67 fatal("can't open file %s", *argv);
68 curfile->fname = strsave(*argv);
69 getdata();
70 if (curfile->fin != stdin)
71 fclose(curfile->fin);
72 }
73 return 0;
74 }
75
settype(s)76 settype(s) /* initialize data for particular typesetter */
77 char *s; /* the minsize could profitably come from the */
78 { /* troff description file /usr/lib/font/dev.../DESC.out */
79 if (strcmp(s, "202") == 0)
80 { minsize = 5; ttype = DEV202; }
81 else if (strcmp(s, "aps") == 0)
82 { minsize = 5; ttype = DEVAPS; }
83 else if (strcmp(s, "cat") == 0)
84 { minsize = 6; ttype = DEVCAT; }
85 else if (strcmp(s, "har") == 0)
86 { minsize = 4; ttype = DEVHAR; }
87 else if (strcmp(s, "ver") == 0)
88 { minsize = 6; ttype = DEVVER; }
89 else if (strcmp(s, "psc") == 0)
90 {/* Postscript printer (Laserwriter) using transcript */
91 minsize = 4; /* troff believes 2, but that's so small */
92 ttype = DEVPSC; }
93 else
94 { minsize = 6; ttype = DEVCAT; }
95 }
96
getdata()97 getdata()
98 {
99 register FILE *fin;
100 int i, type, ln;
101 char fname[100];
102 extern int errno;
103
104 errno = 0;
105 fin = curfile->fin;
106 curfile->lineno = 0;
107 printf(".lf 1 %s\n", curfile->fname);
108 while ((type = getline(in)) != EOF) {
109 if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
110 for (i = 11; i < 100; i++)
111 used[i] = 0;
112 printf("%s", in);
113 if (markline) { /* turn off from last time */
114 printf(".nr MK 0\n");
115 markline = 0;
116 }
117 display = 1;
118 init();
119 yyparse();
120 if (eqnreg > 0) {
121 if (markline)
122 printf(".nr MK %d\n", markline); /* for -ms macros */
123 printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht);
124 printf(".rn %d 10\n", eqnreg);
125 if (!noeqn)
126 printf("\\&\\*(10\n");
127 }
128 printf(".EN");
129 while (putchar(input()) != '\n')
130 ;
131 printf(".lf %d\n", curfile->lineno+1);
132 }
133 else if (type == lefteq)
134 inline();
135 else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') {
136 if (sscanf(in+3, "%d %s", &ln, fname) == 2) {
137 free(curfile->fname);
138 printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname));
139 } else
140 printf(".lf %d\n", curfile->lineno = ln);
141 } else
142 printf("%s", in);
143 }
144 return(0);
145 }
146
getline(s)147 getline(s)
148 register char *s;
149 {
150 register c;
151
152 while ((c=input()) != '\n' && c != EOF && c != lefteq) {
153 if (s >= in+MAXLINE) {
154 error("input line too long: %.20s\n", in);
155 in[MAXLINE] = '\0';
156 break;
157 }
158 *s++ = c;
159 }
160 if (c != lefteq)
161 *s++ = c;
162 *s = '\0';
163 return(c);
164 }
165
166 inline()
167 {
168 int ds, n, sz1 = 0;
169
170 n = curfile->lineno;
171 if (szstack[0] != 0)
172 printf(".nr %d \\n(.s\n", sz1 = salloc());
173 ds = salloc();
174 printf(".rm %d \n", ds);
175 display = 0;
176 do {
177 if (*in)
178 printf(".as %d \"%s\n", ds, in);
179 init();
180 yyparse();
181 if (eqnreg > 0) {
182 printf(".as %d \\*(%d\n", ds, eqnreg);
183 sfree(eqnreg);
184 printf(".lf %d\n", curfile->lineno+1);
185 }
186 } while (getline(in) == lefteq);
187 if (*in)
188 printf(".as %d \"%s", ds, in);
189 if (sz1)
190 printf("\\s\\n(%d", sz1);
191 printf("\\*(%d\n", ds);
192 printf(".lf %d\n", curfile->lineno+1);
193 if (curfile->lineno > n+3)
194 fprintf(stderr, "eqn warning: multi-line %c...%c, lines %d-%d, file %s\n",
195 lefteq, righteq, n, curfile->lineno, curfile->fname);
196 sfree(ds);
197 if (sz1) sfree(sz1);
198 }
199
putout(p1)200 putout(p1)
201 int p1;
202 {
203 float before, after;
204 extern float BeforeSub, AfterSub;
205
206 dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]);
207 eqnht = eht[p1];
208 before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */
209 after = ebase[p1] - AfterSub;
210 if (spaceval || before > 0.01 || after > 0.01) {
211 printf(".ds %d ", p1); /* used to be \\x'0' here: why? */
212 if (spaceval != NULL)
213 printf("\\x'0-%s'", spaceval);
214 else if (before > 0.01)
215 printf("\\x'0-%gm'", before);
216 printf("\\*(%d", p1);
217 if (spaceval == NULL && after > 0.01)
218 printf("\\x'%gm'", after);
219 putchar('\n');
220 }
221 if (szstack[0] != 0)
222 printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1);
223 eqnreg = p1;
224 if (spaceval != NULL) {
225 free(spaceval);
226 spaceval = NULL;
227 }
228 }
229
init()230 init()
231 {
232 synerr = 0;
233 ct = 0;
234 ps = gsize;
235 ftp = ftstack;
236 ft = ftp->ft;
237 nszstack = 0;
238 if (szstack[0] != 0) /* absolute gsize in effect */
239 printf(".nr 99 \\n(.s\n");
240 }
241
salloc()242 salloc()
243 {
244 int i;
245
246 for (i = 11; i < 100; i++)
247 if (used[i] == 0) {
248 used[i]++;
249 return(i);
250 }
251 error(FATAL, "no eqn strings left (%d)", i);
252 return(0);
253 }
254
sfree(n)255 sfree(n)
256 int n;
257 {
258 used[n] = 0;
259 }
260
nrwid(n1,p,n2)261 nrwid(n1, p, n2)
262 int n1, p, n2;
263 {
264 printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */
265 }
266
ABSPS(dn)267 char *ABSPS(dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */
268 int dn;
269 {
270 static char buf[100], *lb = buf;
271 char *p;
272
273 if (lb > buf + sizeof(buf) - 10)
274 lb = buf;
275 p = lb;
276 *lb++ = '\\';
277 *lb++ = 's';
278 if (dn >= 10) { /* \s(dd only works in new troff */
279 if (dn >= 40)
280 *lb++ = '(';
281 *lb++ = dn/10 + '0';
282 *lb++ = dn%10 + '0';
283 } else {
284 *lb++ = dn + '0';
285 }
286 *lb++ = '\0';
287 return p;
288 }
289
DPS(f,t)290 char *DPS(f, t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */
291 int f, t;
292 {
293 static char buf[100], *lb = buf;
294 char *p;
295 int dn;
296
297 if (lb > buf + sizeof(buf) - 10)
298 lb = buf;
299 p = lb;
300 *lb++ = '\\';
301 *lb++ = 's';
302 dn = EFFPS(t) - EFFPS(f);
303 if (szstack[nszstack] != 0) /* absolute */
304 dn = EFFPS(t); /* should do proper \s(dd */
305 else if (dn >= 0)
306 *lb++ = '+';
307 else {
308 *lb++ = '-';
309 dn = -dn;
310 }
311 if (dn >= 10) { /* \s+(dd only works in new troff */
312 *lb++ = '(';
313 *lb++ = dn/10 + '0';
314 *lb++ = dn%10 + '0';
315 } else {
316 *lb++ = dn + '0';
317 }
318 *lb++ = '\0';
319 return p;
320 }
321
EFFPS(n)322 EFFPS(n) /* effective value of n */
323 int n;
324 {
325 if (n >= minsize)
326 return n;
327 else
328 return minsize;
329 }
330
EM(m,ps)331 double EM(m, ps) /* convert m to ems in gsize */
332 double m;
333 int ps;
334 {
335 m *= (float) EFFPS(ps) / gsize;
336 if (m <= 0.001 && m >= -0.001)
337 return 0;
338 else
339 return m;
340 }
341
REL(m,ps)342 double REL(m, ps) /* convert m to ems in ps */
343 double m;
344 int ps;
345 {
346 m *= (float) gsize / EFFPS(ps);
347 if (m <= 0.001 && m >= -0.001)
348 return 0;
349 else
350 return m;
351 }
352