|
|
1.1 root 1: #include "e.h"
2: #include "y.tab.h"
3: #include <ctype.h>
4:
5: #define CSSIZE 1000
6: char cs[CSSIZE+20]; /* text string converted into this */
7: char *csp; /* next spot in cs[] */
8: char *psp; /* next character in input token */
9:
10: int lf, rf; /* temporary spots for left and right fonts */
11: int lastft; /* last \f added */
12: int nextft; /* next \f to be added */
13:
14: int pclass; /* class of previous character */
15: int nclass; /* class of next character */
16:
17: int class[LAST][LAST] ={ /* guesswork, tuned to times roman postscript */
18:
19: /*OT OL IL DG LP RP SL PL IF IJ VB */
20: /*OT*/ { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0 }, /* OTHER */
21: /*OL*/ { 1, 0, 1, 1, 1, 1, 1, 2, 2, 2, 0 }, /* OLET */
22: /*IL*/ { 1, 1, 0, 1, 1, 1, 1, 3, 2, 1, 0 }, /* ILET */
23: /*DG*/ { 1, 1, 1, 0, 1, 1, 1, 2, 2, 2, 0 }, /* DIG */
24: /*LP*/ { 1, 1, 1, 1, 1, 2, 1, 2, 3, 3, 0 }, /* LPAR */
25: /*RP*/ { 2, 2, 2, 1, 1, 1, 1, 2, 3, 3, 0 }, /* RPAR */
26: /*SL*/ { 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0 }, /* SLASH */
27: /*PL*/ { 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 0 }, /* PLUS */
28: /*IF*/ { 3, 3, 1, 2, 2, 3, 2, 3, 0, 1, 1 }, /* ILETF */
29: /*IJ*/ { 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0 }, /* ILETJ */
30: /*VB*/ { 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 1 }, /* VBAR */
31:
32: };
33:
34: extern void shim(int, int);
35: extern void roman(int);
36: extern void sadd(char *);
37: extern void cadd(int);
38: extern int trans(int, char *);
39:
40: void text(int t, char *p1) /* convert text string p1 of type t */
41: {
42: int c;
43: char *p;
44: tbl *tp;
45:
46: yyval = salloc();
47: ebase[yyval] = 0;
48: eht[yyval] = EM(1.0, ps); /* ht in ems of orig size */
49: lfont[yyval] = rfont[yyval] = ROM;
50: lclass[yyval] = rclass[yyval] = OTHER;
51: if (t == QTEXT) {
52: for (p = p1; *p; p++) /* scan for embedded \f's */
53: if (*p == '\\' && *(p+1) == 'f')
54: break;
55: if (*p) /* if found \f, leave it alone and hope */
56: p = p1;
57: else {
58: sprintf(cs, "\\f%s%s\\fP", ftp->name, p1);
59: p = cs;
60: }
61: } else if (t == SPACE)
62: p = "\\ ";
63: else if (t == THIN)
64: p = "\\|";
65: else if (t == TAB)
66: p = "\\t";
67: else if ((tp = lookup(restbl, p1)) != NULL) {
68: p = tp->cval;
69: } else {
70: lf = rf = 0;
71: lastft = 0;
72: nclass = NONE; /* get started with no class == no pad */
73: csp = cs;
74: for (psp = p1; (c = *psp++) != '\0'; ) {
75: nextft = ft;
76: pclass = nclass;
77: rf = trans(c, p1);
78: if (lf == 0) {
79: lf = rf; /* left stuff is first found */
80: lclass[yyval] = nclass;
81: }
82: if (csp-cs > CSSIZE)
83: ERROR "converted token %.25s... too long", p1 FATAL ;
84: }
85: sadd("\\fP");
86: *csp = '\0';
87: p = cs;
88: lfont[yyval] = lf;
89: rfont[yyval] = rf;
90: rclass[yyval] = nclass;
91: }
92: dprintf(".\t%dtext: S%d <- %s; b=%g,h=%g,lf=%c,rf=%c,ps=%d\n",
93: t, yyval, p, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval], ps);
94: printf(".ds %d \"%s\n", yyval, p);
95: }
96:
97: trans(int c, char *p1)
98: {
99: int f;
100:
101: if (isalpha(c) && ft == ITAL && c != 'f' && c != 'j') { /* italic letter */
102: shim(pclass, nclass = ILET);
103: cadd(c);
104: return ITAL;
105: }
106: if (isalpha(c) && ft != ITAL) { /* other letter */
107: shim(pclass, nclass = OLET);
108: cadd(c);
109: return ROM;
110: }
111: if (isdigit(c)) {
112: shim(pclass, nclass = DIG);
113: roman(c);
114: return ROM; /* this is the right side font of this object */
115: }
116: f = ROM;
117: nclass = OTHER;
118: switch (c) {
119: case ':': case ';': case '!': case '%': case '?':
120: shim(pclass, nclass);
121: roman(c);
122: return f;
123: case '(': case '[':
124: shim(pclass, nclass = LPAR);
125: roman(c);
126: return f;
127: case ')': case ']':
128: shim(pclass, nclass = RPAR);
129: roman(c);
130: return f;
131: case ',':
132: shim(pclass, nclass = OTHER);
133: roman(c);
134: return f;
135: case '.':
136: if (rf == ROM)
137: roman(c);
138: else
139: cadd(c);
140: return f;
141: case '|': /* postscript needs help with default width! */
142: shim(pclass, nclass = VBAR);
143: sadd("\\v'.17m'\\z|\\v'-.17m'\\|"); /* and height */
144: return f;
145: case '=':
146: shim(pclass, nclass = PLUS);
147: sadd("\\(eq");
148: return f;
149: case '+':
150: shim(pclass, nclass = PLUS);
151: sadd("\\(pl");
152: return f;
153: case '>':
154: case '<': /* >, >=, >>, <, <-, <=, << */
155: shim(pclass, nclass = PLUS);
156: if (*psp == '=') {
157: sadd(c == '<' ? "\\(<=" : "\\(>=");
158: psp++;
159: } else if (c == '<' && *psp == '-') { /* <- only */
160: sadd("\\(<-");
161: psp++;
162: } else if (*psp == c) { /* << or >> */
163: cadd(c);
164: cadd(c);
165: *psp++;
166: } else {
167: cadd(c);
168: }
169: return f;
170: case '-':
171: shim(pclass, nclass = PLUS); /* probably too big for ->'s */
172: if (*psp == '>') {
173: sadd("\\(->");
174: psp++;
175: } else {
176: sadd("\\(mi");
177: }
178: return f;
179: case '/':
180: shim(pclass, nclass = SLASH);
181: cadd('/');
182: return f;
183: case '~':
184: case ' ':
185: sadd("\\|\\|");
186: return f;
187: case '^':
188: sadd("\\|");
189: return f;
190: case '\\': /* troff - pass only \(xx without comment */
191: shim(pclass, nclass);
192: cadd('\\');
193: cadd(c = *psp++);
194: if (c == '(' && *psp && *(psp+1)) {
195: cadd(*psp++);
196: cadd(*psp++);
197: } else
198: fprintf(stderr, "eqn warning: unquoted troff command \\%c, line %d, file %s\n",
199: c, curfile->lineno, curfile->fname);
200: return f;
201: case '\'':
202: shim(pclass, nclass);
203: sadd("\\(fm");
204: return f;
205:
206: case 'f':
207: if (ft == ITAL) {
208: shim(pclass, nclass = ILETF);
209: cadd('f');
210: f = ITAL;
211: } else
212: cadd('f');
213: return f;
214: case 'j':
215: if (ft == ITAL) {
216: shim(pclass, nclass = ILETJ);
217: cadd('j');
218: f = ITAL;
219: } else
220: cadd('j');
221: return f;
222: default:
223: shim(pclass, nclass);
224: cadd(c);
225: return ft==ITAL ? ITAL : ROM;
226: }
227: }
228:
229: char *pad(int n) /* return the padding as a string */
230: {
231: static char buf[20];
232:
233: buf[0] = 0;
234: if (n < 0) {
235: sprintf(buf, "\\h'-%du*\\w'\\^'u'", -n);
236: return buf;
237: }
238: for ( ; n > 1; n -= 2)
239: strcat(buf, "\\|");
240: if (n > 0)
241: strcat(buf, "\\^");
242: return buf;
243: }
244:
245: void shim(int lc, int rc) /* add padding space suitable to left and right classes */
246: {
247: sadd(pad(class[lc][rc]));
248: }
249:
250: void roman(int c) /* add char c in "roman" font */
251: {
252: nextft = ROM;
253: cadd(c);
254: }
255:
256: void sadd(char *s) /* add string s to cs */
257: {
258: while (*s)
259: cadd(*s++);
260: }
261:
262: void cadd(int c) /* add char c to end of cs */
263: {
264: char *p;
265:
266: if (lastft != nextft) {
267: if (lastft != 0) {
268: *csp++ = '\\';
269: *csp++ = 'f';
270: *csp++ = 'P';
271: }
272: *csp++ = '\\';
273: *csp++ = 'f';
274: if (ftp == ftstack) { /* bottom level */
275: if (ftp->ft == ITAL) /* usual case */
276: *csp++ = nextft;
277: else /* gfont set, use it */
278: for (p = ftp->name; *csp = *p++; )
279: csp++;
280: } else { /* inside some kind of font ... */
281: for (p = ftp->name; *csp = *p++; )
282: csp++;
283: }
284: lastft = nextft;
285: }
286: *csp++ = c;
287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.