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