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