colcrt.c revision 1.4 1 /* $NetBSD: colcrt.c,v 1.4 1997/10/18 12:59:10 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
39 The Regents of the University of California. All rights reserved.\n");
40 #endif /* not lint */
41
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)colcrt.c 8.1 (Berkeley) 6/6/93";
45 #else
46 __RCSID("$NetBSD: colcrt.c,v 1.4 1997/10/18 12:59:10 lukem Exp $");
47 #endif
48 #endif /* not lint */
49
50 #include <stdio.h>
51 #include <string.h>
52 #include <unistd.h>
53
54 /*
55 * colcrt - replaces col for crts with new nroff esp. when using tbl.
56 * Bill Joy UCB July 14, 1977
57 *
58 * This filter uses a screen buffer, 267 half-lines by 132 columns.
59 * It interprets the up and down sequences generated by the new
60 * nroff when used with tbl and by \u \d and \r.
61 * General overstriking doesn't work correctly.
62 * Underlining is split onto multiple lines, etc.
63 *
64 * Option - suppresses all underlining.
65 * Option -2 forces printing of all half lines.
66 */
67
68 char page[267][132];
69
70 int outline = 1;
71 int outcol;
72
73 char suppresul;
74 char printall;
75
76 char *progname;
77 FILE *f;
78
79 int main __P((int, char **));
80 void move __P((int, int));
81 void pflush __P((int));
82 int plus __P((char, char));
83
84 int
85 main(argc, argv)
86 int argc;
87 char *argv[];
88 {
89 int c;
90 char *cp, *dp;
91
92 argc--;
93 progname = *argv++;
94 while (argc > 0 && argv[0][0] == '-') {
95 switch (argv[0][1]) {
96 case 0:
97 suppresul = 1;
98 break;
99 case '2':
100 printall = 1;
101 break;
102 default:
103 printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
104 fflush(stdout);
105 exit(1);
106 }
107 argc--;
108 argv++;
109 }
110 do {
111 if (argc > 0) {
112 close(0);
113 if (!(f = fopen(argv[0], "r"))) {
114 fflush(stdout);
115 perror(argv[0]);
116 exit (1);
117 }
118 argc--;
119 argv++;
120 }
121 for (;;) {
122 c = getc(stdin);
123 if (c == -1) {
124 pflush(outline);
125 fflush(stdout);
126 break;
127 }
128 switch (c) {
129 case '\n':
130 if (outline >= 265)
131 pflush(62);
132 outline += 2;
133 outcol = 0;
134 continue;
135 case '\016':
136 case '\017':
137 continue;
138 case 033:
139 c = getc(stdin);
140 switch (c) {
141 case '9':
142 if (outline >= 266)
143 pflush(62);
144 outline++;
145 continue;
146 case '8':
147 if (outline >= 1)
148 outline--;
149 continue;
150 case '7':
151 outline -= 2;
152 if (outline < 0)
153 outline = 0;
154 continue;
155 default:
156 continue;
157 }
158 case '\b':
159 if (outcol)
160 outcol--;
161 continue;
162 case '\t':
163 outcol += 8;
164 outcol &= ~7;
165 outcol--;
166 c = ' ';
167 default:
168 if (outcol >= 132) {
169 outcol++;
170 continue;
171 }
172 cp = &page[outline][outcol];
173 outcol++;
174 if (c == '_') {
175 if (suppresul)
176 continue;
177 cp += 132;
178 c = '-';
179 }
180 if (*cp == 0) {
181 *cp = c;
182 dp = cp - outcol;
183 for (cp--; cp >= dp && *cp == 0; cp--)
184 *cp = ' ';
185 } else
186 if (plus(c, *cp) || plus(*cp, c))
187 *cp = '+';
188 else if (*cp == ' ' || *cp == 0)
189 *cp = c;
190 continue;
191 }
192 }
193 } while (argc > 0);
194 fflush(stdout);
195 exit(0);
196 }
197
198 int
199 plus(c, d)
200 char c, d;
201 {
202
203 return ((c == '|' && d == '-') || d == '_');
204 }
205
206 int first;
207
208 void
209 pflush(ol)
210 int ol;
211 {
212 int i;
213 char *cp;
214 char lastomit;
215 int l;
216
217 l = ol;
218 lastomit = 0;
219 if (l > 266)
220 l = 266;
221 else
222 l |= 1;
223 for (i = first | 1; i < l; i++) {
224 move(i, i - 1);
225 move(i, i + 1);
226 }
227 for (i = first; i < l; i++) {
228 cp = page[i];
229 if (printall == 0 && lastomit == 0 && *cp == 0) {
230 lastomit = 1;
231 continue;
232 }
233 lastomit = 0;
234 printf("%s\n", cp);
235 }
236 memmove(page, page[ol], (267 - ol) * 132);
237 memset(page[267- ol], 0, ol * 132);
238 outline -= ol;
239 outcol = 0;
240 first = 1;
241 }
242
243 void
244 move(l, m)
245 int l, m;
246 {
247 char *cp, *dp;
248
249 for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
250 switch (*cp) {
251 case '|':
252 if (*dp != ' ' && *dp != '|' && *dp != 0)
253 return;
254 break;
255 case ' ':
256 break;
257 default:
258 return;
259 }
260 }
261 if (*cp == 0) {
262 for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
263 if (*cp == '|')
264 *dp = '|';
265 else if (*dp == 0)
266 *dp = ' ';
267 page[l][0] = 0;
268 }
269 }
270