xref: /illumos-gate/usr/src/cmd/troff/n8.c (revision e5190c10)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
327c478bd9Sstevel@tonic-gate  * The Regents of the University of California
337c478bd9Sstevel@tonic-gate  * All Rights Reserved
347c478bd9Sstevel@tonic-gate  *
357c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
367c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
377c478bd9Sstevel@tonic-gate  * contributors.
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate 
40*e5190c10Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*e5190c10Smuffin 
427c478bd9Sstevel@tonic-gate #include	<ctype.h>
437c478bd9Sstevel@tonic-gate #include	"tdef.h"
447c478bd9Sstevel@tonic-gate #include "ext.h"
457c478bd9Sstevel@tonic-gate #define	HY_BIT	0200	/* stuff in here only works for ascii */
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * troff8.c
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  * hyphenation
517c478bd9Sstevel@tonic-gate  */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate char	hbuf[NHEX];
547c478bd9Sstevel@tonic-gate char	*nexth = hbuf;
557c478bd9Sstevel@tonic-gate tchar	*hyend;
567c478bd9Sstevel@tonic-gate #define THRESH 160 /*digram goodness threshold*/
577c478bd9Sstevel@tonic-gate int	thresh = THRESH;
587c478bd9Sstevel@tonic-gate 
59*e5190c10Smuffin int
607c478bd9Sstevel@tonic-gate hyphen(wp)
617c478bd9Sstevel@tonic-gate 	tchar *wp;
627c478bd9Sstevel@tonic-gate {
63*e5190c10Smuffin 	int	j;
64*e5190c10Smuffin 	tchar *i;
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 	i = wp;
677c478bd9Sstevel@tonic-gate 	while (punct(cbits(*i++)))
687c478bd9Sstevel@tonic-gate 		;
697c478bd9Sstevel@tonic-gate 	if (!alph(cbits(*--i)))
70*e5190c10Smuffin 		return (0);
717c478bd9Sstevel@tonic-gate 	wdstart = i++;
727c478bd9Sstevel@tonic-gate 	while (alph(cbits(*i++)))
737c478bd9Sstevel@tonic-gate 		;
747c478bd9Sstevel@tonic-gate 	hyend = wdend = --i - 1;
757c478bd9Sstevel@tonic-gate 	while (punct(cbits(*i++)))
767c478bd9Sstevel@tonic-gate 		;
777c478bd9Sstevel@tonic-gate 	if (*--i)
78*e5190c10Smuffin 		return (0);
797c478bd9Sstevel@tonic-gate 	if ((wdend - wdstart - 4) < 0)
80*e5190c10Smuffin 		return (0);
817c478bd9Sstevel@tonic-gate 	hyp = hyptr;
827c478bd9Sstevel@tonic-gate 	*hyp = 0;
837c478bd9Sstevel@tonic-gate 	hyoff = 2;
847c478bd9Sstevel@tonic-gate 	if (!exword() && !suffix())
857c478bd9Sstevel@tonic-gate 		digram();
867c478bd9Sstevel@tonic-gate 	*hyp++ = 0;
877c478bd9Sstevel@tonic-gate 	if (*hyptr)
887c478bd9Sstevel@tonic-gate 		for (j = 1; j; ) {
897c478bd9Sstevel@tonic-gate 			j = 0;
907c478bd9Sstevel@tonic-gate 			for (hyp = hyptr + 1; *hyp != 0; hyp++) {
917c478bd9Sstevel@tonic-gate 				if (*(hyp - 1) > *hyp) {
927c478bd9Sstevel@tonic-gate 					j++;
937c478bd9Sstevel@tonic-gate 					i = *hyp;
947c478bd9Sstevel@tonic-gate 					*hyp = *(hyp - 1);
957c478bd9Sstevel@tonic-gate 					*(hyp - 1) = i;
967c478bd9Sstevel@tonic-gate 				}
977c478bd9Sstevel@tonic-gate 			}
987c478bd9Sstevel@tonic-gate 		}
99*e5190c10Smuffin 
100*e5190c10Smuffin 	return (0);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 
104*e5190c10Smuffin int
1057c478bd9Sstevel@tonic-gate punct(i)
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate 	if (!i || alph(i))
1087c478bd9Sstevel@tonic-gate 		return(0);
1097c478bd9Sstevel@tonic-gate 	else
1107c478bd9Sstevel@tonic-gate 		return(1);
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 
114*e5190c10Smuffin int
1157c478bd9Sstevel@tonic-gate alph(i)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate 	if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z')
1187c478bd9Sstevel@tonic-gate 		return(1);
1197c478bd9Sstevel@tonic-gate 	else
1207c478bd9Sstevel@tonic-gate 		return(0);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 
124*e5190c10Smuffin int
1257c478bd9Sstevel@tonic-gate caseht()
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate 	thresh = THRESH;
1287c478bd9Sstevel@tonic-gate 	if (skip())
129*e5190c10Smuffin 		return (0);
1307c478bd9Sstevel@tonic-gate 	noscale++;
1317c478bd9Sstevel@tonic-gate 	thresh = atoi();
1327c478bd9Sstevel@tonic-gate 	noscale = 0;
133*e5190c10Smuffin 
134*e5190c10Smuffin 	return (0);
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 
138*e5190c10Smuffin int
1397c478bd9Sstevel@tonic-gate casehw()
1407c478bd9Sstevel@tonic-gate {
141*e5190c10Smuffin 	int	i, k;
142*e5190c10Smuffin 	char	*j;
1437c478bd9Sstevel@tonic-gate 	tchar t;
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	k = 0;
1467c478bd9Sstevel@tonic-gate 	while (!skip()) {
1477c478bd9Sstevel@tonic-gate 		if ((j = nexth) >= (hbuf + NHEX - 2))
1487c478bd9Sstevel@tonic-gate 			goto full;
1497c478bd9Sstevel@tonic-gate 		for (; ; ) {
1507c478bd9Sstevel@tonic-gate 			if (ismot(t = getch()))
1517c478bd9Sstevel@tonic-gate 				continue;
1527c478bd9Sstevel@tonic-gate 			i = cbits(t);
1537c478bd9Sstevel@tonic-gate 			if (i == ' ' || i == '\n') {
1547c478bd9Sstevel@tonic-gate 				*j++ = 0;
1557c478bd9Sstevel@tonic-gate 				nexth = j;
1567c478bd9Sstevel@tonic-gate 				*j = 0;
1577c478bd9Sstevel@tonic-gate 				if (i == ' ')
1587c478bd9Sstevel@tonic-gate 					break;
1597c478bd9Sstevel@tonic-gate 				else
160*e5190c10Smuffin 					return (0);
1617c478bd9Sstevel@tonic-gate 			}
1627c478bd9Sstevel@tonic-gate 			if (i == '-') {
1637c478bd9Sstevel@tonic-gate 				k = HY_BIT;
1647c478bd9Sstevel@tonic-gate 				continue;
1657c478bd9Sstevel@tonic-gate 			}
1667c478bd9Sstevel@tonic-gate 			*j++ = maplow(i) | k;
1677c478bd9Sstevel@tonic-gate 			k = 0;
1687c478bd9Sstevel@tonic-gate 			if (j >= (hbuf + NHEX - 2))
1697c478bd9Sstevel@tonic-gate 				goto full;
1707c478bd9Sstevel@tonic-gate 		}
1717c478bd9Sstevel@tonic-gate 	}
172*e5190c10Smuffin 	return (0);
1737c478bd9Sstevel@tonic-gate full:
1747c478bd9Sstevel@tonic-gate 	errprint(gettext("exception word list full."));
1757c478bd9Sstevel@tonic-gate 	*nexth = 0;
176*e5190c10Smuffin 
177*e5190c10Smuffin 	return (0);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 
181*e5190c10Smuffin int
1827c478bd9Sstevel@tonic-gate exword()
1837c478bd9Sstevel@tonic-gate {
184*e5190c10Smuffin 	tchar *w;
185*e5190c10Smuffin 	char	*e;
1867c478bd9Sstevel@tonic-gate 	char	*save;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	e = hbuf;
1897c478bd9Sstevel@tonic-gate 	while (1) {
1907c478bd9Sstevel@tonic-gate 		save = e;
1917c478bd9Sstevel@tonic-gate 		if (*e == 0)
1927c478bd9Sstevel@tonic-gate 			return(0);
1937c478bd9Sstevel@tonic-gate 		w = wdstart;
1947c478bd9Sstevel@tonic-gate 		while (*e && w <= hyend && (*e & 0177) == maplow(cbits(*w))) {
1957c478bd9Sstevel@tonic-gate 			e++;
1967c478bd9Sstevel@tonic-gate 			w++;
1977c478bd9Sstevel@tonic-gate 		};
1987c478bd9Sstevel@tonic-gate 		if (!*e) {
1997c478bd9Sstevel@tonic-gate 			if (w-1 == hyend || (w == wdend && maplow(cbits(*w)) == 's')) {
2007c478bd9Sstevel@tonic-gate 				w = wdstart;
2017c478bd9Sstevel@tonic-gate 				for (e = save; *e; e++) {
2027c478bd9Sstevel@tonic-gate 					if (*e & HY_BIT)
2037c478bd9Sstevel@tonic-gate 						*hyp++ = w;
2047c478bd9Sstevel@tonic-gate 					if (hyp > (hyptr + NHYP - 1))
2057c478bd9Sstevel@tonic-gate 						hyp = hyptr + NHYP - 1;
2067c478bd9Sstevel@tonic-gate 					w++;
2077c478bd9Sstevel@tonic-gate 				}
2087c478bd9Sstevel@tonic-gate 				return(1);
2097c478bd9Sstevel@tonic-gate 			} else {
2107c478bd9Sstevel@tonic-gate 				e++;
2117c478bd9Sstevel@tonic-gate 				continue;
2127c478bd9Sstevel@tonic-gate 			}
2137c478bd9Sstevel@tonic-gate 		} else
2147c478bd9Sstevel@tonic-gate 			while (*e++)
2157c478bd9Sstevel@tonic-gate 				;
2167c478bd9Sstevel@tonic-gate 	}
217*e5190c10Smuffin 
218*e5190c10Smuffin 	return (0);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 
222*e5190c10Smuffin int
2237c478bd9Sstevel@tonic-gate suffix()
2247c478bd9Sstevel@tonic-gate {
225*e5190c10Smuffin 	tchar *w;
226*e5190c10Smuffin 	char	*s, *s0;
2277c478bd9Sstevel@tonic-gate 	tchar i;
2287c478bd9Sstevel@tonic-gate 	extern char	*suftab[];
2297c478bd9Sstevel@tonic-gate 	extern tchar *chkvow();
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate again:
2327c478bd9Sstevel@tonic-gate 	if (!alph(cbits(i = cbits(*hyend))))
2337c478bd9Sstevel@tonic-gate 		return(0);
2347c478bd9Sstevel@tonic-gate 	if (i < 'a')
2357c478bd9Sstevel@tonic-gate 		i -= 'A' - 'a';
2367c478bd9Sstevel@tonic-gate 	if ((s0 = suftab[i-'a']) == 0)
2377c478bd9Sstevel@tonic-gate 		return(0);
2387c478bd9Sstevel@tonic-gate 	for (; ; ) {
2397c478bd9Sstevel@tonic-gate 		if ((i = *s0 & 017) == 0)
2407c478bd9Sstevel@tonic-gate 			return(0);
2417c478bd9Sstevel@tonic-gate 		s = s0 + i - 1;
2427c478bd9Sstevel@tonic-gate 		w = hyend - 1;
2437c478bd9Sstevel@tonic-gate 		while (s > s0 && w >= wdstart && (*s & 0177) == maplow(cbits(*w))) {
2447c478bd9Sstevel@tonic-gate 			s--;
2457c478bd9Sstevel@tonic-gate 			w--;
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 		if (s == s0)
2487c478bd9Sstevel@tonic-gate 			break;
2497c478bd9Sstevel@tonic-gate 		s0 += i;
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 	s = s0 + i - 1;
2527c478bd9Sstevel@tonic-gate 	w = hyend;
2537c478bd9Sstevel@tonic-gate 	if (*s0 & HY_BIT)
2547c478bd9Sstevel@tonic-gate 		goto mark;
2557c478bd9Sstevel@tonic-gate 	while (s > s0) {
2567c478bd9Sstevel@tonic-gate 		w--;
2577c478bd9Sstevel@tonic-gate 		if (*s-- & HY_BIT) {
2587c478bd9Sstevel@tonic-gate mark:
2597c478bd9Sstevel@tonic-gate 			hyend = w - 1;
2607c478bd9Sstevel@tonic-gate 			if (*s0 & 0100)
2617c478bd9Sstevel@tonic-gate 				continue;
2627c478bd9Sstevel@tonic-gate 			if (!chkvow(w))
2637c478bd9Sstevel@tonic-gate 				return(0);
2647c478bd9Sstevel@tonic-gate 			*hyp++ = w;
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 	}
2677c478bd9Sstevel@tonic-gate 	if (*s0 & 040)
2687c478bd9Sstevel@tonic-gate 		return(0);
2697c478bd9Sstevel@tonic-gate 	if (exword())
2707c478bd9Sstevel@tonic-gate 		return(1);
2717c478bd9Sstevel@tonic-gate 	goto again;
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 
275*e5190c10Smuffin int
2767c478bd9Sstevel@tonic-gate maplow(i)
277*e5190c10Smuffin int	i;
2787c478bd9Sstevel@tonic-gate {
2797c478bd9Sstevel@tonic-gate 	if (ischar(i) && isupper(i))
2807c478bd9Sstevel@tonic-gate 		i = tolower(i);
2817c478bd9Sstevel@tonic-gate 	return(i);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 
285*e5190c10Smuffin int
2867c478bd9Sstevel@tonic-gate vowel(i)
2877c478bd9Sstevel@tonic-gate int	i;
2887c478bd9Sstevel@tonic-gate {
2897c478bd9Sstevel@tonic-gate 	switch (maplow(i)) {
2907c478bd9Sstevel@tonic-gate 	case 'a':
2917c478bd9Sstevel@tonic-gate 	case 'e':
2927c478bd9Sstevel@tonic-gate 	case 'i':
2937c478bd9Sstevel@tonic-gate 	case 'o':
2947c478bd9Sstevel@tonic-gate 	case 'u':
2957c478bd9Sstevel@tonic-gate 	case 'y':
2967c478bd9Sstevel@tonic-gate 		return(1);
2977c478bd9Sstevel@tonic-gate 	default:
2987c478bd9Sstevel@tonic-gate 		return(0);
2997c478bd9Sstevel@tonic-gate 	}
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate tchar *chkvow(w)
3047c478bd9Sstevel@tonic-gate tchar *w;
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate 	while (--w >= wdstart)
3077c478bd9Sstevel@tonic-gate 		if (vowel(cbits(*w)))
3087c478bd9Sstevel@tonic-gate 			return(w);
3097c478bd9Sstevel@tonic-gate 	return(0);
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 
313*e5190c10Smuffin int
3147c478bd9Sstevel@tonic-gate digram()
3157c478bd9Sstevel@tonic-gate {
316*e5190c10Smuffin 	tchar *w;
317*e5190c10Smuffin 	int	val;
3187c478bd9Sstevel@tonic-gate 	tchar * nhyend, *maxw;
3197c478bd9Sstevel@tonic-gate 	int	maxval;
3207c478bd9Sstevel@tonic-gate 	extern char	bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate again:
3237c478bd9Sstevel@tonic-gate 	if (!(w = chkvow(hyend + 1)))
324*e5190c10Smuffin 		return (0);
3257c478bd9Sstevel@tonic-gate 	hyend = w;
3267c478bd9Sstevel@tonic-gate 	if (!(w = chkvow(hyend)))
327*e5190c10Smuffin 		return (0);
3287c478bd9Sstevel@tonic-gate 	nhyend = w;
3297c478bd9Sstevel@tonic-gate 	maxval = 0;
3307c478bd9Sstevel@tonic-gate 	w--;
3317c478bd9Sstevel@tonic-gate 	while ((++w < hyend) && (w < (wdend - 1))) {
3327c478bd9Sstevel@tonic-gate 		val = 1;
3337c478bd9Sstevel@tonic-gate 		if (w == wdstart)
3347c478bd9Sstevel@tonic-gate 			val *= dilook('a', cbits(*w), bxh);
3357c478bd9Sstevel@tonic-gate 		else if (w == wdstart + 1)
3367c478bd9Sstevel@tonic-gate 			val *= dilook(cbits(*(w-1)), cbits(*w), bxxh);
3377c478bd9Sstevel@tonic-gate 		else
3387c478bd9Sstevel@tonic-gate 			val *= dilook(cbits(*(w-1)), cbits(*w), xxh);
3397c478bd9Sstevel@tonic-gate 		val *= dilook(cbits(*w), cbits(*(w+1)), xhx);
3407c478bd9Sstevel@tonic-gate 		val *= dilook(cbits(*(w+1)), cbits(*(w+2)), hxx);
3417c478bd9Sstevel@tonic-gate 		if (val > maxval) {
3427c478bd9Sstevel@tonic-gate 			maxval = val;
3437c478bd9Sstevel@tonic-gate 			maxw = w + 1;
3447c478bd9Sstevel@tonic-gate 		}
3457c478bd9Sstevel@tonic-gate 	}
3467c478bd9Sstevel@tonic-gate 	hyend = nhyend;
3477c478bd9Sstevel@tonic-gate 	if (maxval > thresh)
3487c478bd9Sstevel@tonic-gate 		*hyp++ = maxw;
3497c478bd9Sstevel@tonic-gate 	goto again;
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 
353*e5190c10Smuffin int
3547c478bd9Sstevel@tonic-gate dilook(a, b, t)
3557c478bd9Sstevel@tonic-gate int	a, b;
3567c478bd9Sstevel@tonic-gate char	t[26][13];
3577c478bd9Sstevel@tonic-gate {
358*e5190c10Smuffin 	int	i, j;
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
3617c478bd9Sstevel@tonic-gate 	if (!(j & 01))
3627c478bd9Sstevel@tonic-gate 		i >>= 4;
3637c478bd9Sstevel@tonic-gate 	return(i & 017);
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 
367