1 /* $MirOS: src/usr.bin/oldroff/nroff/n8.c,v 1.3 2008/11/08 23:04:42 tg Exp $ */
2
3 /*-
4 * Copyright (c) 1979, 1980, 1981, 1986, 1988, 1990, 1991, 1992
5 * The Regents of the University of California.
6 * Copyright (C) Caldera International Inc. 2001-2002.
7 * Copyright (c) 2003, 2004
8 * Thorsten "mirabilos" Glaser <tg@mirbsd.org>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms,
12 * with or without modification, are permitted provided
13 * that the following conditions are met:
14 *
15 * Redistributions of source code and documentation must retain
16 * the above copyright notice, this list of conditions and the
17 * following disclaimer. Redistributions in binary form must
18 * reproduce the above copyright notice, this list of conditions
19 * and the following disclaimer in the documentation and/or other
20 * materials provided with the distribution.
21 *
22 * All advertising materials mentioning features or use of this
23 * software must display the following acknowledgement:
24 * This product includes software developed or owned by
25 * Caldera International, Inc.
26 *
27 * Neither the name of Caldera International, Inc. nor the names
28 * of other contributors may be used to endorse or promote products
29 * derived from this software without specific prior written permission.
30 *
31 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
32 * INTERNATIONAL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
33 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
36 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
41 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
42 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44
45 #include <sys/cdefs.h>
46 __SCCSID("@(#)n8.c 4.2 (Berkeley) 4/18/91");
47 __RCSID("$MirOS: src/usr.bin/oldroff/nroff/n8.c,v 1.3 2008/11/08 23:04:42 tg Exp $");
48
49 #include "tdef.h"
50
51 /*
52 troff8.c
53
54 hyphenation
55 */
56
57 char hbuf[NHEX];
58 char *nexth = hbuf;
59 int *hyend;
60 extern int *wdstart, *wdend;
61 extern int *hyptr[];
62 extern int **hyp;
63 extern int hyoff;
64 extern int noscale;
65 extern int xxx;
66 #define THRESH 160 /*digram goodness threshold*/
67 int thresh = THRESH;
68
hyphen(wp)69 hyphen(wp)
70 int *wp;
71 {
72 register *i, j;
73
74 i = wp;
75 while(punct(*i++))
76 ;
77 if (!alph(*--i))
78 return;
79 wdstart = i++;
80 while(alph(*i++))
81 ;
82 hyend = wdend = --i-1;
83 while(punct(*i++))
84 ;
85 if (*--i)
86 return;
87 if ((wdend-wdstart-4) < 0)
88 return;
89 hyp = hyptr;
90 *hyp = 0;
91 hyoff = 2;
92 if (!exword() && !suffix())
93 digram();
94 *hyp++ = 0;
95 if (*hyptr) for(j = 1; j;) {
96 j = 0;
97 for(hyp = hyptr+1; *hyp != 0; hyp++) {
98 if (*(hyp-1) > *hyp) {
99 j++;
100 i = *hyp;
101 *hyp = *(hyp-1);
102 *(hyp-1) = i;
103 }
104 }
105 }
106 }
107
punct(i)108 punct(i)
109 int i;
110 {
111 if (!i || alph(i))
112 return(0);
113 else
114 return(1);
115 }
116
alph(i)117 alph(i)
118 int i;
119 {
120 register j;
121
122 j = i & CMASK;
123 if (((j >= 'A') && (j <= 'Z')) || ((j >= 'a') && (j <= 'z')))
124 return(1);
125 else
126 return(0);
127 }
128
caseht()129 caseht()
130 {
131 thresh = THRESH;
132 if (skip())
133 return;
134 noscale++;
135 thresh = nr_atoi();
136 noscale = 0;
137 }
138
casehw()139 casehw()
140 {
141 register i, k;
142 register char *j;
143
144 k = 0;
145 while(!skip()) {
146 if ((j = nexth) >= (hbuf + NHEX - 2))
147 goto full;
148 for (;;) {
149 if ((i = getch()) & MOT)
150 continue;
151 if (((i &= CMASK) == ' ') || (i == '\n')) {
152 *j++ = 0;
153 nexth = j;
154 *j = 0;
155 if (i == ' ')
156 break;
157 else
158 return;
159 }
160 if (i == '-') {
161 k = 0200;
162 continue;
163 }
164 *j++ = maplow(i) | k;
165 k = 0;
166 if (j >= (hbuf + NHEX - 2))
167 goto full;
168 }
169 }
170 return;
171 full:
172 prstr("Exception word list full.\n");
173 *nexth = 0;
174 }
175
exword()176 exword()
177 {
178 register int *w;
179 register char *e;
180 char *save;
181
182 e = hbuf;
183 while(1) {
184 save = e;
185 if (*e == 0)return(0);
186 w = wdstart;
187 while((*e && (w <= hyend)) &&
188 ((*e & 0177) == maplow(*w & CMASK))) {e++; w++;};
189 if (!*e) {
190 if (((w-1) == hyend) ||
191 ((w == wdend) && (maplow(*w & CMASK) == 's'))) {
192 w = wdstart;
193 for(e = save; *e; e++) {
194 if (*e & 0200)*hyp++ = w;
195 if (hyp > (hyptr+NHYP-1))
196 hyp = hyptr+NHYP-1;
197 w++;
198 }
199 return(1);
200 }else{e++; continue;}
201 }else while(*e++);
202 }
203 }
204
suffix()205 suffix()
206 {
207 register int *w;
208 register char *s, *s0;
209 int i;
210 extern char *suftab[];
211 extern int *chkvow();
212
213 again:
214 if (!alph(i = *hyend & CMASK))
215 return(0);
216 if (i < 'a')
217 i -= 'A'-'a';
218 if ((s0 = suftab[i-'a']) == 0)
219 return(0);
220 for (;;) {
221 if ((i = *s0 & 017) == 0)
222 return(0);
223 s = s0 + i - 1;
224 w = hyend - 1;
225 while(((s > s0) && (w >= wdstart)) &&
226 ((*s & 0177) == maplow(*w))) {
227 s--;
228 w--;
229 }
230 if (s == s0)
231 break;
232 s0 += i;
233 }
234 s = s0 + i - 1;
235 w = hyend;
236 if (*s0 & 0200) goto mark;
237 while(s > s0) {
238 w--;
239 if (*s-- & 0200) {
240 mark:
241 hyend = w - 1;
242 if (*s0 & 0100)
243 continue;
244 if (!chkvow(w))
245 return(0);
246 *hyp++ = w;
247 }
248 }
249 if (*s0 & 040)
250 return(0);
251 if (exword())
252 return(1);
253 goto again;
254 }
255
maplow(i)256 maplow(i)
257 int i;
258 {
259 if ((i &= CMASK) < 'a')i += 'a' - 'A';
260 return(i);
261 }
262
vowel(i)263 vowel(i)
264 int i;
265 {
266 switch(maplow(i)) {
267 case 'a':
268 case 'e':
269 case 'i':
270 case 'o':
271 case 'u':
272 case 'y':
273 return(1);
274 default:
275 return(0);
276 }
277 }
278
chkvow(w)279 int *chkvow(w)
280 int *w;
281 {
282 while(--w >= wdstart)if(vowel(*w & CMASK))return(w);
283 return(0);
284 }
285
digram()286 digram() {
287 register *w, val;
288 int *nhyend, *maxw, maxval;
289 extern char bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
290
291 again:
292 if (!(w=chkvow(hyend+1)))return;
293 hyend = w;
294 if (!(w=chkvow(hyend)))return;
295 nhyend = w;
296 maxval = 0;
297 w--;
298 while((++w < hyend) && (w < (wdend-1))) {
299 val = 1;
300 if (w == wdstart)val *= dilook('a',*w,bxh);
301 else if(w == wdstart+1)val *= dilook(*(w-1),*w,bxxh);
302 else val *= dilook(*(w-1),*w,xxh);
303 val *= dilook(*w, *(w+1), xhx);
304 val *= dilook(*(w+1), *(w+2), hxx);
305 if (val > maxval) {
306 maxval = val;
307 maxw = w + 1;
308 }
309 }
310 hyend = nhyend;
311 if (maxval > thresh)*hyp++ = maxw;
312 goto again;
313 }
314
dilook(a,b,t)315 dilook(a,b,t)
316 int a, b;
317 char t[26][13];
318 {
319 register i, j;
320
321 i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
322 if (!(j & 01))i >>= 4;
323 return(i & 017);
324 }
325