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