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