1 /* $MirOS: src/usr.bin/oldroff/nroff/n8.c,v 1.3 2008/11/08 23:04:42 tg Exp $ */
2 
3 /*-
4  * Copyright (c) 1979, 1980, 1981, 1986, 1988, 1990, 1991, 1992
5  *     The Regents of the University of California.
6  * Copyright (C) Caldera International Inc.  2001-2002.
7  * Copyright (c) 2003, 2004
8  *	Thorsten "mirabilos" Glaser <tg@mirbsd.org>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms,
12  * with or without modification, are permitted provided
13  * that the following conditions are met:
14  *
15  * Redistributions of source code and documentation must retain
16  * the above copyright notice, this list of conditions and the
17  * following disclaimer.  Redistributions in binary form must
18  * reproduce the above copyright notice, this list of conditions
19  * and the following disclaimer in the documentation and/or other
20  * materials provided with the distribution.
21  *
22  * All advertising materials mentioning features or use of this
23  * software must display the following acknowledgement:
24  *   This product includes software developed or owned by
25  *   Caldera International, Inc.
26  *
27  * Neither the name of Caldera International, Inc. nor the names
28  * of other contributors may be used to endorse or promote products
29  * derived from this software without specific prior written permission.
30  *
31  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
32  * INTERNATIONAL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
33  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
36  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
37  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
41  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
42  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  */
44 
45 #include <sys/cdefs.h>
46 __SCCSID("@(#)n8.c	4.2 (Berkeley) 4/18/91");
47 __RCSID("$MirOS: src/usr.bin/oldroff/nroff/n8.c,v 1.3 2008/11/08 23:04:42 tg Exp $");
48 
49 #include "tdef.h"
50 
51 /*
52 troff8.c
53 
54 hyphenation
55 */
56 
57 char hbuf[NHEX];
58 char *nexth = hbuf;
59 int *hyend;
60 extern int *wdstart, *wdend;
61 extern int *hyptr[];
62 extern int **hyp;
63 extern int hyoff;
64 extern int noscale;
65 extern int xxx;
66 #define THRESH 160 /*digram goodness threshold*/
67 int thresh = THRESH;
68 
hyphen(wp)69 hyphen(wp)
70 int *wp;
71 {
72 	register *i, j;
73 
74 	i = wp;
75 	while(punct(*i++))
76 		;
77 	if (!alph(*--i))
78 		return;
79 	wdstart = i++;
80 	while(alph(*i++))
81 		;
82 	hyend = wdend = --i-1;
83 	while(punct(*i++))
84 		;
85 	if (*--i)
86 		return;
87 	if ((wdend-wdstart-4) < 0)
88 		return;
89 	hyp = hyptr;
90 	*hyp = 0;
91 	hyoff = 2;
92 	if (!exword() && !suffix())
93 		digram();
94 	*hyp++ = 0;
95 	if (*hyptr) for(j = 1; j;) {
96 		j = 0;
97 		for(hyp = hyptr+1; *hyp != 0; hyp++) {
98 			if (*(hyp-1) > *hyp) {
99 				j++;
100 				i = *hyp;
101 				*hyp = *(hyp-1);
102 				*(hyp-1) = i;
103 			}
104 		}
105 	}
106 }
107 
punct(i)108 punct(i)
109 int i;
110 {
111 	if (!i || alph(i))
112 		return(0);
113 	else
114 		return(1);
115 }
116 
alph(i)117 alph(i)
118 int i;
119 {
120 	register j;
121 
122 	j = i & CMASK;
123 	if (((j >= 'A') && (j <= 'Z')) || ((j >= 'a') && (j <= 'z')))
124 		return(1);
125 	else
126 		return(0);
127 }
128 
caseht()129 caseht()
130 {
131 	thresh = THRESH;
132 	if (skip())
133 		return;
134 	noscale++;
135 	thresh = nr_atoi();
136 	noscale = 0;
137 }
138 
casehw()139 casehw()
140 {
141 	register i, k;
142 	register char *j;
143 
144 	k = 0;
145 	while(!skip()) {
146 		if ((j = nexth) >= (hbuf + NHEX - 2))
147 			goto full;
148 		for (;;) {
149 			if ((i = getch()) & MOT)
150 				continue;
151 			if (((i &= CMASK) == ' ') || (i == '\n')) {
152 				*j++ = 0;
153 				nexth = j;
154 				*j = 0;
155 				if (i == ' ')
156 					break;
157 				else
158 					return;
159 			}
160 			if (i == '-') {
161 				k = 0200;
162 				continue;
163 			}
164 			*j++ = maplow(i) | k;
165 			k = 0;
166 			if (j >= (hbuf + NHEX - 2))
167 				goto full;
168 		}
169 	}
170 	return;
171 full:
172 	prstr("Exception word list full.\n");
173 	*nexth = 0;
174 }
175 
exword()176 exword()
177 {
178 	register int *w;
179 	register char *e;
180 	char *save;
181 
182 	e = hbuf;
183 	while(1) {
184 		save = e;
185 		if (*e == 0)return(0);
186 		w = wdstart;
187 		while((*e && (w <= hyend)) &&
188 		      ((*e & 0177) == maplow(*w & CMASK))) {e++; w++;};
189 		if (!*e) {
190 			if (((w-1) == hyend) ||
191 			   ((w == wdend) && (maplow(*w & CMASK) == 's'))) {
192 				w = wdstart;
193 				for(e = save; *e; e++) {
194 					if (*e & 0200)*hyp++ = w;
195 					if (hyp > (hyptr+NHYP-1))
196 						hyp = hyptr+NHYP-1;
197 					w++;
198 				}
199 				return(1);
200 			}else{e++; continue;}
201 		}else while(*e++);
202 	}
203 }
204 
suffix()205 suffix()
206 {
207 	register int *w;
208 	register char *s, *s0;
209 	int i;
210 	extern char *suftab[];
211 	extern int *chkvow();
212 
213 again:
214 	if (!alph(i = *hyend & CMASK))
215 		return(0);
216 	if (i < 'a')
217 		i -= 'A'-'a';
218 	if ((s0 = suftab[i-'a']) == 0)
219 		return(0);
220 	for (;;) {
221 		if ((i = *s0 & 017) == 0)
222 			return(0);
223 		s = s0 + i - 1;
224 		w = hyend - 1;
225 		while(((s > s0) && (w >= wdstart)) &&
226 		   ((*s & 0177) == maplow(*w))) {
227 			s--;
228 			w--;
229 		}
230 		if (s == s0)
231 			break;
232 		s0 += i;
233 	}
234 	s = s0 + i - 1;
235 	w = hyend;
236 	if (*s0 & 0200) goto mark;
237 	while(s > s0) {
238 		w--;
239 		if (*s-- & 0200) {
240 	mark:
241 			hyend = w - 1;
242 			if (*s0 & 0100)
243 				continue;
244 			if (!chkvow(w))
245 				return(0);
246 			*hyp++ = w;
247 		}
248 	}
249 	if (*s0 & 040)
250 		return(0);
251 	if (exword())
252 		return(1);
253 	goto again;
254 }
255 
maplow(i)256 maplow(i)
257 int i;
258 {
259 	if ((i &= CMASK) < 'a')i += 'a' - 'A';
260 	return(i);
261 }
262 
vowel(i)263 vowel(i)
264 int i;
265 {
266 	switch(maplow(i)) {
267 		case 'a':
268 		case 'e':
269 		case 'i':
270 		case 'o':
271 		case 'u':
272 		case 'y':
273 			return(1);
274 		default:
275 			return(0);
276 	}
277 }
278 
chkvow(w)279 int *chkvow(w)
280 int *w;
281 {
282 	while(--w >= wdstart)if(vowel(*w & CMASK))return(w);
283 	return(0);
284 }
285 
digram()286 digram() {
287 	register *w, val;
288 	int *nhyend, *maxw, maxval;
289 	extern char bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
290 
291 again:
292 	if (!(w=chkvow(hyend+1)))return;
293 	hyend = w;
294 	if (!(w=chkvow(hyend)))return;
295 	nhyend = w;
296 	maxval = 0;
297 	w--;
298 	while((++w < hyend) && (w < (wdend-1))) {
299 		val = 1;
300 		if (w == wdstart)val *= dilook('a',*w,bxh);
301 		else if(w == wdstart+1)val *= dilook(*(w-1),*w,bxxh);
302 		else val *= dilook(*(w-1),*w,xxh);
303 		val *= dilook(*w, *(w+1), xhx);
304 		val *= dilook(*(w+1), *(w+2), hxx);
305 		if (val > maxval) {
306 			maxval = val;
307 			maxw = w + 1;
308 		}
309 	}
310 	hyend = nhyend;
311 	if (maxval > thresh)*hyp++ = maxw;
312 	goto again;
313 }
314 
dilook(a,b,t)315 dilook(a,b,t)
316 int a, b;
317 char t[26][13];
318 {
319 	register i, j;
320 
321 	i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
322 	if (!(j & 01))i >>= 4;
323 	return(i & 017);
324 }
325