xref: /csrg-svn/usr.bin/colcrt/colcrt.c (revision 984)
1*984Sbill static char *sccsid = "@(#)colcrt.c	4.1 (Berkeley) 10/01/80";
2*984Sbill #include <stdio.h>
3*984Sbill /*
4*984Sbill  * colcrt - replaces col for crts with new nroff esp. when using tbl.
5*984Sbill  * Bill Joy UCB July 14, 1977
6*984Sbill  *
7*984Sbill  * This filter uses a screen buffer, 267 half-lines by 132 columns.
8*984Sbill  * It interprets the up and down sequences generated by the new
9*984Sbill  * nroff when used with tbl and by \u \d and \r.
10*984Sbill  * General overstriking doesn't work correctly.
11*984Sbill  * Underlining is split onto multiple lines, etc.
12*984Sbill  *
13*984Sbill  * Option - suppresses all underlining.
14*984Sbill  * Option -2 forces printing of all half lines.
15*984Sbill  */
16*984Sbill 
17*984Sbill char	page[267][132];
18*984Sbill 
19*984Sbill int	outline = 1;
20*984Sbill int	outcol;
21*984Sbill 
22*984Sbill char	buf[256];
23*984Sbill char	suppresul;
24*984Sbill char	printall;
25*984Sbill 
26*984Sbill char	*progname;
27*984Sbill FILE	*f;
28*984Sbill 
29*984Sbill main(argc, argv)
30*984Sbill 	int argc;
31*984Sbill 	char *argv[];
32*984Sbill {
33*984Sbill 	register c;
34*984Sbill 	register char *cp, *dp;
35*984Sbill 
36*984Sbill 	argc--;
37*984Sbill 	progname = *argv++;
38*984Sbill 	while (argc > 0 && argv[0][0] == '-') {
39*984Sbill 		switch (argv[0][1]) {
40*984Sbill 			case 0:
41*984Sbill 				suppresul = 1;
42*984Sbill 				break;
43*984Sbill 			case '2':
44*984Sbill 				printall = 1;
45*984Sbill 				break;
46*984Sbill 			default:
47*984Sbill 				printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
48*984Sbill 				fflush(stdout);
49*984Sbill 				exit(1);
50*984Sbill 		}
51*984Sbill 		argc--;
52*984Sbill 		argv++;
53*984Sbill 	}
54*984Sbill 	setbuf(stdout, buf);
55*984Sbill 	do {
56*984Sbill 		if (argc > 0) {
57*984Sbill 			close(0);
58*984Sbill 			if ((f=fopen(argv[0], "r")
59*984Sbill ) < 0) {
60*984Sbill 				fflush(stdout);
61*984Sbill 				perror(argv[0]);
62*984Sbill 				fflush(stdout);
63*984Sbill 				exit (1);
64*984Sbill 			}
65*984Sbill 			argc--;
66*984Sbill 			argv++;
67*984Sbill 		}
68*984Sbill 		for (;;) {
69*984Sbill 			c = getc(stdin);
70*984Sbill 			if (c == -1) {
71*984Sbill 				pflush(outline);
72*984Sbill 				fflush(stdout);
73*984Sbill 				break;
74*984Sbill 			}
75*984Sbill 			switch (c) {
76*984Sbill 				case '\n':
77*984Sbill 					if (outline >= 265)
78*984Sbill 						pflush(62);
79*984Sbill 					outline += 2;
80*984Sbill 					outcol = 0;
81*984Sbill 					continue;
82*984Sbill 				case '\016':
83*984Sbill 					case '\017':
84*984Sbill 					continue;
85*984Sbill 				case 033:
86*984Sbill 					c = getc(stdin);
87*984Sbill 					switch (c) {
88*984Sbill 						case '9':
89*984Sbill 							if (outline >= 266)
90*984Sbill 								pflush(62);
91*984Sbill 							outline++;
92*984Sbill 							continue;
93*984Sbill 						case '8':
94*984Sbill 							if (outline >= 1)
95*984Sbill 								outline--;
96*984Sbill 							continue;
97*984Sbill 						case '7':
98*984Sbill 							outline -= 2;
99*984Sbill 							if (outline < 0)
100*984Sbill 								outline = 0;
101*984Sbill 							continue;
102*984Sbill 						default:
103*984Sbill 							continue;
104*984Sbill 					}
105*984Sbill 				case '\b':
106*984Sbill 					if (outcol)
107*984Sbill 						outcol--;
108*984Sbill 					continue;
109*984Sbill 				case '\t':
110*984Sbill 					outcol += 8;
111*984Sbill 					outcol &= ~7;
112*984Sbill 					outcol--;
113*984Sbill 					c = ' ';
114*984Sbill 				default:
115*984Sbill 					if (outcol >= 132) {
116*984Sbill 						outcol++;
117*984Sbill 						continue;
118*984Sbill 					}
119*984Sbill 					cp = &page[outline][outcol];
120*984Sbill 					outcol++;
121*984Sbill 					if (c == '_') {
122*984Sbill 						if (suppresul)
123*984Sbill 							continue;
124*984Sbill 						cp += 132;
125*984Sbill 						c = '-';
126*984Sbill 					}
127*984Sbill 					if (*cp == 0) {
128*984Sbill 						*cp = c;
129*984Sbill 						dp = cp - outcol;
130*984Sbill 						for (cp--; cp >= dp && *cp == 0; cp--)
131*984Sbill 							*cp = ' ';
132*984Sbill 					} else
133*984Sbill 						if (plus(c, *cp) || plus(*cp, c))
134*984Sbill 							*cp = '+';
135*984Sbill 						else if (*cp == ' ' || *cp == 0)
136*984Sbill 							*cp = c;
137*984Sbill 					continue;
138*984Sbill 			}
139*984Sbill 		}
140*984Sbill 	} while (argc > 0);
141*984Sbill 	fflush(stdout);
142*984Sbill 	exit(0);
143*984Sbill }
144*984Sbill 
145*984Sbill plus(c, d)
146*984Sbill 	char c, d;
147*984Sbill {
148*984Sbill 
149*984Sbill 	return (c == '|' && d == '-' || d == '_');
150*984Sbill }
151*984Sbill 
152*984Sbill int first;
153*984Sbill 
154*984Sbill pflush(ol)
155*984Sbill 	int ol;
156*984Sbill {
157*984Sbill 	register int i, j;
158*984Sbill 	register char *cp;
159*984Sbill 	char lastomit;
160*984Sbill 	int l;
161*984Sbill 
162*984Sbill 	l = ol;
163*984Sbill 	lastomit = 0;
164*984Sbill 	if (l > 266)
165*984Sbill 		l = 266;
166*984Sbill 	else
167*984Sbill 		l |= 1;
168*984Sbill 	for (i = first | 1; i < l; i++) {
169*984Sbill 		move(i, i - 1);
170*984Sbill 		move(i, i + 1);
171*984Sbill 	}
172*984Sbill 	for (i = first; i < l; i++) {
173*984Sbill 		cp = page[i];
174*984Sbill 		if (printall == 0 && lastomit == 0 && *cp == 0) {
175*984Sbill 			lastomit = 1;
176*984Sbill 			continue;
177*984Sbill 		}
178*984Sbill 		lastomit = 0;
179*984Sbill 		printf("%s\n", cp);
180*984Sbill 	}
181*984Sbill 	copy(page, page[ol], (267 - ol) * 132);
182*984Sbill 	clear(page[267- ol], ol * 132);
183*984Sbill 	outline -= ol;
184*984Sbill 	outcol = 0;
185*984Sbill 	first = 1;
186*984Sbill }
187*984Sbill move(l, m)
188*984Sbill 	int l, m;
189*984Sbill {
190*984Sbill 	register char *cp, *dp;
191*984Sbill 
192*984Sbill 	for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
193*984Sbill 		switch (*cp) {
194*984Sbill 			case '|':
195*984Sbill 				if (*dp != ' ' && *dp != '|' && *dp != 0)
196*984Sbill 					return;
197*984Sbill 				break;
198*984Sbill 			case ' ':
199*984Sbill 				break;
200*984Sbill 			default:
201*984Sbill 				return;
202*984Sbill 		}
203*984Sbill 	}
204*984Sbill 	if (*cp == 0) {
205*984Sbill 		for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
206*984Sbill 			if (*cp == '|')
207*984Sbill 				*dp = '|';
208*984Sbill 			else if (*dp == 0)
209*984Sbill 				*dp = ' ';
210*984Sbill 		page[l][0] = 0;
211*984Sbill 	}
212*984Sbill }
213*984Sbill 
214*984Sbill copy(to, from, i)
215*984Sbill 	register char *to, *from;
216*984Sbill 	register int i;
217*984Sbill {
218*984Sbill 
219*984Sbill 	if (i > 0)
220*984Sbill 		do
221*984Sbill 			*to++ = *from++;
222*984Sbill 		while (--i);
223*984Sbill }
224*984Sbill 
225*984Sbill clear(at, cnt)
226*984Sbill 	register char *at;
227*984Sbill 	register int cnt;
228*984Sbill {
229*984Sbill 
230*984Sbill 	if (cnt > 0)
231*984Sbill 		do
232*984Sbill 			*at++ = 0;
233*984Sbill 		while (--cnt);
234*984Sbill }
235