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 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 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 196 shim() /* add a \| space */ 197 { 198 sadd("\\|"); 199 } 200 201 halfshim() /* add a \^ space */ 202 { 203 sadd("\\^"); 204 } 205 206 roman(c) /* add char c in "roman" font */ 207 int c; 208 { 209 nextft = ROM; 210 cadd(c); 211 } 212 213 name4(c1,c2) 214 int c1, c2; 215 { 216 sadd("\\("); 217 cadd(c1); 218 cadd(c2); 219 } 220 221 sadd(s) /* add string s to cs */ 222 char *s; 223 { 224 while (*s) 225 cadd(*s++); 226 } 227 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