xref: /illumos-gate/usr/src/cmd/eqn/text.c (revision 42b53e0fbc5c05289c3d334bb864b784fafe5ce4)
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
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
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
192 shim(void)
193 {
194 	cs[csp++] = '\\'; cs[csp++] = '|';
195 }
196 
197 void
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
206 name4(int c1, int c2)
207 {
208 	cs[csp++] = '\\';
209 	cs[csp++] = '(';
210 	cs[csp++] = c1;
211 	cs[csp++] = c2;
212 }
213