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 [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 @\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 = "%s@"; break;
186: case 'R': case 'r':
187: format= "@%s"; break;
188: case 'n': case 'N':
189: if (!dwide[icol] || tabentry[ilin][icol+1] != 0)
190: {
191: format=dwide[icol]? "@%s" : "%s@";
192: break;
193: }
194: case 'c': case 'C':
195: format = "@%s@"; 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: }