Blob


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