xref: /original-bsd/usr.bin/colcrt/colcrt.c (revision 792e4f5f)
1 /*
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)colcrt.c	5.3 (Berkeley) 10/26/88";
26 #endif /* not lint */
27 
28 #include <stdio.h>
29 /*
30  * colcrt - replaces col for crts with new nroff esp. when using tbl.
31  * Bill Joy UCB July 14, 1977
32  *
33  * This filter uses a screen buffer, 267 half-lines by 132 columns.
34  * It interprets the up and down sequences generated by the new
35  * nroff when used with tbl and by \u \d and \r.
36  * General overstriking doesn't work correctly.
37  * Underlining is split onto multiple lines, etc.
38  *
39  * Option - suppresses all underlining.
40  * Option -2 forces printing of all half lines.
41  */
42 
43 char	page[267][132];
44 
45 int	outline = 1;
46 int	outcol;
47 
48 char	suppresul;
49 char	printall;
50 
51 char	*progname;
52 FILE	*f;
53 
54 main(argc, argv)
55 	int argc;
56 	char *argv[];
57 {
58 	register c;
59 	register char *cp, *dp;
60 
61 	argc--;
62 	progname = *argv++;
63 	while (argc > 0 && argv[0][0] == '-') {
64 		switch (argv[0][1]) {
65 			case 0:
66 				suppresul = 1;
67 				break;
68 			case '2':
69 				printall = 1;
70 				break;
71 			default:
72 				printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
73 				fflush(stdout);
74 				exit(1);
75 		}
76 		argc--;
77 		argv++;
78 	}
79 	do {
80 		if (argc > 0) {
81 			close(0);
82 			if (!(f = fopen(argv[0], "r"))) {
83 				fflush(stdout);
84 				perror(argv[0]);
85 				exit (1);
86 			}
87 			argc--;
88 			argv++;
89 		}
90 		for (;;) {
91 			c = getc(stdin);
92 			if (c == -1) {
93 				pflush(outline);
94 				fflush(stdout);
95 				break;
96 			}
97 			switch (c) {
98 				case '\n':
99 					if (outline >= 265)
100 						pflush(62);
101 					outline += 2;
102 					outcol = 0;
103 					continue;
104 				case '\016':
105 					case '\017':
106 					continue;
107 				case 033:
108 					c = getc(stdin);
109 					switch (c) {
110 						case '9':
111 							if (outline >= 266)
112 								pflush(62);
113 							outline++;
114 							continue;
115 						case '8':
116 							if (outline >= 1)
117 								outline--;
118 							continue;
119 						case '7':
120 							outline -= 2;
121 							if (outline < 0)
122 								outline = 0;
123 							continue;
124 						default:
125 							continue;
126 					}
127 				case '\b':
128 					if (outcol)
129 						outcol--;
130 					continue;
131 				case '\t':
132 					outcol += 8;
133 					outcol &= ~7;
134 					outcol--;
135 					c = ' ';
136 				default:
137 					if (outcol >= 132) {
138 						outcol++;
139 						continue;
140 					}
141 					cp = &page[outline][outcol];
142 					outcol++;
143 					if (c == '_') {
144 						if (suppresul)
145 							continue;
146 						cp += 132;
147 						c = '-';
148 					}
149 					if (*cp == 0) {
150 						*cp = c;
151 						dp = cp - outcol;
152 						for (cp--; cp >= dp && *cp == 0; cp--)
153 							*cp = ' ';
154 					} else
155 						if (plus(c, *cp) || plus(*cp, c))
156 							*cp = '+';
157 						else if (*cp == ' ' || *cp == 0)
158 							*cp = c;
159 					continue;
160 			}
161 		}
162 	} while (argc > 0);
163 	fflush(stdout);
164 	exit(0);
165 }
166 
167 plus(c, d)
168 	char c, d;
169 {
170 
171 	return (c == '|' && d == '-' || d == '_');
172 }
173 
174 int first;
175 
176 pflush(ol)
177 	int ol;
178 {
179 	register int i, j;
180 	register char *cp;
181 	char lastomit;
182 	int l;
183 
184 	l = ol;
185 	lastomit = 0;
186 	if (l > 266)
187 		l = 266;
188 	else
189 		l |= 1;
190 	for (i = first | 1; i < l; i++) {
191 		move(i, i - 1);
192 		move(i, i + 1);
193 	}
194 	for (i = first; i < l; i++) {
195 		cp = page[i];
196 		if (printall == 0 && lastomit == 0 && *cp == 0) {
197 			lastomit = 1;
198 			continue;
199 		}
200 		lastomit = 0;
201 		printf("%s\n", cp);
202 	}
203 	bcopy(page[ol], page, (267 - ol) * 132);
204 	bzero(page[267- ol], ol * 132);
205 	outline -= ol;
206 	outcol = 0;
207 	first = 1;
208 }
209 
210 move(l, m)
211 	int l, m;
212 {
213 	register char *cp, *dp;
214 
215 	for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
216 		switch (*cp) {
217 			case '|':
218 				if (*dp != ' ' && *dp != '|' && *dp != 0)
219 					return;
220 				break;
221 			case ' ':
222 				break;
223 			default:
224 				return;
225 		}
226 	}
227 	if (*cp == 0) {
228 		for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
229 			if (*cp == '|')
230 				*dp = '|';
231 			else if (*dp == 0)
232 				*dp = ' ';
233 		page[l][0] = 0;
234 	}
235 }
236