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