xref: /illumos-gate/usr/src/cmd/troff/n8.c (revision 306990466301759c88d84c51c57b57ca930a3635)
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  * University Copyright- Copyright (c) 1982, 1986, 1988
32  * The Regents of the University of California
33  * All Rights Reserved
34  *
35  * University Acknowledgment- Portions of this document are derived from
36  * software developed by the University of California, Berkeley, and its
37  * contributors.
38  */
39 
40 #include	<ctype.h>
41 #include	"tdef.h"
42 #include "ext.h"
43 #define	HY_BIT	0200	/* stuff in here only works for ascii */
44 
45 /*
46  * troff8.c
47  *
48  * hyphenation
49  */
50 
51 char	hbuf[NHEX];
52 char	*nexth = hbuf;
53 tchar	*hyend;
54 #define THRESH 160 /*digram goodness threshold*/
55 int	thresh = THRESH;
56 
57 int
58 hyphen(wp)
59 	tchar *wp;
60 {
61 	int	j;
62 	tchar *i;
63 
64 	i = wp;
65 	while (punct(cbits(*i++)))
66 		;
67 	if (!alph(cbits(*--i)))
68 		return (0);
69 	wdstart = i++;
70 	while (alph(cbits(*i++)))
71 		;
72 	hyend = wdend = --i - 1;
73 	while (punct(cbits(*i++)))
74 		;
75 	if (*--i)
76 		return (0);
77 	if ((wdend - wdstart - 4) < 0)
78 		return (0);
79 	hyp = hyptr;
80 	*hyp = 0;
81 	hyoff = 2;
82 	if (!exword() && !suffix())
83 		digram();
84 	*hyp++ = 0;
85 	if (*hyptr)
86 		for (j = 1; j; ) {
87 			j = 0;
88 			for (hyp = hyptr + 1; *hyp != 0; hyp++) {
89 				if (*(hyp - 1) > *hyp) {
90 					j++;
91 					i = *hyp;
92 					*hyp = *(hyp - 1);
93 					*(hyp - 1) = i;
94 				}
95 			}
96 		}
97 
98 	return (0);
99 }
100 
101 
102 int
103 punct(int i)
104 {
105 	if (!i || alph(i))
106 		return(0);
107 	else
108 		return(1);
109 }
110 
111 
112 int
113 alph(int i)
114 {
115 	if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z')
116 		return(1);
117 	else
118 		return(0);
119 }
120 
121 
122 int
123 caseht()
124 {
125 	thresh = THRESH;
126 	if (skip())
127 		return (0);
128 	noscale++;
129 	thresh = atoi();
130 	noscale = 0;
131 
132 	return (0);
133 }
134 
135 
136 int
137 casehw()
138 {
139 	int	i, k;
140 	char	*j;
141 	tchar t;
142 
143 	k = 0;
144 	while (!skip()) {
145 		if ((j = nexth) >= (hbuf + NHEX - 2))
146 			goto full;
147 		for (; ; ) {
148 			if (ismot(t = getch()))
149 				continue;
150 			i = cbits(t);
151 			if (i == ' ' || i == '\n') {
152 				*j++ = 0;
153 				nexth = j;
154 				*j = 0;
155 				if (i == ' ')
156 					break;
157 				else
158 					return (0);
159 			}
160 			if (i == '-') {
161 				k = HY_BIT;
162 				continue;
163 			}
164 			*j++ = maplow(i) | k;
165 			k = 0;
166 			if (j >= (hbuf + NHEX - 2))
167 				goto full;
168 		}
169 	}
170 	return (0);
171 full:
172 	errprint(gettext("exception word list full."));
173 	*nexth = 0;
174 
175 	return (0);
176 }
177 
178 
179 int
180 exword()
181 {
182 	tchar *w;
183 	char	*e;
184 	char	*save;
185 
186 	e = hbuf;
187 	while (1) {
188 		save = e;
189 		if (*e == 0)
190 			return(0);
191 		w = wdstart;
192 		while (*e && w <= hyend && (*e & 0177) == maplow(cbits(*w))) {
193 			e++;
194 			w++;
195 		};
196 		if (!*e) {
197 			if (w-1 == hyend || (w == wdend && maplow(cbits(*w)) == 's')) {
198 				w = wdstart;
199 				for (e = save; *e; e++) {
200 					if (*e & HY_BIT)
201 						*hyp++ = w;
202 					if (hyp > (hyptr + NHYP - 1))
203 						hyp = hyptr + NHYP - 1;
204 					w++;
205 				}
206 				return(1);
207 			} else {
208 				e++;
209 				continue;
210 			}
211 		} else
212 			while (*e++)
213 				;
214 	}
215 
216 	return (0);
217 }
218 
219 
220 int
221 suffix()
222 {
223 	tchar *w;
224 	char	*s, *s0;
225 	tchar i;
226 	extern char	*suftab[];
227 	extern tchar *chkvow();
228 
229 again:
230 	if (!alph(cbits(i = cbits(*hyend))))
231 		return(0);
232 	if (i < 'a')
233 		i -= 'A' - 'a';
234 	if ((s0 = suftab[i-'a']) == 0)
235 		return(0);
236 	for (; ; ) {
237 		if ((i = *s0 & 017) == 0)
238 			return(0);
239 		s = s0 + i - 1;
240 		w = hyend - 1;
241 		while (s > s0 && w >= wdstart && (*s & 0177) == maplow(cbits(*w))) {
242 			s--;
243 			w--;
244 		}
245 		if (s == s0)
246 			break;
247 		s0 += i;
248 	}
249 	s = s0 + i - 1;
250 	w = hyend;
251 	if (*s0 & HY_BIT)
252 		goto mark;
253 	while (s > s0) {
254 		w--;
255 		if (*s-- & HY_BIT) {
256 mark:
257 			hyend = w - 1;
258 			if (*s0 & 0100)
259 				continue;
260 			if (!chkvow(w))
261 				return(0);
262 			*hyp++ = w;
263 		}
264 	}
265 	if (*s0 & 040)
266 		return(0);
267 	if (exword())
268 		return(1);
269 	goto again;
270 }
271 
272 
273 int
274 maplow(i)
275 int	i;
276 {
277 	if (ischar(i) && isupper(i))
278 		i = tolower(i);
279 	return(i);
280 }
281 
282 
283 int
284 vowel(i)
285 int	i;
286 {
287 	switch (maplow(i)) {
288 	case 'a':
289 	case 'e':
290 	case 'i':
291 	case 'o':
292 	case 'u':
293 	case 'y':
294 		return(1);
295 	default:
296 		return(0);
297 	}
298 }
299 
300 
301 tchar *chkvow(w)
302 tchar *w;
303 {
304 	while (--w >= wdstart)
305 		if (vowel(cbits(*w)))
306 			return(w);
307 	return(0);
308 }
309 
310 
311 int
312 digram()
313 {
314 	tchar *w;
315 	int	val;
316 	tchar * nhyend, *maxw;
317 	int	maxval;
318 	extern char	bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
319 
320 again:
321 	if (!(w = chkvow(hyend + 1)))
322 		return (0);
323 	hyend = w;
324 	if (!(w = chkvow(hyend)))
325 		return (0);
326 	nhyend = w;
327 	maxval = 0;
328 	w--;
329 	while ((++w < hyend) && (w < (wdend - 1))) {
330 		val = 1;
331 		if (w == wdstart)
332 			val *= dilook('a', cbits(*w), bxh);
333 		else if (w == wdstart + 1)
334 			val *= dilook(cbits(*(w-1)), cbits(*w), bxxh);
335 		else
336 			val *= dilook(cbits(*(w-1)), cbits(*w), xxh);
337 		val *= dilook(cbits(*w), cbits(*(w+1)), xhx);
338 		val *= dilook(cbits(*(w+1)), cbits(*(w+2)), hxx);
339 		if (val > maxval) {
340 			maxval = val;
341 			maxw = w + 1;
342 		}
343 	}
344 	hyend = nhyend;
345 	if (maxval > thresh)
346 		*hyp++ = maxw;
347 	goto again;
348 }
349 
350 
351 int
352 dilook(a, b, t)
353 int	a, b;
354 char	t[26][13];
355 {
356 	int	i, j;
357 
358 	i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
359 	if (!(j & 01))
360 		i >>= 4;
361 	return(i & 017);
362 }
363 
364 
365