pic: use troff drawing commands for filling objects
[troff.git] / eqn / main.c
blob19f8105180505d1dc000cffb641b031a82d8b84e
1 #include "e.h"
2 #include <errno.h>
4 #define MAXLINE 3600 /* maximum input line */
6 char *version = "version Oct 24, 1991";
8 char in[MAXLINE+1]; /* input buffer */
9 int noeqn;
10 char *cmdname;
12 int yyparse(void);
13 void settype(char *);
14 int getdata(void);
15 int getlinex(char *);
16 void inlineeq(void);
17 void init(void);
18 void init_tbl(void);
20 int main(int argc, char *argv[])
22 char *p, buf[20];
24 cmdname = argv[0];
25 if (p = getenv("TYPESETTER"))
26 typesetter = p;
27 while (argc > 1 && argv[1][0] == '-') {
28 switch (argv[1][1]) {
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];
38 break;
39 case 's':
40 szstack[0] = gsize = atoi(&argv[1][2]);
41 break;
42 case 'p':
43 deltaps = atoi(&argv[1][2]);
44 dps_set = 1;
45 break;
46 case 'm':
47 minsize = atoi(&argv[1][2]);
48 break;
49 case 'f':
50 strcpy(ftstack[0].name,&argv[1][2]);
51 break;
52 case 'e':
53 noeqn++;
54 break;
55 case 'T':
56 typesetter = &argv[1][2];
57 break;
58 default:
59 fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]);
60 break;
62 argc--;
63 argv++;
65 settype(typesetter);
66 sprintf(buf, "\"%s\"", typesetter);
67 install(deftbl, strsave(typesetter), strsave(buf), 0);
68 init_tbl(); /* install other keywords in tables */
69 curfile = infile;
70 pushsrc(File, curfile->fname);
71 if (argc <= 1) {
72 curfile->fin = stdin;
73 curfile->fname = strsave("-");
74 getdata();
75 } else
76 while (argc-- > 1) {
77 if (strcmp(*++argv, "-") == 0)
78 curfile->fin = stdin;
79 else if ((curfile->fin = fopen(*argv, "r")) == NULL)
80 ERROR "can't open file %s", *argv FATAL;
81 curfile->fname = strsave(*argv);
82 getdata();
83 if (curfile->fin != stdin)
84 fclose(curfile->fin);
86 return 0;
90 * initialize data for particular typesetter
91 * the minsize could profitably come from the
92 * troff description file /usr/lib/font/dev.../DESC.out
94 void settype(char *s)
96 if (strcmp(s, "202") == 0) {
97 minsize = 5;
98 ttype = DEV202;
99 } else if (strcmp(s, "aps") == 0) {
100 minsize = 5;
101 ttype = DEVAPS;
102 } else if (strcmp(s, "cat") == 0) {
103 minsize = 6;
104 ttype = DEVCAT;
105 } else if (strcmp(s, "post") == 0) {
106 minsize = 4;
107 ttype = DEVPOST;
108 } else {
109 minsize = 5;
110 ttype = DEV202;
114 int getdata(void)
116 int i, type, ln;
117 char fname[100];
119 errno = 0;
120 curfile->lineno = 0;
121 printf(".lf 1 %s\n", curfile->fname);
122 while ((type = getlinex(in)) != EOF) {
123 if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
124 for (i = 11; i < 100; i++)
125 used[i] = 0;
126 printf("%s", in);
127 if (markline) { /* turn off from last time */
128 printf(".nr MK 0\n");
129 markline = 0;
131 display = 1;
132 init();
133 yyparse();
134 if (eqnreg > 0) {
135 if (markline)
136 printf(".nr MK %d\n", markline); /* for -ms macros */
137 printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht);
138 printf(".rn %d 10\n", eqnreg);
139 if (!noeqn)
140 printf("\\&\\*(10\n");
142 printf(".EN");
143 while (putchar(input()) != '\n')
145 printf(".lf %d\n", curfile->lineno+1);
147 else if (type == lefteq)
148 inlineeq();
149 else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') {
150 if (sscanf(in+3, "%d %s", &ln, fname) == 2) {
151 free(curfile->fname);
152 printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname));
153 } else
154 printf(".lf %d\n", curfile->lineno = ln);
155 } else
156 printf("%s", in);
158 return 0;
161 int getlinex(char *s)
163 int c;
165 while ((c=input()) != '\n' && c != EOF && c != lefteq) {
166 if (s >= in+MAXLINE) {
167 ERROR "input line too long: %.20s\n", in WARNING;
168 in[MAXLINE] = '\0';
169 break;
171 *s++ = c;
173 if (c != lefteq)
174 *s++ = c;
175 *s = '\0';
176 return c;
179 void inlineeq(void)
181 int ds, n, sz1 = 0;
183 n = curfile->lineno;
184 if (szstack[0] != 0)
185 printf(".nr %d \\n(.s\n", sz1 = salloc());
186 ds = salloc();
187 printf(".rm %d \n", ds);
188 display = 0;
189 do {
190 if (*in)
191 printf(".as %d \"%s\n", ds, in);
192 init();
193 yyparse();
194 if (eqnreg > 0) {
195 printf(".as %d \\*(%d\n", ds, eqnreg);
196 sfree(eqnreg);
197 printf(".lf %d\n", curfile->lineno+1);
199 } while (getlinex(in) == lefteq);
200 if (*in)
201 printf(".as %d \"%s", ds, in);
202 if (sz1)
203 printf("\\s\\n(%d", sz1);
204 printf("\\*(%d\n", ds);
205 printf(".lf %d\n", curfile->lineno+1);
206 if (curfile->lineno > n+3)
207 fprintf(stderr, "eqn warning: multi-line %c...%c, file %s:%d,%d\n",
208 lefteq, righteq, curfile->fname, n, curfile->lineno);
209 sfree(ds);
210 if (sz1)
211 sfree(sz1);
214 void putout(int p1)
216 double before, after;
217 extern double BeforeSub, AfterSub;
219 dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]);
220 eqnht = eht[p1];
221 before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */
222 after = ebase[p1] - AfterSub;
223 if (spaceval || before > 0.01 || after > 0.01) {
224 printf(".ds %d ", p1); /* used to be \\x'0' here: why? */
225 if (spaceval != NULL)
226 printf("\\x'0-%s'", spaceval);
227 else if (before > 0.01)
228 printf("\\x'0-%gm'", before);
229 printf("\\*(%d", p1);
230 if (spaceval == NULL && after > 0.01)
231 printf("\\x'%gm'", after);
232 putchar('\n');
234 if (szstack[0] != 0)
235 printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1);
236 eqnreg = p1;
237 if (spaceval != NULL) {
238 free(spaceval);
239 spaceval = NULL;
243 void init(void)
245 synerr = 0;
246 ct = 0;
247 ps = gsize;
248 ftp = ftstack;
249 ft = ftp->ft;
250 nszstack = 0;
251 if (szstack[0] != 0) /* absolute gsize in effect */
252 printf(".nr 99 \\n(.s\n");
255 int salloc(void)
257 int i;
259 for (i = 11; i < 100; i++)
260 if (used[i] == 0) {
261 used[i]++;
262 return i;
264 ERROR "no eqn strings left (%d)", i FATAL;
265 return 0;
268 void sfree(int n)
270 used[n] = 0;
273 void nrwid(int n1, int p, int n2)
275 printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */
278 char *ABSPS(int dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */
280 static char buf[100], *lb = buf;
281 char *p;
283 if (lb > buf + sizeof(buf) - 10)
284 lb = buf;
285 p = lb;
286 *lb++ = '\\';
287 *lb++ = 's';
288 if (dn >= 10) { /* \s(dd only works in new troff */
289 if (dn >= 40)
290 *lb++ = '(';
291 *lb++ = dn/10 + '0';
292 *lb++ = dn%10 + '0';
293 } else {
294 *lb++ = dn + '0';
296 *lb++ = '\0';
297 return p;
300 char *DPS(int f, int t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */
302 static char buf[100], *lb = buf;
303 char *p;
304 int dn;
306 if (lb > buf + sizeof(buf) - 10)
307 lb = buf;
308 p = lb;
309 *lb++ = '\\';
310 *lb++ = 's';
311 dn = EFFPS(t) - EFFPS(f);
312 if (szstack[nszstack] != 0) /* absolute */
313 dn = EFFPS(t); /* should do proper \s(dd */
314 else if (dn >= 0)
315 *lb++ = '+';
316 else {
317 *lb++ = '-';
318 dn = -dn;
320 if (dn >= 10) { /* \s+(dd only works in new troff */
321 *lb++ = '(';
322 *lb++ = dn/10 + '0';
323 *lb++ = dn%10 + '0';
324 } else {
325 *lb++ = dn + '0';
327 *lb++ = '\0';
328 return p;
331 int EFFPS(int n) /* effective value of n */
333 if (n >= minsize)
334 return n;
335 else
336 return minsize;
339 double EM(double m, int ps) /* convert m to ems in gsize */
341 m *= (double) EFFPS(ps) / gsize;
342 if (m <= 0.001 && m >= -0.001)
343 return 0;
344 else
345 return m;
348 double REL(double m, int ps) /* convert m to ems in ps */
350 m *= (double) gsize / EFFPS(ps);
351 if (m <= 0.001 && m >= -0.001)
352 return 0;
353 else
354 return m;