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
hyphen(wp)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
punct(i)71 punct(i)
72 int i;
73 {
74 if (!i || alph(i))
75 return(0);
76 else
77 return(1);
78 }
79
alph(i)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
caseht()92 caseht()
93 {
94 thresh = THRESH;
95 if (skip())
96 return;
97 noscale++;
98 thresh = atoi();
99 noscale = 0;
100 }
101
casehw()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
exword()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
suffix()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
maplow(i)219 maplow(i)
220 int i;
221 {
222 if ((i &= CMASK) < 'a')i += 'a' - 'A';
223 return(i);
224 }
225
vowel(i)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
chkvow(w)242 int *chkvow(w)
243 int *w;
244 {
245 while(--w >= wdstart)if(vowel(*w & CMASK))return(w);
246 return(0);
247 }
248
digram()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
dilook(a,b,t)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