xref: /original-bsd/old/roff/common_source/n8.c (revision 5133e8a4)
1 /*-
2  * Copyright (c) 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.proprietary.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)n8.c	4.2 (Berkeley) 04/18/91";
10 #endif /* not lint */
11 
12 #include "tdef.h"
13 
14 /*
15 troff8.c
16 
17 hyphenation
18 */
19 
20 char hbuf[NHEX];
21 char *nexth = hbuf;
22 int *hyend;
23 extern int *wdstart, *wdend;
24 extern int *hyptr[];
25 extern int **hyp;
26 extern int hyoff;
27 extern int noscale;
28 extern int xxx;
29 #define THRESH 160 /*digram goodness threshold*/
30 int thresh = THRESH;
31 
32 hyphen(wp)
33 int *wp;
34 {
35 	register *i, j;
36 
37 	i = wp;
38 	while(punct(*i++))
39 		;
40 	if (!alph(*--i))
41 		return;
42 	wdstart = i++;
43 	while(alph(*i++))
44 		;
45 	hyend = wdend = --i-1;
46 	while(punct(*i++))
47 		;
48 	if (*--i)
49 		return;
50 	if ((wdend-wdstart-4) < 0)
51 		return;
52 	hyp = hyptr;
53 	*hyp = 0;
54 	hyoff = 2;
55 	if (!exword() && !suffix())
56 		digram();
57 	*hyp++ = 0;
58 	if (*hyptr) for(j = 1; j;) {
59 		j = 0;
60 		for(hyp = hyptr+1; *hyp != 0; hyp++) {
61 			if (*(hyp-1) > *hyp) {
62 				j++;
63 				i = *hyp;
64 				*hyp = *(hyp-1);
65 				*(hyp-1) = i;
66 			}
67 		}
68 	}
69 }
70 
71 punct(i)
72 int i;
73 {
74 	if (!i || alph(i))
75 		return(0);
76 	else
77 		return(1);
78 }
79 
80 alph(i)
81 int i;
82 {
83 	register j;
84 
85 	j = i & CMASK;
86 	if (((j >= 'A') && (j <= 'Z')) || ((j >= 'a') && (j <= 'z')))
87 		return(1);
88 	else
89 		return(0);
90 }
91 
92 caseht()
93 {
94 	thresh = THRESH;
95 	if (skip())
96 		return;
97 	noscale++;
98 	thresh = atoi();
99 	noscale = 0;
100 }
101 
102 casehw()
103 {
104 	register i, k;
105 	register char *j;
106 
107 	k = 0;
108 	while(!skip()) {
109 		if ((j = nexth) >= (hbuf + NHEX - 2))
110 			goto full;
111 		for (;;) {
112 			if ((i = getch()) & MOT)
113 				continue;
114 			if (((i &= CMASK) == ' ') || (i == '\n')) {
115 				*j++ = 0;
116 				nexth = j;
117 				*j = 0;
118 				if (i == ' ')
119 					break;
120 				else
121 					return;
122 			}
123 			if (i == '-') {
124 				k = 0200;
125 				continue;
126 			}
127 			*j++ = maplow(i) | k;
128 			k = 0;
129 			if (j >= (hbuf + NHEX - 2))
130 				goto full;
131 		}
132 	}
133 	return;
134 full:
135 	prstr("Exception word list full.\n");
136 	*nexth = 0;
137 }
138 
139 exword()
140 {
141 	register int *w;
142 	register char *e;
143 	char *save;
144 
145 	e = hbuf;
146 	while(1) {
147 		save = e;
148 		if (*e == 0)return(0);
149 		w = wdstart;
150 		while((*e && (w <= hyend)) &&
151 		      ((*e & 0177) == maplow(*w & CMASK))) {e++; w++;};
152 		if (!*e) {
153 			if (((w-1) == hyend) ||
154 			   ((w == wdend) && (maplow(*w & CMASK) == 's'))) {
155 				w = wdstart;
156 				for(e = save; *e; e++) {
157 					if (*e & 0200)*hyp++ = w;
158 					if (hyp > (hyptr+NHYP-1))
159 						hyp = hyptr+NHYP-1;
160 					w++;
161 				}
162 				return(1);
163 			}else{e++; continue;}
164 		}else while(*e++);
165 	}
166 }
167 
168 suffix()
169 {
170 	register int *w;
171 	register char *s, *s0;
172 	int i;
173 	extern char *suftab[];
174 	extern int *chkvow();
175 
176 again:
177 	if (!alph(i = *hyend & CMASK))
178 		return(0);
179 	if (i < 'a')
180 		i -= 'A'-'a';
181 	if ((s0 = suftab[i-'a']) == 0)
182 		return(0);
183 	for (;;) {
184 		if ((i = *s0 & 017) == 0)
185 			return(0);
186 		s = s0 + i - 1;
187 		w = hyend - 1;
188 		while(((s > s0) && (w >= wdstart)) &&
189 		   ((*s & 0177) == maplow(*w))) {
190 			s--;
191 			w--;
192 		}
193 		if (s == s0)
194 			break;
195 		s0 += i;
196 	}
197 	s = s0 + i - 1;
198 	w = hyend;
199 	if (*s0 & 0200) goto mark;
200 	while(s > s0) {
201 		w--;
202 		if (*s-- & 0200) {
203 	mark:
204 			hyend = w - 1;
205 			if (*s0 & 0100)
206 				continue;
207 			if (!chkvow(w))
208 				return(0);
209 			*hyp++ = w;
210 		}
211 	}
212 	if (*s0 & 040)
213 		return(0);
214 	if (exword())
215 		return(1);
216 	goto again;
217 }
218 
219 maplow(i)
220 int i;
221 {
222 	if ((i &= CMASK) < 'a')i += 'a' - 'A';
223 	return(i);
224 }
225 
226 vowel(i)
227 int i;
228 {
229 	switch(maplow(i)) {
230 		case 'a':
231 		case 'e':
232 		case 'i':
233 		case 'o':
234 		case 'u':
235 		case 'y':
236 			return(1);
237 		default:
238 			return(0);
239 	}
240 }
241 
242 int *chkvow(w)
243 int *w;
244 {
245 	while(--w >= wdstart)if(vowel(*w & CMASK))return(w);
246 	return(0);
247 }
248 
249 digram() {
250 	register *w, val;
251 	int *nhyend, *maxw, maxval;
252 	extern char bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
253 
254 again:
255 	if (!(w=chkvow(hyend+1)))return;
256 	hyend = w;
257 	if (!(w=chkvow(hyend)))return;
258 	nhyend = w;
259 	maxval = 0;
260 	w--;
261 	while((++w < hyend) && (w < (wdend-1))) {
262 		val = 1;
263 		if (w == wdstart)val *= dilook('a',*w,bxh);
264 		else if(w == wdstart+1)val *= dilook(*(w-1),*w,bxxh);
265 		else val *= dilook(*(w-1),*w,xxh);
266 		val *= dilook(*w, *(w+1), xhx);
267 		val *= dilook(*(w+1), *(w+2), hxx);
268 		if (val > maxval) {
269 			maxval = val;
270 			maxw = w + 1;
271 		}
272 	}
273 	hyend = nhyend;
274 	if (maxval > thresh)*hyp++ = maxw;
275 	goto again;
276 }
277 
278 dilook(a,b,t)
279 int a, b;
280 char t[26][13];
281 {
282 	register i, j;
283 
284 	i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
285 	if (!(j & 01))i >>= 4;
286 	return(i & 017);
287 }
288