xref: /titanic_44/usr/src/cmd/eqn/text.c (revision 25cf1a301a396c38e8adf52c15f537b80d2483f7)
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