1 #ifndef lint
2 static char sccsid[] = "@(#)write1line.c 1.2 (CWI) 85/10/02";
3 #endif lint
4
5 /*
6 * write out one line of output table
7 */
8
9 #include "defs.h"
10 #include "ext.h"
11
12 #define realsplit ((ct == 'a' || ct == 'n') && table[nl][c].rcol)
13
14 int watchout;
15 int once;
16 int topat[MAXCOL];
17
18 /*
19 * i is line number for deciding format
20 * nl is line number for finding data
21 * usually identical
22 */
putline(i,nl)23 putline(i, nl){
24 int c, lf, ct, form, lwid, vspf, ip, cmidx, exvspen, vforml;
25 int vct, chfont, uphalf;
26 char *s, *size, *fn;
27
28 dprint(".\\\" -- putline( %d, %d)\n", i, nl);
29
30 watchout = vspf = exvspen = 0;
31 if(i == 0)
32 once = 0;
33 if(i == 0 && (allflg || boxflg || dboxflg))
34 fullwide(0, dboxflg ? '=' : '-');
35 if(instead[nl] == 0 && fullbot[nl] == 0){
36 for(c = 0; c < ncol; c++){
37 s = table[nl][c].col;
38 if(s == 0)
39 continue;
40 if(vspen(s)){
41 for(ip = nl; ip < nlin; ip = next(ip))
42 if(!vspen(s = table[ip][c].col))
43 break;
44 if((int) s > 0 && (int) s < 128)
45 printf(".ne \\n(%c|u+\\n(.Vu\n", s);
46 continue;
47 }
48 if(point(s))
49 continue;
50 printf(".ne \\n(%c|u+\\n(.Vu\n", s);
51 watchout = 1;
52 }
53 }
54 if(linestop[nl])
55 printf(".mk #%c\n", linestop[nl] + 'a' - 1);
56 lf = prev(nl);
57 if(instead[nl]){
58 puts(instead[nl]);
59 return;
60 }
61 if(fullbot[nl]){
62 switch(ct = fullbot[nl]){
63 case '=':
64 case '-':
65 fullwide(nl, ct);
66 }
67 return;
68 }
69 for(c = 0; c < ncol; c++){
70 if(instead[nl] == 0 && fullbot[nl] == 0){
71 if(vspen(table[nl][c].col))
72 vspf = 1;
73 }
74 if(lf >= 0){
75 if(vspen(table[lf][c].col))
76 vspf = 1;
77 }
78 }
79 if(vspf){
80 printf(".nr #^ \\n(\\*(#du\n");
81 /*
82 * current line position relative to bottom
83 */
84 printf(".nr #- \\n(#^\n");
85 }
86 vspf = 0;
87 chfont = 0;
88 for(c = 0; c < ncol; c++){
89 s = table[nl][c].col;
90 if(s == 0)
91 continue;
92 chfont |= (int) (font[stynum[nl]][c]);
93 if(point(s))
94 continue;
95 lf = prev(nl);
96 if(lf >= 0 && vspen(table[lf][c].col))
97 printf(
98 ".if (\\n(%c|+\\n(^%c-1v)>\\n(#- .nr #- +(\\n(%c|+\\n(^%c-\\n(#--1v)\n",
99 s, 'a' + c, s, 'a' + c);
100 else
101 printf(
102 ".if (\\n(%c|+\\n(#^-1v)>\\n(#- .nr #- +(\\n(%c|+\\n(#^-\\n(#--1v)\n",
103 s, s);
104 }
105 if(allflg && once > 0)
106 fullwide(i, '-');
107 once = 1;
108 runtabs(i, nl);
109 if(allh(i) && !pr1403){
110 printf(".nr %d \\n(.v\n", SVS);
111 printf(".vs \\n(.vu-\\n(.sp\n");
112 }
113 if(chfont)
114 printf(".nr %2d \\n(.f\n", S1);
115 printf(".nr 35 1m\n");
116 printf("\\&");
117 vct = 0;
118 for(c = 0; c < ncol; c++){
119 uphalf = 0;
120 if(watchout == 0 && i + 1 < nlin
121 && (lf = left(i, c, &lwid)) >= 0){
122 tohcol(c);
123 drawvert(lf, i, c, lwid);
124 vct += 2;
125 }
126 if(rightl && c + 1 == ncol)
127 continue;
128 vforml = i;
129 for(lf = prev(nl); lf >= 0 && vspen (table[lf][c].col);
130 lf = prev (lf))
131 vforml = lf;
132 form = ctype(vforml, c);
133 if(form != 's'){
134 ct = (int) reg(c, CLEFT);
135 if(form == 'a')
136 ct = (int) reg(c, CMID);
137 if(form == 'n' && table[nl][c].rcol && lused[c] == 0)
138 ct = (int) reg(c, CMID);
139 printf("\\h'|\\n(%2su'", ct);
140 }
141 s = table[nl][c].col;
142 fn = font[stynum[vforml]][c];
143 size = csize[stynum[vforml]][c];
144 if(*size == 0)
145 size = 0;
146 if((ctop[stynum[nl]][c] & HALFUP) != 0 && pr1403 == 0)
147 uphalf = 1;
148 switch(ct = ctype(vforml, c)){
149
150 case 'n':
151 case 'a':
152 if(table[nl][c].rcol){
153 if(lused[c]){
154 /*
155 * Zero field width
156 */
157 ip = prev(nl);
158 if(ip >= 0){
159 /*
160 * Indentation is getting complete out of hand here, let's shift to
161 * the left
162 */
163 if(vspen(table[ip][c].col)){
164 if(exvspen == 0){
165 printf("\\v'-(\\n(\\*(#du-\\n(^%cu", c + 'a');
166 if(cmidx)
167 printf("-((\\n(#-u-\\n(^%cu)/2u)", c + 'a');
168
169 vct++;
170 if(pr1403){
171 /*
172 * Must round to whole lines (bwk?)
173 */
174 printf("/1v*1v");
175 }
176 printf("'");
177 exvspen = 1;
178 }
179 }
180 /*
181 * Restore layout of this source
182 */
183 }
184 printf("%c%c", F1, F2);
185 if(uphalf)
186 printf("\\u");
187 puttext(s, fn, size);
188 if(uphalf)
189 printf("\\d");
190 printf("%c", F1);
191 }
192 s = table[nl][c].rcol;
193 form = 1;
194 break;
195 }
196 case 'c':
197 form = 3;
198 break;
199 case 'r':
200 form = 2;
201 break;
202 case 'l':
203 form = 1;
204 break;
205 case '-':
206 case '=':
207 if(real(table[nl][c].col)){
208 fprintf(stderr,
209 "%s: line %d: Data ignored on table line %d\n",
210 ifile, iline - 1, i + 1);
211 }
212 makeline(i, c, ct);
213 continue;
214 default:
215 continue;
216 }
217 if(realsplit ? rused[c] : used[c]){
218 /*
219 * Zero field width
220 */
221 /*
222 * form: 1 left, 2 right, 3 center adjust
223 */
224 if(ifline(s)){
225 makeline(i, c, ifline (s));
226 continue;
227 }
228 if(filler(s)){
229 printf("\\l'|\\n(%2su\\&%s'", reg(c, CRIGHT),
230 s + 2);
231 continue;
232 }
233 ip = prev(nl);
234 cmidx = (ctop[stynum[nl]][c] & (CTOP | CDOWN)) == 0;
235 if(ip >= 0)
236 if(vspen(table[ip][c].col)){
237 if(exvspen == 0){
238 printf(
239 "\\v'-(\\n(\\*(#du-\\n(^%cu",
240 c + 'a');
241 if(cmidx)
242 printf(
243 "-((\\n(#-u-\\n(^%cu)/2u)", c + 'a');
244 vct++;
245 if(pr1403){
246 /*
247 * Round to
248 * whole lines
249 */
250 printf("/1v*1v");
251 }
252 printf("'");
253 }
254 }
255 printf("%c", F1);
256 if(form != 1)
257 printf("%c", F2);
258 if(vspen(s))
259 vspf = 1;
260 else
261 puttext(s, fn, size);
262 if(form != 2)
263 printf("%c", F2);
264 printf("%c", F1);
265 }
266 ip = prev(nl); /*
267 * Julian Onion mod (system III)
268 */
269 if(ip >= 0){
270 if(vspen(table[ip][c].col)){
271 exvspen = (c + 1 < ncol)
272 && vspen(table[ip][c + 1].col)
273 && (topat[c] == topat[c + 1])
274 && (cmidx == ((ctop[stynum[nl]][c+1]
275 & (CTOP|CDOWN)) == 0))
276 && (left(i, c + 1, &lwid) < 0);
277 /*
278 * IS THIS WRONG? SHOULD IT BE
279 * (cmidx = ...
280 && (cmidx = (ctop[stynum[nl]][c+1] &(CTOP|CDOWN) == 0))
281 */
282 if(exvspen == 0){
283 printf("\\v'(\\n(\\*(#du-\\n(^%cu",
284 c + 'a');
285 if(cmidx)
286 printf(
287 "-((\\n(#-u-\\n(^%cu)/2u)",
288 c + 'a');
289 vct++;
290 if(pr1403){
291 /*
292 * Round to
293 * whole lines
294 */
295 printf("/1v*1v");
296 }
297 printf("'");
298 }
299 }
300 else
301 exvspen = 0;
302 }
303 /*
304 * if lines need to be split for gcos
305 * here is the place for a backslash
306 */
307 if(vct > 7 && c < ncol){
308 printf("\n.sp-1\n\\&");
309 vct = 0;
310 }
311 }
312 printf("\n");
313 if(allh(i) && !pr1403)
314 printf(".vs \\n(%du\n", SVS);
315 if(watchout)
316 funnies(i, nl);
317 if(vspf){
318 for(c = 0; c < ncol; c++){
319 if(vspen(table[nl][c].col)
320 && (nl == 0 || (lf = prev (nl)) < 0
321 || !vspen(table[lf][c].col
322 ) )){
323 printf(".nr ^%c \\n(#^u\n", 'a' + c);
324 topat[c] = nl;
325 }
326 }
327 }
328 }
329
puttext(s,fn,size)330 puttext(s, fn, size)
331 char *s, *size, *fn;
332 {
333 if(point(s)){
334 putfont(fn);
335 putsize(size);
336 printf("%s", s);
337 if(*fn > 0)
338 printf("\\f\\n(%2d", S1);
339 if(size != 0)
340 putsize("0");
341 }
342 }
343
344 /*
345 * write out funny diverted things
346 */
funnies(stl,lin)347 funnies(stl, lin){
348 int c, s, pl, lwid, dv, lf, ct;
349 char *fn;
350 extern char *reg();
351
352 dprint(".\\\" -- funnies\n");
353 /*
354 * remember current vertical position
355 */
356 printf(".mk ##\n");
357 /*
358 * bottom position
359 */
360 printf(".nr %d \\n(##\n", S1);
361 for(c = 0; c < ncol; c++){
362 s = (int)table[lin][c].col;
363 if(point(s))
364 continue;
365 if(s == 0)
366 continue;
367 printf(".sp |\\n(##u-1v\n");
368 printf(".nr %d ", SIND);
369 for(pl = stl; pl >= 0 && !isalpha(ct = ctype (pl, c));
370 pl = prev (pl))
371 ;
372 switch(ct){
373
374 case 'n':
375 case 'c':
376 printf("(\\n(%2su+\\n(%2su-\\n(%c-u)/2u\n",reg(c,CLEFT),
377 reg(c - 1 + ctspan(lin, c), CRIGHT), s);
378 break;
379 case 'l':
380 printf("\\n(%2su\n", reg(c, CLEFT));
381 break;
382 case 'a':
383 printf("\\n(%2su\n", reg(c, CMID));
384 break;
385 case 'r':
386 printf("\\n(%2su-\\n(%c-u\n", reg(c, CRIGHT), s);
387 break;
388 }
389 printf(".in +\\n(%du\n", SIND);
390 fn = font[stynum[stl]][c];
391 putfont(fn);
392 pl = prev(stl);
393 if(stl > 0 && pl >= 0 && vspen(table[pl][c].col)){
394 printf(".sp |\\n(^%cu\n", 'a' + c);
395 if((ctop[stynum[stl]][c]&(CTOP|CDOWN)) == 0){
396 printf(".nr %d \\n(#-u-\\n(^%c-\\n(%c|+1v\n",
397 TMP, 'a' + c, s);
398 printf(".if \\n(%d>0 .sp \\n(%du/2u",TMP,TMP);
399 /*
400 * Round
401 */
402 if(pr1403)
403 printf("/1v*1v");
404 printf("\n");
405 }
406 }
407 printf(".%c+\n", s);
408 printf(".in -\\n(%du\n", SIND);
409 if(*fn > 0)
410 putfont("P");
411 printf(".mk %d\n", S2);
412 printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", S2, S1, S1, S2);
413 }
414 printf(".sp |\\n(%du\n", S1);
415 for(c = dv = 0; c < ncol; c++){
416 if(stl + 1 < nlin && (lf = left(stl, c, &lwid)) >= 0){
417 if(dv++ == 0)
418 printf(".sp -1\n");
419 tohcol(c);
420 dv++;
421 drawvert(lf, stl, c, lwid);
422 }
423 }
424 if(dv)
425 printf("\n");
426 }
427
putfont(fn)428 putfont(fn)
429 char *fn;
430 {
431 if(fn && *fn)
432 printf(fn[1] ? "\\f(%.2s" : "\\f%.2s", fn);
433 }
434
putsize(s)435 putsize(s)
436 char *s;
437 {
438 if(s && *s)
439 printf("\\s%s", s);
440 }
441