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 
11 main(argc,argv)
12 	int argc;
13 	char *argv[];
14 {
15 	exit(eqn(argc, argv));
16 }
17 
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 
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 
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 
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 
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 
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 
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 
255 sfree(n)
256 	int n;
257 {
258 	used[n] = 0;
259 }
260 
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 
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 
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 
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 
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 
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