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