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