1 /* t5.c: read data for table */ 2 # include "t.h" 3 4 void 5 gettbl(void) 6 { 7 int icol, ch; 8 9 cstore = cspace = chspace(); 10 textflg = 0; 11 for (nlin = nslin = 0; gets1(cstore, MAXCHS - (cstore - cspace)); nlin++) { 12 stynum[nlin] = nslin; 13 if (prefix(".TE", cstore)) { 14 leftover = 0; 15 break; 16 } 17 if (prefix(".TC", cstore) || prefix(".T&", cstore)) { 18 readspec(); 19 nslin++; 20 } 21 if (nlin >= MAXLIN) { 22 leftover = cstore; 23 break; 24 } 25 fullbot[nlin] = 0; 26 if (cstore[0] == '.' && !isdigit(cstore[1])) { 27 instead[nlin] = cstore; 28 while (*cstore++) 29 ; 30 continue; 31 } else 32 instead[nlin] = 0; 33 if (nodata(nlin)) { 34 if (ch = oneh(nlin)) 35 fullbot[nlin] = ch; 36 table[nlin] = (struct colstr *) alocv((ncol + 2) * sizeof(table[0][0])); 37 for (icol = 0; icol < ncol; icol++) { 38 table[nlin][icol].rcol = ""; 39 table[nlin][icol].col = ""; 40 } 41 nlin++; 42 nslin++; 43 fullbot[nlin] = 0; 44 instead[nlin] = (char *) 0; 45 } 46 table[nlin] = (struct colstr *) alocv((ncol + 2) * sizeof(table[0][0])); 47 if (cstore[1] == 0) 48 switch (cstore[0]) { 49 case '_': 50 fullbot[nlin] = '-'; 51 continue; 52 case '=': 53 fullbot[nlin] = '='; 54 continue; 55 } 56 stynum[nlin] = nslin; 57 nslin = min(nslin + 1, nclin - 1); 58 for (icol = 0; icol < ncol; icol++) { 59 table[nlin][icol].col = cstore; 60 table[nlin][icol].rcol = 0; 61 ch = 1; 62 if (match(cstore, "T{")) { /* text follows */ 63 table[nlin][icol].col = 64 (char *)gettext(cstore, nlin, icol, 65 font[icol][stynum[nlin]], 66 csize[icol][stynum[nlin]]); 67 } else 68 { 69 for (; (ch = *cstore) != '\0' && ch != tab; cstore++) 70 ; 71 *cstore++ = '\0'; 72 switch (ctype(nlin, icol)) /* numerical or alpha, subcol */ { 73 case 'n': 74 table[nlin][icol].rcol = maknew(table[nlin][icol].col); 75 break; 76 case 'a': 77 table[nlin][icol].rcol = table[nlin][icol].col; 78 table[nlin][icol].col = ""; 79 break; 80 } 81 } 82 while (ctype(nlin, icol + 1) == 's') /* spanning */ 83 table[nlin][++icol].col = ""; 84 if (ch == '\0') 85 break; 86 } 87 while (++icol < ncol + 2) { 88 table[nlin][icol].col = ""; 89 table [nlin][icol].rcol = 0; 90 } 91 while (*cstore != '\0') 92 cstore++; 93 if (cstore - cspace + MAXLINLEN > MAXCHS) 94 cstore = cspace = chspace(); 95 } 96 last = cstore; 97 permute(); 98 if (textflg) 99 untext(); 100 } 101 102 103 int 104 nodata(int il) 105 { 106 int c; 107 108 for (c = 0; c < ncol; c++) { 109 switch (ctype(il, c)) { 110 case 'c': 111 case 'n': 112 case 'r': 113 case 'l': 114 case 's': 115 case 'a': 116 return(0); 117 } 118 } 119 return(1); 120 } 121 122 123 int 124 oneh(int lin) 125 { 126 int k, icol; 127 128 k = ctype(lin, 0); 129 for (icol = 1; icol < ncol; icol++) { 130 if (k != ctype(lin, icol)) 131 return(0); 132 } 133 return(k); 134 } 135 136 137 # define SPAN "\\^" 138 139 void 140 permute(void) 141 { 142 int irow, jcol, is; 143 char *start, *strig; 144 145 for (jcol = 0; jcol < ncol; jcol++) { 146 for (irow = 1; irow < nlin; irow++) { 147 if (vspand(irow, jcol, 0)) { 148 is = prev(irow); 149 if (is < 0) 150 error("Vertical spanning in first row not allowed"); 151 start = table[is][jcol].col; 152 strig = table[is][jcol].rcol; 153 while (irow < nlin && vspand(irow, jcol, 0)) 154 irow++; 155 table[--irow][jcol].col = start; 156 table[irow][jcol].rcol = strig; 157 while (is < irow) { 158 table[is][jcol].rcol = 0; 159 table[is][jcol].col = SPAN; 160 is = next(is); 161 } 162 } 163 } 164 } 165 } 166 167 168 int 169 vspand(int ir, int ij, int ifform) 170 { 171 if (ir < 0) 172 return(0); 173 if (ir >= nlin) 174 return(0); 175 if (instead[ir]) 176 return(0); 177 if (ifform == 0 && ctype(ir, ij) == '^') 178 return(1); 179 if (table[ir][ij].rcol != 0) 180 return(0); 181 if (fullbot[ir]) 182 return(0); 183 return(vspen(table[ir][ij].col)); 184 } 185 186 187 int 188 vspen(char *s) 189 { 190 if (s == 0) 191 return(0); 192 if (!point(s)) 193 return(0); 194 return(match(s, SPAN)); 195 } 196 197 198