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