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  */
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 
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  */
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 
428 putfont(fn)
429 char *fn;
430 {
431 	if(fn && *fn)
432 		printf(fn[1] ? "\\f(%.2s" : "\\f%.2s", fn);
433 }
434 
435 putsize(s)
436 char *s;
437 {
438 	if(s && *s)
439 		printf("\\s%s", s);
440 }
441