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
21int	csp;
22int	psp;
23#define	CSSIZE	400
24char	cs[420];
25
26int	lf, rf;	/* temporary spots for left and right fonts */
27
28void name4(int, int);
29void roman(int);
30void shim(void);
31int trans(int, char *);
32
33void
34text(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
81int
82trans(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
193void
194shim(void)
195{
196	cs[csp++] = '\\'; cs[csp++] = '|';
197}
198
199void
200roman(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
207void
208name4(int c1, int c2)
209{
210	cs[csp++] = '\\';
211	cs[csp++] = '(';
212	cs[csp++] = c1;
213	cs[csp++] = c2;
214}
215