1 /*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
13 */
14
15 #include "e.h"
16 #include "e.def"
17 #include <locale.h>
18
19 int csp;
20 int psp;
21 #define CSSIZE 400
22 char cs[420];
23
24 int lf, rf; /* temporary spots for left and right fonts */
25
26 void name4(int, int);
27 void roman(int);
28 void shim(void);
29 int trans(int, char *);
30
31 void
text(int t,char * p1)32 text(int t, char *p1)
33 {
34 int c;
35 char *p;
36 tbl *tp, *lookup();
37 extern tbl *restbl[];
38
39 yyval = oalloc();
40 ebase[yyval] = 0;
41 #ifndef NEQN
42 eht[yyval] = VERT(EM(1.0, EFFPS(ps))); /* ht in machine units */
43 #else /* NEQN */
44 eht[yyval] = VERT(2); /* 2 half-spaces */
45 #endif /* NEQN */
46 lfont[yyval] = rfont[yyval] = ROM;
47 if (t == QTEXT)
48 p = p1;
49 else if (t == SPACE)
50 p = "\\ ";
51 else if (t == THIN)
52 p = "\\|";
53 else if (t == TAB)
54 p = "\\t";
55 else if ((tp = lookup(restbl, p1, NULL)) != NULL)
56 p = tp->defn;
57 else {
58 lf = rf = 0;
59 for (csp = psp = 0; (c = p1[psp++]) != '\0'; ) {
60 rf = trans(c, p1);
61 if (lf == 0)
62 lf = rf; /* save first */
63 if (csp > CSSIZE)
64 error(FATAL, gettext(
65 "converted token %.25s... too long"), p1);
66 }
67 cs[csp] = '\0';
68 p = cs;
69 lfont[yyval] = lf;
70 rfont[yyval] = rf;
71 }
72 if (dbg)
73 printf(".\t%dtext: S%d <- %s; b=%d,h=%d,lf=%c,rf=%c\n",
74 t, yyval, p, ebase[yyval], eht[yyval], lfont[yyval],
75 rfont[yyval]);
76 printf(".ds %d \"%s\n", yyval, p);
77 }
78
79 int
trans(int c,char * p1)80 trans(int c, char *p1)
81 {
82 int f;
83 f = ROM;
84 switch (c) {
85 case '0': case '1': case '2': case '3': case '4':
86 case '5': case '6': case '7': case '8': case '9':
87 case ':': case ';': case '!': case '%':
88 case '(': case '[': case ')': case ']':
89 case ',':
90 if (rf == ITAL)
91 shim();
92 roman(c); break;
93 case '.':
94 if (rf == ROM)
95 roman(c);
96 else
97 cs[csp++] = c;
98 f = rf;
99 break;
100 case '|':
101 if (rf == ITAL)
102 shim();
103 shim(); roman(c); shim(); break;
104 case '=':
105 if (rf == ITAL)
106 shim();
107 name4('e', 'q');
108 break;
109 case '+':
110 if (rf == ITAL)
111 shim();
112 name4('p', 'l');
113 break;
114 case '>': case '<':
115 if (rf == ITAL)
116 shim();
117 if (p1[psp] == '=') { /* look ahead for == <= >= */
118 name4(c, '=');
119 psp++;
120 } else {
121 cs[csp++] = c;
122 }
123 break;
124 case '-':
125 if (rf == ITAL)
126 shim();
127 if (p1[psp] == '>') {
128 name4('-', '>'); psp++;
129 } else {
130 name4('m', 'i');
131 }
132 break;
133 case '/':
134 if (rf == ITAL)
135 shim();
136 name4('s', 'l');
137 break;
138 case '~': case ' ':
139 shim(); shim(); break;
140 case '^':
141 shim(); break;
142 case '\\': /* troff - pass 2 or 3 more chars */
143 if (rf == ITAL)
144 shim();
145 cs[csp++] = c; cs[csp++] = c = p1[psp++]; cs[csp++] = p1[psp++];
146 if (c == '(') cs[csp++] = p1[psp++];
147 if (c == '*' && cs[csp-1] == '(') {
148 cs[csp++] = p1[psp++];
149 cs[csp++] = p1[psp++];
150 }
151 break;
152 case '\'':
153 cs[csp++] = '\\';
154 cs[csp++] = 'f';
155 cs[csp++] = rf == ITAL ? ITAL : ROM;
156 name4('f', 'm');
157 cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P';
158 f = rf == ITAL ? ITAL : ROM;
159 break;
160
161 case 'f':
162 if (ft == ITAL) {
163 cs[csp++] = '\\'; cs[csp++] = '^';
164 cs[csp++] = 'f';
165
166 /* trying | instead of ^ */
167 cs[csp++] = '\\'; cs[csp++] = '|';
168
169 f = ITAL;
170 }
171 else
172 cs[csp++] = 'f';
173 break;
174 case 'j':
175 if (ft == ITAL) {
176 cs[csp++] = '\\'; cs[csp++] = '^';
177 cs[csp++] = 'j';
178 f = ITAL;
179 }
180 else
181 cs[csp++] = 'j';
182 break;
183 default:
184 cs[csp++] = c;
185 f = ft == ITAL ? ITAL : ROM;
186 break;
187 }
188 return (f);
189 }
190
191 void
shim(void)192 shim(void)
193 {
194 cs[csp++] = '\\'; cs[csp++] = '|';
195 }
196
197 void
roman(int c)198 roman(int c)
199 {
200 cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = ROM;
201 cs[csp++] = c;
202 cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P';
203 }
204
205 void
name4(int c1,int c2)206 name4(int c1, int c2)
207 {
208 cs[csp++] = '\\';
209 cs[csp++] = '(';
210 cs[csp++] = c1;
211 cs[csp++] = c2;
212 }
213