xref: /csrg-svn/usr.bin/colcrt/colcrt.c (revision 17014)
1*17014Ssam static char *sccsid = "@(#)colcrt.c	4.3 (Berkeley) 08/25/84";
2*17014Ssam 
3984Sbill #include <stdio.h>
4984Sbill /*
5984Sbill  * colcrt - replaces col for crts with new nroff esp. when using tbl.
6984Sbill  * Bill Joy UCB July 14, 1977
7984Sbill  *
8984Sbill  * This filter uses a screen buffer, 267 half-lines by 132 columns.
9984Sbill  * It interprets the up and down sequences generated by the new
10984Sbill  * nroff when used with tbl and by \u \d and \r.
11984Sbill  * General overstriking doesn't work correctly.
12984Sbill  * Underlining is split onto multiple lines, etc.
13984Sbill  *
14984Sbill  * Option - suppresses all underlining.
15984Sbill  * Option -2 forces printing of all half lines.
16984Sbill  */
17984Sbill 
18984Sbill char	page[267][132];
19984Sbill 
20984Sbill int	outline = 1;
21984Sbill int	outcol;
22984Sbill 
233464Sroot char	buf[BUFSIZ];
24984Sbill char	suppresul;
25984Sbill char	printall;
26984Sbill 
27984Sbill char	*progname;
28984Sbill FILE	*f;
29984Sbill 
30984Sbill main(argc, argv)
31984Sbill 	int argc;
32984Sbill 	char *argv[];
33984Sbill {
34984Sbill 	register c;
35984Sbill 	register char *cp, *dp;
36984Sbill 
37984Sbill 	argc--;
38984Sbill 	progname = *argv++;
39984Sbill 	while (argc > 0 && argv[0][0] == '-') {
40984Sbill 		switch (argv[0][1]) {
41984Sbill 			case 0:
42984Sbill 				suppresul = 1;
43984Sbill 				break;
44984Sbill 			case '2':
45984Sbill 				printall = 1;
46984Sbill 				break;
47984Sbill 			default:
48984Sbill 				printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
49984Sbill 				fflush(stdout);
50984Sbill 				exit(1);
51984Sbill 		}
52984Sbill 		argc--;
53984Sbill 		argv++;
54984Sbill 	}
55984Sbill 	setbuf(stdout, buf);
56984Sbill 	do {
57984Sbill 		if (argc > 0) {
58984Sbill 			close(0);
59984Sbill 			if ((f=fopen(argv[0], "r")
60984Sbill ) < 0) {
61984Sbill 				fflush(stdout);
62984Sbill 				perror(argv[0]);
63984Sbill 				fflush(stdout);
64984Sbill 				exit (1);
65984Sbill 			}
66984Sbill 			argc--;
67984Sbill 			argv++;
68984Sbill 		}
69984Sbill 		for (;;) {
70984Sbill 			c = getc(stdin);
71984Sbill 			if (c == -1) {
72984Sbill 				pflush(outline);
73984Sbill 				fflush(stdout);
74984Sbill 				break;
75984Sbill 			}
76984Sbill 			switch (c) {
77984Sbill 				case '\n':
78984Sbill 					if (outline >= 265)
79984Sbill 						pflush(62);
80984Sbill 					outline += 2;
81984Sbill 					outcol = 0;
82984Sbill 					continue;
83984Sbill 				case '\016':
84984Sbill 					case '\017':
85984Sbill 					continue;
86984Sbill 				case 033:
87984Sbill 					c = getc(stdin);
88984Sbill 					switch (c) {
89984Sbill 						case '9':
90984Sbill 							if (outline >= 266)
91984Sbill 								pflush(62);
92984Sbill 							outline++;
93984Sbill 							continue;
94984Sbill 						case '8':
95984Sbill 							if (outline >= 1)
96984Sbill 								outline--;
97984Sbill 							continue;
98984Sbill 						case '7':
99984Sbill 							outline -= 2;
100984Sbill 							if (outline < 0)
101984Sbill 								outline = 0;
102984Sbill 							continue;
103984Sbill 						default:
104984Sbill 							continue;
105984Sbill 					}
106984Sbill 				case '\b':
107984Sbill 					if (outcol)
108984Sbill 						outcol--;
109984Sbill 					continue;
110984Sbill 				case '\t':
111984Sbill 					outcol += 8;
112984Sbill 					outcol &= ~7;
113984Sbill 					outcol--;
114984Sbill 					c = ' ';
115984Sbill 				default:
116984Sbill 					if (outcol >= 132) {
117984Sbill 						outcol++;
118984Sbill 						continue;
119984Sbill 					}
120984Sbill 					cp = &page[outline][outcol];
121984Sbill 					outcol++;
122984Sbill 					if (c == '_') {
123984Sbill 						if (suppresul)
124984Sbill 							continue;
125984Sbill 						cp += 132;
126984Sbill 						c = '-';
127984Sbill 					}
128984Sbill 					if (*cp == 0) {
129984Sbill 						*cp = c;
130984Sbill 						dp = cp - outcol;
131984Sbill 						for (cp--; cp >= dp && *cp == 0; cp--)
132984Sbill 							*cp = ' ';
133984Sbill 					} else
134984Sbill 						if (plus(c, *cp) || plus(*cp, c))
135984Sbill 							*cp = '+';
136984Sbill 						else if (*cp == ' ' || *cp == 0)
137984Sbill 							*cp = c;
138984Sbill 					continue;
139984Sbill 			}
140984Sbill 		}
141984Sbill 	} while (argc > 0);
142984Sbill 	fflush(stdout);
143984Sbill 	exit(0);
144984Sbill }
145984Sbill 
146984Sbill plus(c, d)
147984Sbill 	char c, d;
148984Sbill {
149984Sbill 
150984Sbill 	return (c == '|' && d == '-' || d == '_');
151984Sbill }
152984Sbill 
153984Sbill int first;
154984Sbill 
155984Sbill pflush(ol)
156984Sbill 	int ol;
157984Sbill {
158984Sbill 	register int i, j;
159984Sbill 	register char *cp;
160984Sbill 	char lastomit;
161984Sbill 	int l;
162984Sbill 
163984Sbill 	l = ol;
164984Sbill 	lastomit = 0;
165984Sbill 	if (l > 266)
166984Sbill 		l = 266;
167984Sbill 	else
168984Sbill 		l |= 1;
169984Sbill 	for (i = first | 1; i < l; i++) {
170984Sbill 		move(i, i - 1);
171984Sbill 		move(i, i + 1);
172984Sbill 	}
173984Sbill 	for (i = first; i < l; i++) {
174984Sbill 		cp = page[i];
175984Sbill 		if (printall == 0 && lastomit == 0 && *cp == 0) {
176984Sbill 			lastomit = 1;
177984Sbill 			continue;
178984Sbill 		}
179984Sbill 		lastomit = 0;
180984Sbill 		printf("%s\n", cp);
181984Sbill 	}
182*17014Ssam 	bcopy(page[ol], page, (267 - ol) * 132);
183*17014Ssam 	bzero(page[267- ol], ol * 132);
184984Sbill 	outline -= ol;
185984Sbill 	outcol = 0;
186984Sbill 	first = 1;
187984Sbill }
188*17014Ssam 
189984Sbill move(l, m)
190984Sbill 	int l, m;
191984Sbill {
192984Sbill 	register char *cp, *dp;
193984Sbill 
194984Sbill 	for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
195984Sbill 		switch (*cp) {
196984Sbill 			case '|':
197984Sbill 				if (*dp != ' ' && *dp != '|' && *dp != 0)
198984Sbill 					return;
199984Sbill 				break;
200984Sbill 			case ' ':
201984Sbill 				break;
202984Sbill 			default:
203984Sbill 				return;
204984Sbill 		}
205984Sbill 	}
206984Sbill 	if (*cp == 0) {
207984Sbill 		for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
208984Sbill 			if (*cp == '|')
209984Sbill 				*dp = '|';
210984Sbill 			else if (*dp == 0)
211984Sbill 				*dp = ' ';
212984Sbill 		page[l][0] = 0;
213984Sbill 	}
214984Sbill }
215