Commit | Line | Data |
---|---|---|
bce7f56c ML |
1 | # |
2 | # define ever (;;) | |
3 | # define MAXCHS 2000 | |
4 | main(argc,argv) | |
5 | char *argv[]; | |
6 | { | |
7 | char line[200]; | |
8 | extern int cin; | |
9 | extern char *cspace; | |
10 | cspace = getvec(MAXCHS + 100); | |
11 | for 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 | } | |
26 | while (gets(line)) | |
27 | if (match(line, ".TS")) | |
28 | tableput(); | |
29 | else | |
30 | puts(line); | |
31 | if (argc <= 1) break; | |
32 | } | |
33 | cexit(); | |
34 | } | |
35 | # define MAXCOL 35 | |
36 | # define MAXLIN 220 | |
37 | # define ONELINE 250 | |
38 | char *tabentry[MAXLIN][MAXCOL]; | |
39 | char extra[MAXCHS]; | |
40 | char *cspace, *cstore; | |
41 | char *exstore extra; | |
42 | int sep[MAXCOL], dwide[MAXCOL]; | |
43 | char *instead[MAXLIN]; | |
44 | int newtab[MAXLIN]; | |
45 | char *style[MAXCOL]; | |
46 | tableput() | |
47 | { | |
48 | /* read input, write output, make tables on the way */ | |
49 | char st[ONELINE], *format; | |
50 | int ilin, nlin, icol, ncol, k, ch, ws, cs, ns; | |
51 | int maxchnge, ct; | |
52 | printf(".TS\n"); | |
53 | /* get command line */ | |
54 | cstore = cspace; | |
55 | exstore = extra; | |
56 | ncol = 0; | |
57 | for (ilin=0; ilin<MAXLIN; ilin++) | |
58 | newtab[ilin]=0; | |
59 | gets (st); | |
60 | for (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 */ | |
88 | for (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 */ | |
124 | for (icol=maxchnge=0; icol<ncol; icol++) | |
125 | if (slen(style[icol]) >maxchnge) | |
126 | maxchnge = slen(style[icol]); | |
127 | /* set tab stops */ | |
128 | printf(".nr 49 0\n"); | |
129 | for (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 */ | |
168 | printf (".fc \a @\n"); | |
169 | for (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 | } | |
208 | printf(".fc\n"); | |
209 | printf(".TE\n"); | |
210 | } | |
211 | match (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 | } | |
221 | slen(str) | |
222 | char *str; | |
223 | { | |
224 | int k; | |
225 | for (k=0; *str++ != '\0'; k++); | |
226 | return(k); | |
227 | } | |
228 | space(ch) | |
229 | { | |
230 | switch (ch) | |
231 | { | |
232 | case ' ': case '\t': | |
233 | return(1); | |
234 | } | |
235 | return(0); | |
236 | } | |
237 | letter (ch) | |
238 | { | |
239 | if (ch >= 'a' && ch <= 'z') | |
240 | return(1); | |
241 | if (ch >= 'A' && ch <= 'Z') | |
242 | return(1); | |
243 | return(0); | |
244 | } | |
245 | numb(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 | } | |
254 | broken(str, nlin) | |
255 | { | |
256 | switch(ylet(str,nlin)) | |
257 | { | |
258 | case 'n': case 'N': | |
259 | return(1); | |
260 | } | |
261 | return(0); | |
262 | } | |
263 | ylet (str, k) | |
264 | char *str; | |
265 | { | |
266 | k++; | |
267 | while (*str &&k--) | |
268 | str++; | |
269 | return(*--str); | |
270 | } | |
271 | span(str, k) | |
272 | { | |
273 | switch(ylet(str,k)) | |
274 | { | |
275 | case 's': case 'S': | |
276 | return(1); | |
277 | } | |
278 | return(0); | |
279 | } | |
280 | maknew(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 | } | |
304 | digit(x) | |
305 | { | |
306 | return(x>= '0' && x<= '9'); | |
307 | } | |
308 | settab(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 | } |