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