main.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "e.h"
  10. #define MAXLINE 3600 /* maximum input line */
  11. char *version = "version Oct 24, 1991";
  12. char in[MAXLINE+1]; /* input buffer */
  13. int noeqn;
  14. char *cmdname;
  15. int yyparse(void);
  16. void settype(char *);
  17. int getdata(void);
  18. int getline(char *);
  19. void inlineeq(void);
  20. void init(void);
  21. void init_tbl(void);
  22. void
  23. main(int argc, char *argv[])
  24. {
  25. char *p, buf[20];
  26. cmdname = argv[0];
  27. if (p = getenv("TYPESETTER"))
  28. typesetter = p;
  29. while (argc > 1 && argv[1][0] == '-') {
  30. switch (argv[1][1]) {
  31. case 'd':
  32. if (argv[1][2] == '\0') {
  33. dbg++;
  34. printf("...\teqn %s\n", version);
  35. } else {
  36. lefteq = argv[1][2];
  37. righteq = argv[1][3];
  38. }
  39. break;
  40. case 's': szstack[0] = gsize = atoi(&argv[1][2]); break;
  41. case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break;
  42. case 'm': minsize = atoi(&argv[1][2]); break;
  43. case 'f': strcpy(ftstack[0].name,&argv[1][2]); break;
  44. case 'e': noeqn++; break;
  45. case 'T': typesetter = &argv[1][2]; break;
  46. default:
  47. fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]);
  48. break;
  49. }
  50. argc--;
  51. argv++;
  52. }
  53. settype(typesetter);
  54. sprintf(buf, "\"%s\"", typesetter);
  55. install(deftbl, strsave(typesetter), strsave(buf), 0);
  56. init_tbl(); /* install other keywords in tables */
  57. curfile = infile;
  58. pushsrc(File, curfile->fname);
  59. if (argc <= 1) {
  60. curfile->fin = stdin;
  61. curfile->fname = strsave("-");
  62. getdata();
  63. } else
  64. while (argc-- > 1) {
  65. if (strcmp(*++argv, "-") == 0)
  66. curfile->fin = stdin;
  67. else if ((curfile->fin = fopen(*argv, "r")) == NULL)
  68. ERROR "can't open file %s", *argv FATAL;
  69. curfile->fname = strsave(*argv);
  70. getdata();
  71. if (curfile->fin != stdin)
  72. fclose(curfile->fin);
  73. }
  74. exit(0);
  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. getdata(void)
  91. {
  92. int i, type, ln;
  93. char fname[100];
  94. extern int errno;
  95. errno = 0;
  96. curfile->lineno = 0;
  97. printf(".lf 1 %s\n", curfile->fname);
  98. while ((type = getline(in)) != EOF) {
  99. if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
  100. for (i = 11; i < 100; i++)
  101. used[i] = 0;
  102. printf("%s", in);
  103. if (markline) { /* turn off from last time */
  104. printf(".nr MK 0\n");
  105. markline = 0;
  106. }
  107. display = 1;
  108. init();
  109. yyparse();
  110. if (eqnreg > 0) {
  111. if (markline)
  112. printf(".nr MK %d\n", markline); /* for -ms macros */
  113. printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht);
  114. printf(".rn %d 10\n", eqnreg);
  115. if (!noeqn)
  116. printf("\\&\\*(10\n");
  117. }
  118. printf(".EN");
  119. while (putchar(input()) != '\n')
  120. ;
  121. printf(".lf %d\n", curfile->lineno+1);
  122. }
  123. else if (type == lefteq)
  124. inlineeq();
  125. else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') {
  126. if (sscanf(in+3, "%d %s", &ln, fname) == 2) {
  127. free(curfile->fname);
  128. printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname));
  129. } else
  130. printf(".lf %d\n", curfile->lineno = ln);
  131. } else
  132. printf("%s", in);
  133. }
  134. return(0);
  135. }
  136. getline(char *s)
  137. {
  138. register c;
  139. while ((c=input()) != '\n' && c != EOF && c != lefteq) {
  140. if (s >= in+MAXLINE) {
  141. ERROR "input line too long: %.20s\n", in WARNING;
  142. in[MAXLINE] = '\0';
  143. break;
  144. }
  145. *s++ = c;
  146. }
  147. if (c != lefteq)
  148. *s++ = c;
  149. *s = '\0';
  150. return(c);
  151. }
  152. void inlineeq(void)
  153. {
  154. int ds, n, sz1 = 0;
  155. n = curfile->lineno;
  156. if (szstack[0] != 0)
  157. printf(".nr %d \\n(.s\n", sz1 = salloc());
  158. ds = salloc();
  159. printf(".rm %d \n", ds);
  160. display = 0;
  161. do {
  162. if (*in)
  163. printf(".as %d \"%s\n", ds, in);
  164. init();
  165. yyparse();
  166. if (eqnreg > 0) {
  167. printf(".as %d \\*(%d\n", ds, eqnreg);
  168. sfree(eqnreg);
  169. printf(".lf %d\n", curfile->lineno+1);
  170. }
  171. } while (getline(in) == lefteq);
  172. if (*in)
  173. printf(".as %d \"%s", ds, in);
  174. if (sz1)
  175. printf("\\s\\n(%d", sz1);
  176. printf("\\*(%d\n", ds);
  177. printf(".lf %d\n", curfile->lineno+1);
  178. if (curfile->lineno > n+3)
  179. fprintf(stderr, "eqn warning: multi-line %c...%c, file %s:%d,%d\n",
  180. lefteq, righteq, curfile->fname, n, curfile->lineno);
  181. sfree(ds);
  182. if (sz1) sfree(sz1);
  183. }
  184. void putout(int p1)
  185. {
  186. double before, after;
  187. extern double BeforeSub, AfterSub;
  188. dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]);
  189. eqnht = eht[p1];
  190. before = eht[p1] - ebase[p1] - BeforeSub; /* leave room for sub or superscript */
  191. after = ebase[p1] - AfterSub;
  192. if (spaceval || before > 0.01 || after > 0.01) {
  193. printf(".ds %d ", p1); /* used to be \\x'0' here: why? */
  194. if (spaceval != NULL)
  195. printf("\\x'0-%s'", spaceval);
  196. else if (before > 0.01)
  197. printf("\\x'0-%gm'", before);
  198. printf("\\*(%d", p1);
  199. if (spaceval == NULL && after > 0.01)
  200. printf("\\x'%gm'", after);
  201. putchar('\n');
  202. }
  203. if (szstack[0] != 0)
  204. printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1);
  205. eqnreg = p1;
  206. if (spaceval != NULL) {
  207. free(spaceval);
  208. spaceval = NULL;
  209. }
  210. }
  211. void init(void)
  212. {
  213. synerr = 0;
  214. ct = 0;
  215. ps = gsize;
  216. ftp = ftstack;
  217. ft = ftp->ft;
  218. nszstack = 0;
  219. if (szstack[0] != 0) /* absolute gsize in effect */
  220. printf(".nr 99 \\n(.s\n");
  221. }
  222. salloc(void)
  223. {
  224. int i;
  225. for (i = 11; i < 100; i++)
  226. if (used[i] == 0) {
  227. used[i]++;
  228. return(i);
  229. }
  230. ERROR "no eqn strings left (%d)", i FATAL;
  231. return(0);
  232. }
  233. void sfree(int n)
  234. {
  235. used[n] = 0;
  236. }
  237. void nrwid(int n1, int p, int n2)
  238. {
  239. printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2); /* 0 defends against - width */
  240. }
  241. char *ABSPS(int dn) /* absolute size dn in printable form \sd or \s(dd (dd >= 40) */
  242. {
  243. static char buf[100], *lb = buf;
  244. char *p;
  245. if (lb > buf + sizeof(buf) - 10)
  246. lb = buf;
  247. p = lb;
  248. *lb++ = '\\';
  249. *lb++ = 's';
  250. if (dn >= 10) { /* \s(dd only works in new troff */
  251. if (dn >= 40)
  252. *lb++ = '(';
  253. *lb++ = dn/10 + '0';
  254. *lb++ = dn%10 + '0';
  255. } else {
  256. *lb++ = dn + '0';
  257. }
  258. *lb++ = '\0';
  259. return p;
  260. }
  261. char *DPS(int f, int t) /* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */
  262. {
  263. static char buf[100], *lb = buf;
  264. char *p;
  265. int dn;
  266. if (lb > buf + sizeof(buf) - 10)
  267. lb = buf;
  268. p = lb;
  269. *lb++ = '\\';
  270. *lb++ = 's';
  271. dn = EFFPS(t) - EFFPS(f);
  272. if (szstack[nszstack] != 0) /* absolute */
  273. dn = EFFPS(t); /* should do proper \s(dd */
  274. else if (dn >= 0)
  275. *lb++ = '+';
  276. else {
  277. *lb++ = '-';
  278. dn = -dn;
  279. }
  280. if (dn >= 10) { /* \s+(dd only works in new troff */
  281. *lb++ = '(';
  282. *lb++ = dn/10 + '0';
  283. *lb++ = dn%10 + '0';
  284. } else {
  285. *lb++ = dn + '0';
  286. }
  287. *lb++ = '\0';
  288. return p;
  289. }
  290. EFFPS(int n) /* effective value of n */
  291. {
  292. if (n >= minsize)
  293. return n;
  294. else
  295. return minsize;
  296. }
  297. double EM(double m, int ps) /* convert m to ems in gsize */
  298. {
  299. m *= (double) EFFPS(ps) / gsize;
  300. if (m <= 0.001 && m >= -0.001)
  301. return 0;
  302. else
  303. return m;
  304. }
  305. double REL(double m, int ps) /* convert m to ems in ps */
  306. {
  307. m *= (double) gsize / EFFPS(ps);
  308. if (m <= 0.001 && m >= -0.001)
  309. return 0;
  310. else
  311. return m;
  312. }