Blob


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