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]; /* 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 inline(void); 16 void init(void); 17 void init_tbl(void); 18 19 void 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 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 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 inline(); 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 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 157 void inline(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, lines %d-%d, file %s\n", 186 lefteq, righteq, n, curfile->lineno, curfile->fname); 187 sfree(ds); 188 if (sz1) sfree(sz1); 189 } 190 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 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 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 245 void sfree(int n) 246 { 247 used[n] = 0; 248 } 249 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 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 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 308 EFFPS(int n) /* effective value of n */ 309 { 310 if (n >= minsize) 311 return n; 312 else 313 return minsize; 314 } 315 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 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