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