| /* t5.c: read data for table */ |
| # include "t.h" |
| |
| void |
| gettbl(void) |
| { |
| int icol, ch; |
| |
| cstore = cspace = chspace(); |
| textflg = 0; |
| for (nlin = nslin = 0; gets1(cstore, MAXCHS - (cstore - cspace)); nlin++) { |
| stynum[nlin] = nslin; |
| if (prefix(".TE", cstore)) { |
| leftover = 0; |
| break; |
| } |
| if (prefix(".TC", cstore) || prefix(".T&", cstore)) { |
| readspec(); |
| nslin++; |
| } |
| if (nlin >= MAXLIN) { |
| leftover = cstore; |
| break; |
| } |
| fullbot[nlin] = 0; |
| if (cstore[0] == '.' && !isdigit((uchar)cstore[1])) { |
| instead[nlin] = cstore; |
| while (*cstore++) |
| ; |
| continue; |
| } else |
| instead[nlin] = 0; |
| if (nodata(nlin)) { |
| if (ch = oneh(nlin)) |
| fullbot[nlin] = ch; |
| table[nlin] = (struct colstr *) alocv((ncol + 2) * sizeof(table[0][0])); |
| for (icol = 0; icol < ncol; icol++) { |
| table[nlin][icol].rcol = ""; |
| table[nlin][icol].col = ""; |
| } |
| nlin++; |
| nslin++; |
| fullbot[nlin] = 0; |
| instead[nlin] = (char *) 0; |
| } |
| table[nlin] = (struct colstr *) alocv((ncol + 2) * sizeof(table[0][0])); |
| if (cstore[1] == 0) |
| switch (cstore[0]) { |
| case '_': |
| fullbot[nlin] = '-'; |
| continue; |
| case '=': |
| fullbot[nlin] = '='; |
| continue; |
| } |
| stynum[nlin] = nslin; |
| nslin = min(nslin + 1, nclin - 1); |
| for (icol = 0; icol < ncol; icol++) { |
| table[nlin][icol].col = cstore; |
| table[nlin][icol].rcol = 0; |
| ch = 1; |
| if (match(cstore, "T{")) { /* text follows */ |
| table[nlin][icol].col = |
| (char *)(uintptr)gettext(cstore, nlin, icol, |
| font[icol][stynum[nlin]], |
| csize[icol][stynum[nlin]]); |
| } else |
| { |
| for (; (ch = *cstore) != '\0' && ch != tab; cstore++) |
| ; |
| *cstore++ = '\0'; |
| switch (ctype(nlin, icol)) /* numerical or alpha, subcol */ { |
| case 'n': |
| table[nlin][icol].rcol = maknew(table[nlin][icol].col); |
| break; |
| case 'a': |
| table[nlin][icol].rcol = table[nlin][icol].col; |
| table[nlin][icol].col = ""; |
| break; |
| } |
| } |
| while (ctype(nlin, icol + 1) == 's') /* spanning */ |
| table[nlin][++icol].col = ""; |
| if (ch == '\0') |
| break; |
| } |
| while (++icol < ncol + 2) { |
| table[nlin][icol].col = ""; |
| table [nlin][icol].rcol = 0; |
| } |
| while (*cstore != '\0') |
| cstore++; |
| if (cstore - cspace + MAXLINLEN > MAXCHS) |
| cstore = cspace = chspace(); |
| } |
| last = cstore; |
| permute(); |
| if (textflg) |
| untext(); |
| return; |
| } |
| |
| |
| int |
| nodata(int il) |
| { |
| int c; |
| |
| for (c = 0; c < ncol; c++) { |
| switch (ctype(il, c)) { |
| case 'c': |
| case 'n': |
| case 'r': |
| case 'l': |
| case 's': |
| case 'a': |
| return(0); |
| } |
| } |
| return(1); |
| } |
| |
| |
| int |
| oneh(int lin) |
| { |
| int k, icol; |
| |
| k = ctype(lin, 0); |
| for (icol = 1; icol < ncol; icol++) { |
| if (k != ctype(lin, icol)) |
| return(0); |
| } |
| return(k); |
| } |
| |
| |
| # define SPAN "\\^" |
| |
| void |
| permute(void) |
| { |
| int irow, jcol, is; |
| char *start, *strig; |
| |
| for (jcol = 0; jcol < ncol; jcol++) { |
| for (irow = 1; irow < nlin; irow++) { |
| if (vspand(irow, jcol, 0)) { |
| is = prev(irow); |
| if (is < 0) |
| error("Vertical spanning in first row not allowed"); |
| start = table[is][jcol].col; |
| strig = table[is][jcol].rcol; |
| while (irow < nlin && vspand(irow, jcol, 0)) |
| irow++; |
| table[--irow][jcol].col = start; |
| table[irow][jcol].rcol = strig; |
| while (is < irow) { |
| table[is][jcol].rcol = 0; |
| table[is][jcol].col = SPAN; |
| is = next(is); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| int |
| vspand(int ir, int ij, int ifform) |
| { |
| if (ir < 0) |
| return(0); |
| if (ir >= nlin) |
| return(0); |
| if (instead[ir]) |
| return(0); |
| if (ifform == 0 && ctype(ir, ij) == '^') |
| return(1); |
| if (table[ir][ij].rcol != 0) |
| return(0); |
| if (fullbot[ir]) |
| return(0); |
| return(vspen(table[ir][ij].col)); |
| } |
| |
| |
| int |
| vspen(char *s) |
| { |
| if (s == 0) |
| return(0); |
| if (!point(s)) |
| return(0); |
| return(match(s, SPAN)); |
| } |
| |
| |