xref: /onnv-gate/usr/src/cmd/troff/n8.c (revision 217:758a5315b0d7)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
320Sstevel@tonic-gate  * The Regents of the University of California
330Sstevel@tonic-gate  * All Rights Reserved
340Sstevel@tonic-gate  *
350Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
360Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
370Sstevel@tonic-gate  * contributors.
380Sstevel@tonic-gate  */
390Sstevel@tonic-gate 
40*217Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*217Smuffin 
420Sstevel@tonic-gate #include	<ctype.h>
430Sstevel@tonic-gate #include	"tdef.h"
440Sstevel@tonic-gate #include "ext.h"
450Sstevel@tonic-gate #define	HY_BIT	0200	/* stuff in here only works for ascii */
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * troff8.c
490Sstevel@tonic-gate  *
500Sstevel@tonic-gate  * hyphenation
510Sstevel@tonic-gate  */
520Sstevel@tonic-gate 
530Sstevel@tonic-gate char	hbuf[NHEX];
540Sstevel@tonic-gate char	*nexth = hbuf;
550Sstevel@tonic-gate tchar	*hyend;
560Sstevel@tonic-gate #define THRESH 160 /*digram goodness threshold*/
570Sstevel@tonic-gate int	thresh = THRESH;
580Sstevel@tonic-gate 
59*217Smuffin int
hyphen(wp)600Sstevel@tonic-gate hyphen(wp)
610Sstevel@tonic-gate 	tchar *wp;
620Sstevel@tonic-gate {
63*217Smuffin 	int	j;
64*217Smuffin 	tchar *i;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	i = wp;
670Sstevel@tonic-gate 	while (punct(cbits(*i++)))
680Sstevel@tonic-gate 		;
690Sstevel@tonic-gate 	if (!alph(cbits(*--i)))
70*217Smuffin 		return (0);
710Sstevel@tonic-gate 	wdstart = i++;
720Sstevel@tonic-gate 	while (alph(cbits(*i++)))
730Sstevel@tonic-gate 		;
740Sstevel@tonic-gate 	hyend = wdend = --i - 1;
750Sstevel@tonic-gate 	while (punct(cbits(*i++)))
760Sstevel@tonic-gate 		;
770Sstevel@tonic-gate 	if (*--i)
78*217Smuffin 		return (0);
790Sstevel@tonic-gate 	if ((wdend - wdstart - 4) < 0)
80*217Smuffin 		return (0);
810Sstevel@tonic-gate 	hyp = hyptr;
820Sstevel@tonic-gate 	*hyp = 0;
830Sstevel@tonic-gate 	hyoff = 2;
840Sstevel@tonic-gate 	if (!exword() && !suffix())
850Sstevel@tonic-gate 		digram();
860Sstevel@tonic-gate 	*hyp++ = 0;
870Sstevel@tonic-gate 	if (*hyptr)
880Sstevel@tonic-gate 		for (j = 1; j; ) {
890Sstevel@tonic-gate 			j = 0;
900Sstevel@tonic-gate 			for (hyp = hyptr + 1; *hyp != 0; hyp++) {
910Sstevel@tonic-gate 				if (*(hyp - 1) > *hyp) {
920Sstevel@tonic-gate 					j++;
930Sstevel@tonic-gate 					i = *hyp;
940Sstevel@tonic-gate 					*hyp = *(hyp - 1);
950Sstevel@tonic-gate 					*(hyp - 1) = i;
960Sstevel@tonic-gate 				}
970Sstevel@tonic-gate 			}
980Sstevel@tonic-gate 		}
99*217Smuffin 
100*217Smuffin 	return (0);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 
104*217Smuffin int
punct(i)1050Sstevel@tonic-gate punct(i)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate 	if (!i || alph(i))
1080Sstevel@tonic-gate 		return(0);
1090Sstevel@tonic-gate 	else
1100Sstevel@tonic-gate 		return(1);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 
114*217Smuffin int
alph(i)1150Sstevel@tonic-gate alph(i)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate 	if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z')
1180Sstevel@tonic-gate 		return(1);
1190Sstevel@tonic-gate 	else
1200Sstevel@tonic-gate 		return(0);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 
124*217Smuffin int
caseht()1250Sstevel@tonic-gate caseht()
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate 	thresh = THRESH;
1280Sstevel@tonic-gate 	if (skip())
129*217Smuffin 		return (0);
1300Sstevel@tonic-gate 	noscale++;
1310Sstevel@tonic-gate 	thresh = atoi();
1320Sstevel@tonic-gate 	noscale = 0;
133*217Smuffin 
134*217Smuffin 	return (0);
1350Sstevel@tonic-gate }
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 
138*217Smuffin int
casehw()1390Sstevel@tonic-gate casehw()
1400Sstevel@tonic-gate {
141*217Smuffin 	int	i, k;
142*217Smuffin 	char	*j;
1430Sstevel@tonic-gate 	tchar t;
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	k = 0;
1460Sstevel@tonic-gate 	while (!skip()) {
1470Sstevel@tonic-gate 		if ((j = nexth) >= (hbuf + NHEX - 2))
1480Sstevel@tonic-gate 			goto full;
1490Sstevel@tonic-gate 		for (; ; ) {
1500Sstevel@tonic-gate 			if (ismot(t = getch()))
1510Sstevel@tonic-gate 				continue;
1520Sstevel@tonic-gate 			i = cbits(t);
1530Sstevel@tonic-gate 			if (i == ' ' || i == '\n') {
1540Sstevel@tonic-gate 				*j++ = 0;
1550Sstevel@tonic-gate 				nexth = j;
1560Sstevel@tonic-gate 				*j = 0;
1570Sstevel@tonic-gate 				if (i == ' ')
1580Sstevel@tonic-gate 					break;
1590Sstevel@tonic-gate 				else
160*217Smuffin 					return (0);
1610Sstevel@tonic-gate 			}
1620Sstevel@tonic-gate 			if (i == '-') {
1630Sstevel@tonic-gate 				k = HY_BIT;
1640Sstevel@tonic-gate 				continue;
1650Sstevel@tonic-gate 			}
1660Sstevel@tonic-gate 			*j++ = maplow(i) | k;
1670Sstevel@tonic-gate 			k = 0;
1680Sstevel@tonic-gate 			if (j >= (hbuf + NHEX - 2))
1690Sstevel@tonic-gate 				goto full;
1700Sstevel@tonic-gate 		}
1710Sstevel@tonic-gate 	}
172*217Smuffin 	return (0);
1730Sstevel@tonic-gate full:
1740Sstevel@tonic-gate 	errprint(gettext("exception word list full."));
1750Sstevel@tonic-gate 	*nexth = 0;
176*217Smuffin 
177*217Smuffin 	return (0);
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 
181*217Smuffin int
exword()1820Sstevel@tonic-gate exword()
1830Sstevel@tonic-gate {
184*217Smuffin 	tchar *w;
185*217Smuffin 	char	*e;
1860Sstevel@tonic-gate 	char	*save;
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	e = hbuf;
1890Sstevel@tonic-gate 	while (1) {
1900Sstevel@tonic-gate 		save = e;
1910Sstevel@tonic-gate 		if (*e == 0)
1920Sstevel@tonic-gate 			return(0);
1930Sstevel@tonic-gate 		w = wdstart;
1940Sstevel@tonic-gate 		while (*e && w <= hyend && (*e & 0177) == maplow(cbits(*w))) {
1950Sstevel@tonic-gate 			e++;
1960Sstevel@tonic-gate 			w++;
1970Sstevel@tonic-gate 		};
1980Sstevel@tonic-gate 		if (!*e) {
1990Sstevel@tonic-gate 			if (w-1 == hyend || (w == wdend && maplow(cbits(*w)) == 's')) {
2000Sstevel@tonic-gate 				w = wdstart;
2010Sstevel@tonic-gate 				for (e = save; *e; e++) {
2020Sstevel@tonic-gate 					if (*e & HY_BIT)
2030Sstevel@tonic-gate 						*hyp++ = w;
2040Sstevel@tonic-gate 					if (hyp > (hyptr + NHYP - 1))
2050Sstevel@tonic-gate 						hyp = hyptr + NHYP - 1;
2060Sstevel@tonic-gate 					w++;
2070Sstevel@tonic-gate 				}
2080Sstevel@tonic-gate 				return(1);
2090Sstevel@tonic-gate 			} else {
2100Sstevel@tonic-gate 				e++;
2110Sstevel@tonic-gate 				continue;
2120Sstevel@tonic-gate 			}
2130Sstevel@tonic-gate 		} else
2140Sstevel@tonic-gate 			while (*e++)
2150Sstevel@tonic-gate 				;
2160Sstevel@tonic-gate 	}
217*217Smuffin 
218*217Smuffin 	return (0);
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 
222*217Smuffin int
suffix()2230Sstevel@tonic-gate suffix()
2240Sstevel@tonic-gate {
225*217Smuffin 	tchar *w;
226*217Smuffin 	char	*s, *s0;
2270Sstevel@tonic-gate 	tchar i;
2280Sstevel@tonic-gate 	extern char	*suftab[];
2290Sstevel@tonic-gate 	extern tchar *chkvow();
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate again:
2320Sstevel@tonic-gate 	if (!alph(cbits(i = cbits(*hyend))))
2330Sstevel@tonic-gate 		return(0);
2340Sstevel@tonic-gate 	if (i < 'a')
2350Sstevel@tonic-gate 		i -= 'A' - 'a';
2360Sstevel@tonic-gate 	if ((s0 = suftab[i-'a']) == 0)
2370Sstevel@tonic-gate 		return(0);
2380Sstevel@tonic-gate 	for (; ; ) {
2390Sstevel@tonic-gate 		if ((i = *s0 & 017) == 0)
2400Sstevel@tonic-gate 			return(0);
2410Sstevel@tonic-gate 		s = s0 + i - 1;
2420Sstevel@tonic-gate 		w = hyend - 1;
2430Sstevel@tonic-gate 		while (s > s0 && w >= wdstart && (*s & 0177) == maplow(cbits(*w))) {
2440Sstevel@tonic-gate 			s--;
2450Sstevel@tonic-gate 			w--;
2460Sstevel@tonic-gate 		}
2470Sstevel@tonic-gate 		if (s == s0)
2480Sstevel@tonic-gate 			break;
2490Sstevel@tonic-gate 		s0 += i;
2500Sstevel@tonic-gate 	}
2510Sstevel@tonic-gate 	s = s0 + i - 1;
2520Sstevel@tonic-gate 	w = hyend;
2530Sstevel@tonic-gate 	if (*s0 & HY_BIT)
2540Sstevel@tonic-gate 		goto mark;
2550Sstevel@tonic-gate 	while (s > s0) {
2560Sstevel@tonic-gate 		w--;
2570Sstevel@tonic-gate 		if (*s-- & HY_BIT) {
2580Sstevel@tonic-gate mark:
2590Sstevel@tonic-gate 			hyend = w - 1;
2600Sstevel@tonic-gate 			if (*s0 & 0100)
2610Sstevel@tonic-gate 				continue;
2620Sstevel@tonic-gate 			if (!chkvow(w))
2630Sstevel@tonic-gate 				return(0);
2640Sstevel@tonic-gate 			*hyp++ = w;
2650Sstevel@tonic-gate 		}
2660Sstevel@tonic-gate 	}
2670Sstevel@tonic-gate 	if (*s0 & 040)
2680Sstevel@tonic-gate 		return(0);
2690Sstevel@tonic-gate 	if (exword())
2700Sstevel@tonic-gate 		return(1);
2710Sstevel@tonic-gate 	goto again;
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate 
275*217Smuffin int
maplow(i)2760Sstevel@tonic-gate maplow(i)
277*217Smuffin int	i;
2780Sstevel@tonic-gate {
2790Sstevel@tonic-gate 	if (ischar(i) && isupper(i))
2800Sstevel@tonic-gate 		i = tolower(i);
2810Sstevel@tonic-gate 	return(i);
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 
285*217Smuffin int
vowel(i)2860Sstevel@tonic-gate vowel(i)
2870Sstevel@tonic-gate int	i;
2880Sstevel@tonic-gate {
2890Sstevel@tonic-gate 	switch (maplow(i)) {
2900Sstevel@tonic-gate 	case 'a':
2910Sstevel@tonic-gate 	case 'e':
2920Sstevel@tonic-gate 	case 'i':
2930Sstevel@tonic-gate 	case 'o':
2940Sstevel@tonic-gate 	case 'u':
2950Sstevel@tonic-gate 	case 'y':
2960Sstevel@tonic-gate 		return(1);
2970Sstevel@tonic-gate 	default:
2980Sstevel@tonic-gate 		return(0);
2990Sstevel@tonic-gate 	}
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 
chkvow(w)3030Sstevel@tonic-gate tchar *chkvow(w)
3040Sstevel@tonic-gate tchar *w;
3050Sstevel@tonic-gate {
3060Sstevel@tonic-gate 	while (--w >= wdstart)
3070Sstevel@tonic-gate 		if (vowel(cbits(*w)))
3080Sstevel@tonic-gate 			return(w);
3090Sstevel@tonic-gate 	return(0);
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 
313*217Smuffin int
digram()3140Sstevel@tonic-gate digram()
3150Sstevel@tonic-gate {
316*217Smuffin 	tchar *w;
317*217Smuffin 	int	val;
3180Sstevel@tonic-gate 	tchar * nhyend, *maxw;
3190Sstevel@tonic-gate 	int	maxval;
3200Sstevel@tonic-gate 	extern char	bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate again:
3230Sstevel@tonic-gate 	if (!(w = chkvow(hyend + 1)))
324*217Smuffin 		return (0);
3250Sstevel@tonic-gate 	hyend = w;
3260Sstevel@tonic-gate 	if (!(w = chkvow(hyend)))
327*217Smuffin 		return (0);
3280Sstevel@tonic-gate 	nhyend = w;
3290Sstevel@tonic-gate 	maxval = 0;
3300Sstevel@tonic-gate 	w--;
3310Sstevel@tonic-gate 	while ((++w < hyend) && (w < (wdend - 1))) {
3320Sstevel@tonic-gate 		val = 1;
3330Sstevel@tonic-gate 		if (w == wdstart)
3340Sstevel@tonic-gate 			val *= dilook('a', cbits(*w), bxh);
3350Sstevel@tonic-gate 		else if (w == wdstart + 1)
3360Sstevel@tonic-gate 			val *= dilook(cbits(*(w-1)), cbits(*w), bxxh);
3370Sstevel@tonic-gate 		else
3380Sstevel@tonic-gate 			val *= dilook(cbits(*(w-1)), cbits(*w), xxh);
3390Sstevel@tonic-gate 		val *= dilook(cbits(*w), cbits(*(w+1)), xhx);
3400Sstevel@tonic-gate 		val *= dilook(cbits(*(w+1)), cbits(*(w+2)), hxx);
3410Sstevel@tonic-gate 		if (val > maxval) {
3420Sstevel@tonic-gate 			maxval = val;
3430Sstevel@tonic-gate 			maxw = w + 1;
3440Sstevel@tonic-gate 		}
3450Sstevel@tonic-gate 	}
3460Sstevel@tonic-gate 	hyend = nhyend;
3470Sstevel@tonic-gate 	if (maxval > thresh)
3480Sstevel@tonic-gate 		*hyp++ = maxw;
3490Sstevel@tonic-gate 	goto again;
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 
353*217Smuffin int
dilook(a,b,t)3540Sstevel@tonic-gate dilook(a, b, t)
3550Sstevel@tonic-gate int	a, b;
3560Sstevel@tonic-gate char	t[26][13];
3570Sstevel@tonic-gate {
358*217Smuffin 	int	i, j;
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate 	i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
3610Sstevel@tonic-gate 	if (!(j & 01))
3620Sstevel@tonic-gate 		i >>= 4;
3630Sstevel@tonic-gate 	return(i & 017);
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 
367