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