1 #ifndef lint
2 static char sccsid[] = "@(#)maktab.c	1.4 (Berkeley) 07/27/93";
3 #endif lint
4 
5 
6 /*
7  * compute tab stops
8  */
9 
10 #define tx(a)		(a>0 && a<128)
11 
12 #define FN(i,c)		font[stynum[i]][c]
13 #define SZ(i,c)		csize[stynum[i]][c]
14 
15 #include "defs.h"
16 #include "ext.h"
17 
18 /*
19  * define the tab stops of the table
20  */
maktab()21 maktab()
22 {
23 	int icol, ilin, tsep, k, ik, vforml, il, text;
24 	int doubled[MAXCOL], acase[MAXCOL];
25 	char *s;
26 
27 	for(icol = 0; icol < ncol; icol++){
28 		doubled[icol] = acase[icol] = 0;
29 		printf(".nr %2s 0\n", reg(icol, CRIGHT));
30 		for(text = 0; text < 2; text++){
31 			if(text)
32 				printf(".%2s\n.rm %2s\n", reg(icol, CRIGHT),
33 							reg(icol, CRIGHT));
34 			for(ilin = 0; ilin < nlin; ilin++){
35 				if(instead[ilin] || fullbot[ilin]){
36 					continue;
37 				}
38 				vforml = ilin;
39 				for(il = prev(ilin);
40 				    il >= 0 && vspen(table[il][icol].col);
41 				    il = prev(il))
42 					vforml = il;
43 				if(fspan(vforml, icol)){
44 					continue;
45 				}
46 				if(filler(table[ilin][icol].col)){
47 					continue;
48 				}
49 				if((ctop[stynum[ilin]][icol] & ZEROW) != 0){
50 					continue;
51 				}
52 				switch(ctype(vforml, icol)){
53 
54 				case 'a':
55 					acase[icol] = 1;
56 					s = table[ilin][icol].col;
57 					if(s > 0 && s < (char *)128 && text){
58 						if(doubled[icol] == 0)
59 							printf(
60 							 ".nr %d 0\n.nr %d 0\n",
61 							 S1, S2);
62 						doubled[icol] = 1;
63 						printf(
64 					  ".if \\n(%c->\\n(%d .nr %d \\n(%c-\n",
65 								s, S2, S2, s);
66 					}
67 				case 'n':
68 					if(table[ilin][icol].rcol != 0){
69 						if(doubled[icol] == 0
70 							 && text == 0)
71 							printf(
72 							 ".nr %d 0\n.nr %d 0\n",
73 							 S1, S2);
74 						doubled[icol] = 1;
75 						if(real(s=table[ilin][icol].col)
76 						    && !vspen(s)){
77 							if(tx((int)s) != text)
78 								continue;
79 							printf(".nr %d ", TMP);
80 							wide(s,
81 							      FN(vforml, icol),
82 							      SZ(vforml, icol));
83 							printf("\n");
84 							printf(
85 					   ".if \\n(%d<\\n(%d .nr %d \\n(%d\n",
86 							      S1, TMP, S1, TMP);
87 						}
88 						if(text == 0
89 						   && real(s=table[ilin][icol].rcol)
90 						   && !vspen(s) && !barent(s)){
91 							printf(
92 							   ".nr %d \\w%c%s%c\n",
93 							  	TMP, F1, s, F1);
94 							printf(
95 					    ".if \\n(%d<\\n(%d .nr %d \\n(%d\n",
96 							      S2, TMP, S2, TMP);
97 						}
98 						continue;
99 					}
100 				case 'r':
101 				case 'c':
102 				case 'l':
103 					if(real(s = table[ilin][icol].col)
104 					   && !vspen(s)){
105 						if(tx((int)s) != text)
106 							continue;
107 						printf(".nr %d ", TMP);
108 						wide(s,
109 							FN(vforml, icol),
110 							SZ(vforml, icol));
111 						printf("\n");
112 						printf(
113 	   ".if \\n(%2s<\\n(%d .nr %2s \\n(%d\n", reg(icol, CRIGHT), TMP,
114 							reg(icol, CRIGHT), TMP);
115 					}
116 				}
117 			}
118 		}
119 		if(acase[icol]){
120 			printf(".if \\n(%d>=\\n(%2s .nr %2s \\n(%du+2n\n",
121 				S2, reg(icol, CRIGHT), reg(icol, CRIGHT), S2);
122 		}
123 		if(doubled[icol]){
124 			printf(".nr %2s \\n(%d\n", reg(icol, CMID), S1);
125 			printf(".nr %d \\n(%2s+\\n(%d\n", TMP, reg(icol, CMID),
126 									S2);
127 			printf(".if \\n(%d>\\n(%2s .nr %2s \\n(%d\n", TMP,
128 				    reg(icol, CRIGHT), reg(icol, CRIGHT), TMP);
129 			printf(
130 			     ".if \\n(%d<\\n(%2s .nr %2s +(\\n(%2s-\\n(%d)/2\n",
131 			     TMP, reg(icol, CRIGHT), reg(icol, CMID),
132 			     				reg(icol, CRIGHT), TMP);
133 		}
134 		if(cll[icol][0]){
135 			printf(".nr %d %sn\n", TMP, cll[icol]);
136 			printf(".if \\n(%2s<\\n(%d .nr %2s \\n(%d\n",
137 				reg(icol, CRIGHT), TMP, reg(icol, CRIGHT), TMP);
138 		}
139 		for(ilin = 0; ilin < nlin; ilin++)
140 			if(k = lspan(ilin, icol)){
141 				s = table[ilin][icol - k].col;
142 				if(!real(s) || barent(s) || vspen(s))
143 					continue;
144 				printf(".nr %d ", TMP);
145 				wide(table[ilin][icol - k].col,
146 				      FN(ilin, icol - k), SZ(ilin, icol - k));
147 				for(ik = k; ik >= 0; ik--){
148 					printf("-\\n(%2s", reg(icol-ik,CRIGHT));
149 					if(!expflg && ik > 0)
150 						printf( "-%dn", sep[icol - ik]);
151 				}
152 				printf("\n");
153 				printf(".if \\n(%d>0 .nr %d \\n(%d/%d\n",
154 							TMP, TMP, TMP, k);
155 				printf(".if \\n(%d<0 .nr %d 0\n",
156 							TMP, TMP);
157 				for(ik = 1; ik <= k; ik++){
158 					if(doubled[icol - k + ik]){
159 						printf(".nr %2s +\\n(%d/2\n",
160 							reg(icol - k + ik,CMID),
161 								TMP);
162 					}
163 					printf(".nr %2s +\\n(%d\n",
164 						reg(icol - k + ik, CRIGHT),TMP);
165 				}
166 			}
167 	}
168 	if(textflg)
169 		untext();
170 	/*
171 	 * if even requested, make all columns widest width
172 	 */
173 
174 #define TMP1 S1
175 #define TMP2 S2
176 
177 	if(evenflg){
178 		printf(".nr %d 0\n", TMP);
179 		for(icol = 0; icol < ncol; icol++){
180 			if(evenup[icol] == 0)
181 				continue;
182 			printf(".if \\n(%2s>\\n(%d .nr %d \\n(%2s\n",
183 				reg(icol, CRIGHT), TMP, TMP, reg(icol, CRIGHT));
184 		}
185 		for(icol = 0; icol < ncol; icol++){
186  			/*
187 			 * if column not evened just retain old interval
188 			 */
189 			if(evenup[icol] == 0)
190 				continue;
191 			if(doubled[icol])
192 				printf(
193 				   ".nr %2s (100*\\n(%2s/\\n(%2s)*\\n(%d/100\n",
194 				   	reg(icol, CMID), reg(icol, CMID),
195 				   		reg(icol, CRIGHT), TMP);
196 			/*
197 		 	* that nonsense with the 100's and parens tries to avoid
198 		 	* overflow while proportionally shifting the middle of
199 		 	* the number
200 		 	*/
201 			printf(".nr %2s \\n(%d\n", reg(icol, CRIGHT), TMP);
202 		}
203 	}
204 	/*
205 	 * now adjust for total table width
206 	 */
207 	for(tsep = icol = 0; icol < ncol; icol++)
208 		tsep += sep[icol];
209 	if(expflg){
210 		printf(".nr %d 0", TMP);
211 		for(icol = 0; icol < ncol; icol++)
212 			printf("+\\n(%2s", reg(icol, CRIGHT));
213 		printf("\n");
214 		/*
215 		 * Bug fix: Most users expect the expand to take place
216 		 * over the line length minus the current indentation
217 		 * (I do as well, a bit ugly to see the table creeping
218 		 * in the right margin (jna))
219 		 */
220 		printf(".nr %d \\n(.l-\\n(.i-\\n(%d\n", TMP, TMP);
221 		if(boxflg || dboxflg || allflg)
222 			tsep += 1;
223 		else
224 			tsep -= sep[ncol - 1];
225 		printf(".nr %d \\n(%d/%d\n", TMP, TMP, tsep);
226 		printf(".if \\n(%d<0 .nr %d 0\n", TMP, TMP);
227 	} else
228 		printf(".nr %d 1n\n", TMP);
229 	printf(".nr %2s 0\n", reg(-1,CRIGHT));
230 	tsep = (boxflg || allflg || dboxflg || left1flg) ? 1 : 0;
231 	for(icol = 0; icol < ncol; icol++){
232 		printf(".nr %2s \\n(%2s+(%d*\\n(%d)\n", reg(icol, CLEFT),
233 					reg(icol -1, CRIGHT), tsep, TMP);
234 		printf(".nr %2s +\\n(%2s\n",reg(icol, CRIGHT),reg(icol, CLEFT));
235 		if(doubled[icol]){
236 			/*
237 			 * the next line is last-ditch effort to avoid
238 			 * zero field width
239 			 */
240 			/*
241 			printf(".if \\n(%2s=0 .nr %2s 1\n", reg(icol,CMID),
242 		   				reg(icol,CMID));
243 			 */
244 			printf(".nr %2s +\\n(%2s\n", reg(icol, CMID),
245 							reg(icol, CLEFT));
246 			/*
247 			printf(".if n .if \\n(%2s%%24>0 .nr %2s +12u\n",
248 					reg(icol, CMID), reg(icol, CMID));
249 			 */
250 		}
251 		tsep = sep[icol];
252 	}
253 	if(rightl)
254 		printf(".nr %2s (\\n(%2s+\\n(%2s)/2\n", reg(ncol-1, CRIGHT),
255 							reg(ncol-1, CLEFT),
256 							reg(ncol-2, CRIGHT));
257 	printf(".nr TW \\n(%2s\n", reg(ncol-1, CRIGHT));
258 	if(boxflg || allflg || dboxflg)
259 		printf(".nr TW +%d*\\n(%d\n", sep[ncol - 1], TMP);
260 	printf(
261 ".if t .if\\n(TW>\\n(.lu .tm Table at line %d file %s is too wide - \\n(TW units\n",
262 		iline - 1, strlen(oldname) ? oldname : ifile);
263 	return;
264 }
265 
266 /*
267  * tell troff to calculate width of an entry
268  */
wide(s,fn,size)269 wide(s, fn, size)
270 char *s, *size, *fn;
271 {
272 	/*
273 	 * if s is a pointer to a string, calculate the with of that string
274 	 */
275 	if(point(s)){
276 		printf("\\w%c", F1);
277 		if(*fn > 0)
278 			putfont(fn);
279 		if(*size)
280 			putsize(size);
281 		printf("%s", s);
282 		if(*fn > 0)
283 			putfont("P");
284 		if(*size)
285 			putsize("0");
286 		printf("%c", F1);
287 	} else
288 		/*
289 		 * it is the name of a diversion, so we know the witdh
290 		 * is in <diversionname>-
291 		 */
292 		printf("\\n(%c-", s);
293 }
294 
filler(s)295 filler(s)
296 char *s;
297 {
298 	return(point(s) && s[0] == '\\' && s[1] == 'R');
299 }
300