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