Research V6 development
[unix-history] / usr / source / s2 / tbl.c
CommitLineData
bce7f56c
ML
1#
2# define ever (;;)
3# define MAXCHS 2000
4main(argc,argv)
5 char *argv[];
6{
7char line[200];
8extern int cin;
9extern char *cspace;
10 cspace = getvec(MAXCHS + 100);
11for ever
12{
13 if (argc>1)
14 {
15 argc--;
16 argv++;
17 if (match(*argv, "-ms"))
18 *argv = "/usr/lib/tmac.s";
19 cin = copen(*argv, 'r');
20 if (cin < 0)
21 {
22 printf(2,"where is input file %s\n",*argv);
23 cexit();
24 }
25 }
26while (gets(line))
27 if (match(line, ".TS"))
28 tableput();
29 else
30 puts(line);
31if (argc <= 1) break;
32}
33cexit();
34}
35# define MAXCOL 35
36# define MAXLIN 220
37# define ONELINE 250
38char *tabentry[MAXLIN][MAXCOL];
39char extra[MAXCHS];
40char *cspace, *cstore;
41char *exstore extra;
42int sep[MAXCOL], dwide[MAXCOL];
43char *instead[MAXLIN];
44int newtab[MAXLIN];
45char *style[MAXCOL];
46tableput()
47{
48/* read input, write output, make tables on the way */
49char st[ONELINE], *format;
50int ilin, nlin, icol, ncol, k, ch, ws, cs, ns;
51int maxchnge, ct;
52printf(".TS\n");
53/* get command line */
54cstore = cspace;
55exstore = extra;
56ncol = 0;
57for (ilin=0; ilin<MAXLIN; ilin++)
58 newtab[ilin]=0;
59gets (st);
60for (k=0; k<ONELINE && st[k] != '\0'; k++)
61 if (!space(st[k]))
62 {
63 style[ncol] = st+k;
64 dwide[ncol] =0;
65 for(; letter(st[k]); k++)
66 {
67 if ((st[k]=='n' || st[k] == 'N') &&
68 !dwide[ncol])
69 {
70 dwide[ncol]=1;
71 sep[ncol++] = 0;
72 style[ncol] = style[ncol-1];
73 dwide [ncol] = 0;
74 }
75 }
76 if (digit(st[k]))
77 sep[ncol] = numb(st+k);
78 else
79 sep[ncol] = 3;
80 ncol++;
81 while (digit(st[k]))
82 st[k++] = '\0';
83 if (st[k] == '\0')
84 break;
85 st[k] = '\0';
86 }
87/* now get input lines */
88for (nlin=0; gets(cstore) && !match(cstore, ".TE"); nlin++)
89 {
90 if (cstore[0] == '.' && letter(cstore[1]))
91 {
92 instead[nlin] = cstore;
93 while (*cstore) cstore++;
94 }
95 else instead[nlin] = 0;
96 for (icol = 0; icol <ncol; icol++)
97 {
98 tabentry[nlin][icol] = cstore;
99 for(; (ch= *cstore) != '\0' && ch != '\t'; cstore++)
100 ;
101 *cstore++ = '\0';
102 if (dwide[icol] )
103 if (broken(style[icol],nlin))
104 {
105 tabentry[nlin][icol+1]=maknew(tabentry[nlin][icol]);
106 icol++;
107 if (tabentry[nlin][icol] ==0)
108 newtab[nlin]=newtab[nlin+1]=1;
109 }
110 else
111 tabentry[nlin][++icol] = 0;
112 while (span(style[icol+1],nlin) )
113 tabentry[nlin][++icol] = "";
114 if (ch == '\0') break;
115 }
116 while (++icol <ncol)
117 tabentry[nlin][icol] = "";
118 while (*cstore != '\0')
119 *cstore++;
120 if (cstore-cspace > MAXCHS)
121 cstore = cspace = getvec(MAXCHS+100);
122 }
123/* find longest command string */
124for (icol=maxchnge=0; icol<ncol; icol++)
125 if (slen(style[icol]) >maxchnge)
126 maxchnge = slen(style[icol]);
127/* set tab stops */
128printf(".nr 49 0\n");
129for (icol = 0; icol<ncol; icol++)
130 {
131 ct = 1 + (icol>0 ? sep[icol-1] : 0);
132 printf(".nr %2d 0\n", icol+50);
133 for (ilin=0; ilin < nlin; ilin++)
134 {
135 if (icol>0 && dwide[icol-1]>0 && tabentry[ilin][icol]==0)
136 {
137 printf(".nr 48 \\n(%2d+\\w'%s'+%dn\n",
138 icol+48, tabentry[ilin][icol-1], sep[icol-1]);
139 printf(".if \\n(48-\\n(%2d .nr %2d \\n(48\n",
140 icol+50,icol+50);
141 }
142 if ( !span(style[icol],ilin) && /* not part of span */
143 (dwide[icol] == 0 || tabentry[ilin][icol+1]!= 0)
144 /* not a double item */
145 && (!span(style[icol+1],ilin) || icol==ncol))
146 {
147 printf(".nr 47 \\n(%2d+\\w'%s'+%dn\n",
148 icol+49,tabentry[ilin][icol], ct);
149 printf(".if \\n(47-\\n(%2d .nr %2d \\n(47\n",
150 icol+50,icol+50);
151 }
152 }
153 /* clean up spanned headings */
154 for(ilin=0; ilin<maxchnge; ilin++)
155 {
156 if( !(span(style[icol],ilin)) &&
157 (icol ==1 || dwide[icol-1] == 0) &&
158 span(style[icol+(dwide[icol]?2:1)],ilin))
159 printf(".nr %d \\n(%2d+\\w'%s'+%dn\n",
160 ilin+30, icol+49, tabentry[ilin][icol], ct);
161 else if (span(style[icol],ilin) &&
162 (icol+1==ncol || !span(style[icol+1],ilin)))
163 printf(".if \\n(%d-\\n(%d .nr %d \\n(%d\n",
164 30+ilin, icol+50, icol+50, ilin+30);
165 }
166 }
167/* run out table, put field characters in */
168printf (".fc \a @\n");
169for (ilin=0; ilin<nlin; ilin++)
170 {
171 if (instead[ilin])
172 {
173 printf("%s\n",instead[ilin]);
174 continue;
175 }
176 /* is a new set of tab stops needed */
177 if (ilin < maxchnge || newtab[ilin])
178 settab(ncol, ilin);
179 for (icol=0; icol<ncol; icol++)
180 {
181 switch ( ylet(style[icol],ilin))
182 {
183 default:
184 case 'L': case 'l':
185 format = "\a%s@\a"; break;
186 case 'R': case 'r':
187 format= "\a@%s\a"; break;
188 case 'n': case 'N':
189 if (!dwide[icol] || tabentry[ilin][icol+1] != 0)
190 {
191 format=dwide[icol]? "\a@%s\a" : "\a%s@\a";
192 break;
193 }
194 case 'c': case 'C':
195 format = "\a@%s@\a"; break;
196 case 's': case 'S':
197 format= "";
198 break;
199 }
200 if (! (dwide [icol-1]>0 && tabentry[ilin][icol] == 0 ))
201 printf(format, tabentry[ilin][icol]);
202 if (!span(style[icol+1],ilin))
203 for (k=sep[icol]; k>0; k--)
204 printf(" ");
205 }
206 printf("\n");
207 }
208printf(".fc\n");
209printf(".TE\n");
210}
211match (s1, s2)
212 char *s1, *s2;
213{
214 while (*s1 == *s2)
215 if (*s1++ == '\0')
216 return(1);
217 else
218 *s2++;
219 return(0);
220}
221slen(str)
222 char *str;
223{
224 int k;
225 for (k=0; *str++ != '\0'; k++);
226 return(k);
227}
228space(ch)
229 {
230 switch (ch)
231 {
232 case ' ': case '\t':
233 return(1);
234 }
235 return(0);
236 }
237letter (ch)
238 {
239 if (ch >= 'a' && ch <= 'z')
240 return(1);
241 if (ch >= 'A' && ch <= 'Z')
242 return(1);
243 return(0);
244 }
245numb(str)
246 char *str;
247 {
248 /* convert to integer */
249 int k;
250 for (k=0; *str >= '0' && *str <= '9'; str++)
251 k = k*10 + *str - '0';
252 return(k);
253 }
254broken(str, nlin)
255 {
256 switch(ylet(str,nlin))
257 {
258 case 'n': case 'N':
259 return(1);
260 }
261 return(0);
262 }
263ylet (str, k)
264 char *str;
265{
266 k++;
267 while (*str &&k--)
268 str++;
269 return(*--str);
270}
271span(str, k)
272 {
273 switch(ylet(str,k))
274 {
275 case 's': case 'S':
276 return(1);
277 }
278 return(0);
279 }
280maknew(str)
281 char *str;
282{
283 /* make two numerical fields */
284 int point;
285 char *p, *q;
286 p = str;
287 for (point=0; *str; str++)
288 if (*str=='.')
289 point=1;
290 if (!point && *(str-1)== '$')
291 return(0);
292 for(; str>p; str--)
293 if ( (point && *str == '.') ||
294 (!point && digit(*(str-1)) ) )
295 break;
296 if (!point && p==str) /* not numerical, don't split */
297 return(0);
298 p= str;
299 q = exstore;
300 while (*exstore++ = *str++);
301 *p = 0;
302 return(q);
303 }
304digit(x)
305 {
306 return(x>= '0' && x<= '9');
307 }
308settab(ncol, ilin)
309{
310 int k, icol;
311 printf(".ta ");
312 for (icol = 0; icol<ncol; icol++)
313 if ((dwide[icol] == 0 || tabentry[ilin][icol+1] != 0)
314 && !span(style[icol+1],ilin))
315 printf("\\n(%du ",icol+50);
316 printf("\n");
317}