xref: /titanic_44/usr/src/cmd/troff/n8.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /*
34  * University Copyright- Copyright (c) 1982, 1986, 1988
35  * The Regents of the University of California
36  * All Rights Reserved
37  *
38  * University Acknowledgment- Portions of this document are derived from
39  * software developed by the University of California, Berkeley, and its
40  * contributors.
41  */
42 
43 #include	<ctype.h>
44 #include	"tdef.h"
45 #include "ext.h"
46 #define	HY_BIT	0200	/* stuff in here only works for ascii */
47 
48 /*
49  * troff8.c
50  *
51  * hyphenation
52  */
53 
54 char	hbuf[NHEX];
55 char	*nexth = hbuf;
56 tchar	*hyend;
57 #define THRESH 160 /*digram goodness threshold*/
58 int	thresh = THRESH;
59 
60 hyphen(wp)
61 	tchar *wp;
62 {
63 	register j;
64 	register tchar *i;
65 
66 	i = wp;
67 	while (punct(cbits(*i++)))
68 		;
69 	if (!alph(cbits(*--i)))
70 		return;
71 	wdstart = i++;
72 	while (alph(cbits(*i++)))
73 		;
74 	hyend = wdend = --i - 1;
75 	while (punct(cbits(*i++)))
76 		;
77 	if (*--i)
78 		return;
79 	if ((wdend - wdstart - 4) < 0)
80 		return;
81 	hyp = hyptr;
82 	*hyp = 0;
83 	hyoff = 2;
84 	if (!exword() && !suffix())
85 		digram();
86 	*hyp++ = 0;
87 	if (*hyptr)
88 		for (j = 1; j; ) {
89 			j = 0;
90 			for (hyp = hyptr + 1; *hyp != 0; hyp++) {
91 				if (*(hyp - 1) > *hyp) {
92 					j++;
93 					i = *hyp;
94 					*hyp = *(hyp - 1);
95 					*(hyp - 1) = i;
96 				}
97 			}
98 		}
99 }
100 
101 
102 punct(i)
103 {
104 	if (!i || alph(i))
105 		return(0);
106 	else
107 		return(1);
108 }
109 
110 
111 alph(i)
112 {
113 	if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z')
114 		return(1);
115 	else
116 		return(0);
117 }
118 
119 
120 caseht()
121 {
122 	thresh = THRESH;
123 	if (skip())
124 		return;
125 	noscale++;
126 	thresh = atoi();
127 	noscale = 0;
128 }
129 
130 
131 casehw()
132 {
133 	register i, k;
134 	register char	*j;
135 	tchar t;
136 
137 	k = 0;
138 	while (!skip()) {
139 		if ((j = nexth) >= (hbuf + NHEX - 2))
140 			goto full;
141 		for (; ; ) {
142 			if (ismot(t = getch()))
143 				continue;
144 			i = cbits(t);
145 			if (i == ' ' || i == '\n') {
146 				*j++ = 0;
147 				nexth = j;
148 				*j = 0;
149 				if (i == ' ')
150 					break;
151 				else
152 					return;
153 			}
154 			if (i == '-') {
155 				k = HY_BIT;
156 				continue;
157 			}
158 			*j++ = maplow(i) | k;
159 			k = 0;
160 			if (j >= (hbuf + NHEX - 2))
161 				goto full;
162 		}
163 	}
164 	return;
165 full:
166 	errprint(gettext("exception word list full."));
167 	*nexth = 0;
168 }
169 
170 
171 exword()
172 {
173 	register tchar *w;
174 	register char	*e;
175 	char	*save;
176 
177 	e = hbuf;
178 	while (1) {
179 		save = e;
180 		if (*e == 0)
181 			return(0);
182 		w = wdstart;
183 		while (*e && w <= hyend && (*e & 0177) == maplow(cbits(*w))) {
184 			e++;
185 			w++;
186 		};
187 		if (!*e) {
188 			if (w-1 == hyend || (w == wdend && maplow(cbits(*w)) == 's')) {
189 				w = wdstart;
190 				for (e = save; *e; e++) {
191 					if (*e & HY_BIT)
192 						*hyp++ = w;
193 					if (hyp > (hyptr + NHYP - 1))
194 						hyp = hyptr + NHYP - 1;
195 					w++;
196 				}
197 				return(1);
198 			} else {
199 				e++;
200 				continue;
201 			}
202 		} else
203 			while (*e++)
204 				;
205 	}
206 }
207 
208 
209 suffix()
210 {
211 	register tchar *w;
212 	register char	*s, *s0;
213 	tchar i;
214 	extern char	*suftab[];
215 	extern tchar *chkvow();
216 
217 again:
218 	if (!alph(cbits(i = cbits(*hyend))))
219 		return(0);
220 	if (i < 'a')
221 		i -= 'A' - 'a';
222 	if ((s0 = suftab[i-'a']) == 0)
223 		return(0);
224 	for (; ; ) {
225 		if ((i = *s0 & 017) == 0)
226 			return(0);
227 		s = s0 + i - 1;
228 		w = hyend - 1;
229 		while (s > s0 && w >= wdstart && (*s & 0177) == maplow(cbits(*w))) {
230 			s--;
231 			w--;
232 		}
233 		if (s == s0)
234 			break;
235 		s0 += i;
236 	}
237 	s = s0 + i - 1;
238 	w = hyend;
239 	if (*s0 & HY_BIT)
240 		goto mark;
241 	while (s > s0) {
242 		w--;
243 		if (*s-- & HY_BIT) {
244 mark:
245 			hyend = w - 1;
246 			if (*s0 & 0100)
247 				continue;
248 			if (!chkvow(w))
249 				return(0);
250 			*hyp++ = w;
251 		}
252 	}
253 	if (*s0 & 040)
254 		return(0);
255 	if (exword())
256 		return(1);
257 	goto again;
258 }
259 
260 
261 maplow(i)
262 register int	i;
263 {
264 	if (ischar(i) && isupper(i))
265 		i = tolower(i);
266 	return(i);
267 }
268 
269 
270 vowel(i)
271 int	i;
272 {
273 	switch (maplow(i)) {
274 	case 'a':
275 	case 'e':
276 	case 'i':
277 	case 'o':
278 	case 'u':
279 	case 'y':
280 		return(1);
281 	default:
282 		return(0);
283 	}
284 }
285 
286 
287 tchar *chkvow(w)
288 tchar *w;
289 {
290 	while (--w >= wdstart)
291 		if (vowel(cbits(*w)))
292 			return(w);
293 	return(0);
294 }
295 
296 
297 digram()
298 {
299 	register tchar *w;
300 	register val;
301 	tchar * nhyend, *maxw;
302 	int	maxval;
303 	extern char	bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
304 
305 again:
306 	if (!(w = chkvow(hyend + 1)))
307 		return;
308 	hyend = w;
309 	if (!(w = chkvow(hyend)))
310 		return;
311 	nhyend = w;
312 	maxval = 0;
313 	w--;
314 	while ((++w < hyend) && (w < (wdend - 1))) {
315 		val = 1;
316 		if (w == wdstart)
317 			val *= dilook('a', cbits(*w), bxh);
318 		else if (w == wdstart + 1)
319 			val *= dilook(cbits(*(w-1)), cbits(*w), bxxh);
320 		else
321 			val *= dilook(cbits(*(w-1)), cbits(*w), xxh);
322 		val *= dilook(cbits(*w), cbits(*(w+1)), xhx);
323 		val *= dilook(cbits(*(w+1)), cbits(*(w+2)), hxx);
324 		if (val > maxval) {
325 			maxval = val;
326 			maxw = w + 1;
327 		}
328 	}
329 	hyend = nhyend;
330 	if (maxval > thresh)
331 		*hyp++ = maxw;
332 	goto again;
333 }
334 
335 
336 dilook(a, b, t)
337 int	a, b;
338 char	t[26][13];
339 {
340 	register i, j;
341 
342 	i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
343 	if (!(j & 01))
344 		i >>= 4;
345 	return(i & 017);
346 }
347 
348 
349