Commit | Line | Data |
---|---|---|
161392db RH |
1 | #ifndef lint |
2 | static char sccsid[] = "@(#)n8.c 4.1 %G%"; | |
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 | } |