1 #ifndef lint
2 static char sccsid[] = "@(#)text.c 2.2 (CWI) 87/04/01";
3 #endif lint
4 #include "e.h"
5 #include "y.tab.h"
6 #include <ctype.h>
7
8 #define CSSIZE 400
9 char cs[CSSIZE+20]; /* text string converted into this */
10 char *csp; /* next spot in cs[] */
11 char *psp; /* next character in input token */
12
13 int lf, rf; /* temporary spots for left and right fonts */
14 int lastft; /* last \f added */
15 int nextft; /* next \f to be added */
16
text(t,p1)17 text(t, p1) /* convert text string p1 of type t */
18 int t;
19 char *p1;
20 {
21 int c;
22 char *p;
23 tbl *tp;
24
25 yyval = salloc();
26 ebase[yyval] = 0;
27 eht[yyval] = EM(1.0, ps); /* ht in ems of orig size */
28 eps[yyval] = ps;
29 lfont[yyval] = rfont[yyval] = ROM;
30 if (t == QTEXT) {
31 for (p = p1; *p; p++) /* scan for embedded \f's */
32 if (*p == '\\' && *(p+1) == 'f')
33 break;
34 if (*p) /* if found \f, leave it alone and hope */
35 p = p1;
36 else {
37 sprintf(cs, "\\f%s%s\\fP", ftp->name, p1);
38 p = cs;
39 }
40 } else if (t == SPACE)
41 p = "\\ ";
42 else if (t == THIN)
43 p = "\\|";
44 else if (t == TAB)
45 p = "\\t";
46 else if ((tp = lookup(restbl, p1, NULL)) != NULL) {
47 p = tp->defn;
48 } else {
49 lf = rf = 0;
50 /* sprintf(cs, "\\f%s", ftp->name); */
51 lastft = 0;
52 csp = cs;
53 for (psp = p1; (c = *psp++) != '\0'; ) {
54 nextft = ft;
55 rf = trans(c, p1);
56 if (lf == 0)
57 lf = rf; /* save first */
58 if (csp-cs > CSSIZE)
59 error(FATAL,"converted token %.25s... too long",p1);
60 }
61 sadd("\\fP");
62 *csp = '\0';
63 p = cs;
64 lfont[yyval] = lf;
65 rfont[yyval] = rf;
66 }
67 dprintf(".\t%dtext: S%d <- %s; b=%g,h=%g,lf=%c,rf=%c,ps=%d\n",
68 t, yyval, p, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval], ps);
69 printf(".ds %d \"%s\n", yyval, p);
70 }
71
trans(c,p1)72 trans(c, p1)
73 int c;
74 char *p1;
75 {
76 int f;
77
78 f = ROM;
79 switch (c) {
80 case '0': case '1': case '2': case '3': case '4':
81 case '5': case '6': case '7': case '8': case '9':
82 case ':': case ';': case '!': case '%': case '?':
83 case '(': case '[': case ']':
84 if (rf == ITAL)
85 shim();
86 roman(c);
87 break;
88 case ')':
89 if (rf == ITAL)
90 halfshim();
91 roman(c);
92 break;
93 case ',':
94 roman(c);
95 halfshim();
96 f = rf;
97 break;
98 case '.':
99 if (rf == ROM)
100 roman(c);
101 else
102 cadd(c);
103 f = rf;
104 break;
105 case '|':
106 if (rf == ITAL && ttype != DEV202)
107 shim();
108 shim(); roman(c); shim();
109 break;
110 case '=':
111 if (rf == ITAL)
112 shim();
113 name4('e','q');
114 break;
115 case '+':
116 if (rf == ITAL)
117 shim();
118 name4('p','l');
119 break;
120 case '>': case '<':
121 if (rf == ITAL)
122 shim();
123 if (*psp == '=') { /* look ahead for == <= >= */
124 name4(c,'=');
125 psp++;
126 } else {
127 cadd(c);
128 }
129 break;
130 case '-':
131 if (rf == ITAL)
132 shim();
133 if (*psp == '>') {
134 name4('-','>');
135 halfshim();
136 psp++;
137 } else {
138 name4('m','i');
139 }
140 break;
141 case '/':
142 halfshim();
143 cadd('/');
144 halfshim();
145 break;
146 case '~': case ' ':
147 shim(); shim();
148 break;
149 case '^':
150 shim();
151 break;
152 case '\\': /* troff - pass only \(xx without comment */
153 if (rf == ITAL)
154 shim();
155 cadd('\\');
156 cadd(c = *psp++);
157 if (c == '(' && *psp && *(psp+1)) {
158 cadd(*psp++);
159 cadd(*psp++);
160 } else
161 fprintf(stderr, "eqn warning: unquoted troff command \\%c, line %d, file %s\n",
162 c, curfile->lineno, curfile->fname);
163 break;
164 case '\'':
165 name4('f','m');
166 break;
167
168 case 'f':
169 if (ft == ITAL) {
170 if (psp == p1+1 || !isalnum(*(psp-2)))
171 halfshim();
172 cadd('f');
173 if (!isalpha(*psp) && *psp != '\0') /* add \| except in text */
174 shim();
175 f = ITAL;
176 }
177 else
178 cadd('f');
179 break;
180 case 'j':
181 if (ft == ITAL) {
182 sadd("\\^j");
183 f = ITAL;
184 }
185 else
186 cadd('j');
187 break;
188 default:
189 cadd(c);
190 f = ft==ITAL ? ITAL : ROM;
191 break;
192 }
193 return(f);
194 }
195
shim()196 shim() /* add a \| space */
197 {
198 sadd("\\|");
199 }
200
halfshim()201 halfshim() /* add a \^ space */
202 {
203 sadd("\\^");
204 }
205
roman(c)206 roman(c) /* add char c in "roman" font */
207 int c;
208 {
209 nextft = ROM;
210 cadd(c);
211 }
212
name4(c1,c2)213 name4(c1,c2)
214 int c1, c2;
215 {
216 sadd("\\(");
217 cadd(c1);
218 cadd(c2);
219 }
220
sadd(s)221 sadd(s) /* add string s to cs */
222 char *s;
223 {
224 while (*s)
225 cadd(*s++);
226 }
227
cadd(c)228 cadd(c) /* add char c to end of cs */
229 int c;
230 {
231 char *p;
232
233 if (lastft != nextft) {
234 if (lastft != 0) {
235 *csp++ = '\\';
236 *csp++ = 'f';
237 *csp++ = 'P';
238 }
239 *csp++ = '\\';
240 *csp++ = 'f';
241 if (ftp == ftstack) { /* bottom level */
242 if (ftp->ft == ITAL) /* usual case */
243 *csp++ = nextft;
244 else /* gfont set, use it */
245 for (p = ftp->name; *csp = *p++; )
246 csp++;
247 } else { /* inside some kind of font ... */
248 for (p = ftp->name; *csp = *p++; )
249 csp++;
250 }
251 lastft = nextft;
252 }
253 *csp++ = c;
254 }
255