t6.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /* t6.c: compute tab stops */
  10. # define tx(a) (a>0 && a<128)
  11. # include "t.h"
  12. # define FN(i,c) font[c][stynum[i]]
  13. # define SZ(i,c) csize[c][stynum[i]]
  14. # define TMP1 S1
  15. # define TMP2 S2
  16. void
  17. maktab(void) /* define the tab stops of the table */
  18. {
  19. int icol, ilin, tsep, k, ik, vforml, il, s, text;
  20. char *ss;
  21. for (icol = 0; icol < ncol; icol++) {
  22. doubled[icol] = acase[icol] = 0;
  23. Bprint(&tabout, ".nr %2s 0\n", reg(icol, CRIGHT));
  24. for (text = 0; text < 2; text++) {
  25. if (text)
  26. Bprint(&tabout, ".%2s\n.rm %2s\n", reg(icol, CRIGHT),
  27. reg(icol, CRIGHT));
  28. for (ilin = 0; ilin < nlin; ilin++) {
  29. if (instead[ilin] || fullbot[ilin])
  30. continue;
  31. vforml = ilin;
  32. for (il = prev(ilin); il >= 0 && vspen(table[il][icol].col); il = prev(il))
  33. vforml = il;
  34. if (fspan(vforml, icol))
  35. continue;
  36. if (filler(table[ilin][icol].col))
  37. continue;
  38. if ((flags[icol][stynum[ilin]] & ZEROW) != 0)
  39. continue;
  40. switch (ctype(vforml, icol)) {
  41. case 'a':
  42. acase[icol] = 1;
  43. ss = table[ilin][icol].col;
  44. s = (int)(uintptr)ss;
  45. if (s > 0 && s < 128 && text) {
  46. if (doubled[icol] == 0)
  47. Bprint(&tabout, ".nr %d 0\n.nr %d 0\n",
  48. S1, S2);
  49. doubled[icol] = 1;
  50. Bprint(&tabout, ".if \\n(%c->\\n(%d .nr %d \\n(%c-\n",
  51. s, S2, S2, (int)s);
  52. }
  53. case 'n':
  54. if (table[ilin][icol].rcol != 0) {
  55. if (doubled[icol] == 0 && text == 0)
  56. Bprint(&tabout, ".nr %d 0\n.nr %d 0\n",
  57. S1, S2);
  58. doubled[icol] = 1;
  59. if (real(ss = table[ilin][icol].col) && !vspen(ss)) {
  60. s = (int)(uintptr)ss;
  61. if (tx(s) != text)
  62. continue;
  63. Bprint(&tabout, ".nr %d ", TMP);
  64. wide(ss, FN(vforml, icol), SZ(vforml, icol));
  65. Bprint(&tabout, "\n");
  66. Bprint(&tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n",
  67. S1, TMP, S1, TMP);
  68. }
  69. if (text == 0 && real(ss = table[ilin][icol].rcol) && !vspen(ss) && !barent(ss)) {
  70. Bprint(&tabout, ".nr %d \\w%c%s%c\n",
  71. TMP, F1, ss, F1);
  72. Bprint(&tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n", S2, TMP, S2,
  73. TMP);
  74. }
  75. continue;
  76. }
  77. case 'r':
  78. case 'c':
  79. case 'l':
  80. if (real(ss = table[ilin][icol].col) && !vspen(ss)) {
  81. s = (int)(uintptr)ss;
  82. if (tx(s) != text)
  83. continue;
  84. Bprint(&tabout, ".nr %d ", TMP);
  85. wide(ss, FN(vforml, icol), SZ(vforml, icol));
  86. Bprint(&tabout, "\n");
  87. Bprint(&tabout, ".if \\n(%2s<\\n(%d .nr %2s \\n(%d\n",
  88. reg(icol, CRIGHT), TMP, reg(icol, CRIGHT), TMP);
  89. }
  90. }
  91. }
  92. }
  93. if (acase[icol]) {
  94. Bprint(&tabout, ".if \\n(%d>=\\n(%2s .nr %2s \\n(%du+2n\n",
  95. S2, reg(icol, CRIGHT), reg(icol, CRIGHT), S2);
  96. }
  97. if (doubled[icol]) {
  98. Bprint(&tabout, ".nr %2s \\n(%d\n", reg(icol, CMID), S1);
  99. Bprint(&tabout, ".nr %d \\n(%2s+\\n(%d\n", TMP, reg(icol, CMID), S2);
  100. Bprint(&tabout, ".if \\n(%d>\\n(%2s .nr %2s \\n(%d\n", TMP,
  101. reg(icol, CRIGHT), reg(icol, CRIGHT), TMP);
  102. Bprint(&tabout, ".if \\n(%d<\\n(%2s .nr %2s +(\\n(%2s-\\n(%d)/2\n",
  103. TMP, reg(icol, CRIGHT), reg(icol, CMID), reg(icol, CRIGHT), TMP);
  104. }
  105. if (cll[icol][0]) {
  106. Bprint(&tabout, ".nr %d %sn\n", TMP, cll[icol]);
  107. Bprint(&tabout, ".if \\n(%2s<\\n(%d .nr %2s \\n(%d\n",
  108. reg(icol, CRIGHT), TMP, reg(icol, CRIGHT), TMP);
  109. }
  110. for (ilin = 0; ilin < nlin; ilin++)
  111. if (k = lspan(ilin, icol)) {
  112. ss = table[ilin][icol-k].col;
  113. if (!real(ss) || barent(ss) || vspen(ss) )
  114. continue;
  115. Bprint(&tabout, ".nr %d ", TMP);
  116. wide(table[ilin][icol-k].col, FN(ilin, icol - k), SZ(ilin, icol - k));
  117. for (ik = k; ik >= 0; ik--) {
  118. Bprint(&tabout, "-\\n(%2s", reg(icol - ik, CRIGHT));
  119. if (!expflg && ik > 0)
  120. Bprint(&tabout, "-%dn", sep[icol-ik]);
  121. }
  122. Bprint(&tabout, "\n");
  123. Bprint(&tabout, ".if \\n(%d>0 .nr %d \\n(%d/%d\n", TMP,
  124. TMP, TMP, k);
  125. Bprint(&tabout, ".if \\n(%d<0 .nr %d 0\n", TMP, TMP);
  126. for (ik = 1; ik <= k; ik++) {
  127. if (doubled[icol-k+ik])
  128. Bprint(&tabout, ".nr %2s +\\n(%d/2\n",
  129. reg(icol - k + ik, CMID), TMP);
  130. Bprint(&tabout, ".nr %2s +\\n(%d\n",
  131. reg(icol - k + ik, CRIGHT), TMP);
  132. }
  133. }
  134. }
  135. if (textflg)
  136. untext();
  137. /* if even requested, make all columns widest width */
  138. if (evenflg) {
  139. Bprint(&tabout, ".nr %d 0\n", TMP);
  140. for (icol = 0; icol < ncol; icol++) {
  141. if (evenup[icol] == 0)
  142. continue;
  143. Bprint(&tabout, ".if \\n(%2s>\\n(%d .nr %d \\n(%2s\n",
  144. reg(icol, CRIGHT), TMP, TMP, reg(icol, CRIGHT));
  145. }
  146. for (icol = 0; icol < ncol; icol++) {
  147. if (evenup[icol] == 0)
  148. /* if column not evened just retain old interval */
  149. continue;
  150. if (doubled[icol])
  151. Bprint(&tabout, ".nr %2s (100*\\n(%2s/\\n(%2s)*\\n(%d/100\n",
  152. reg(icol, CMID), reg(icol, CMID), reg(icol, CRIGHT), TMP);
  153. /* that nonsense with the 100's and parens tries
  154. to avoid overflow while proportionally shifting
  155. the middle of the number */
  156. Bprint(&tabout, ".nr %2s \\n(%d\n", reg(icol, CRIGHT), TMP);
  157. }
  158. }
  159. /* now adjust for total table width */
  160. for (tsep = icol = 0; icol < ncol; icol++)
  161. tsep += sep[icol];
  162. if (expflg) {
  163. Bprint(&tabout, ".nr %d 0", TMP);
  164. for (icol = 0; icol < ncol; icol++)
  165. Bprint(&tabout, "+\\n(%2s", reg(icol, CRIGHT));
  166. Bprint(&tabout, "\n");
  167. Bprint(&tabout, ".nr %d \\n(.l-\\n(%d\n", TMP, TMP);
  168. if (boxflg || dboxflg || allflg)
  169. /* tsep += 1; */ {}
  170. else
  171. tsep -= sep[ncol-1];
  172. Bprint(&tabout, ".nr %d \\n(%d/%d\n", TMP, TMP, tsep);
  173. Bprint(&tabout, ".if \\n(%d<0 .nr %d 0\n", TMP, TMP);
  174. } else
  175. Bprint(&tabout, ".nr %d 1n\n", TMP);
  176. Bprint(&tabout, ".nr %2s 0\n", reg(-1, CRIGHT));
  177. tsep = (boxflg || allflg || dboxflg || left1flg) ? 2 : 0;
  178. if (sep[-1] >= 0)
  179. tsep = sep[-1];
  180. for (icol = 0; icol < ncol; icol++) {
  181. Bprint(&tabout, ".nr %2s \\n(%2s+((%d*\\n(%d)/2)\n", reg(icol, CLEFT),
  182. reg(icol - 1, CRIGHT), tsep, TMP);
  183. Bprint(&tabout, ".nr %2s +\\n(%2s\n", reg(icol, CRIGHT), reg(icol, CLEFT));
  184. if (doubled[icol]) {
  185. /* the next line is last-ditch effort to avoid zero field width */
  186. /*Bprint(&tabout, ".if \\n(%2s=0 .nr %2s 1\n",reg(icol,CMID), reg(icol,CMID));*/
  187. Bprint(&tabout, ".nr %2s +\\n(%2s\n", reg(icol, CMID),
  188. reg(icol, CLEFT));
  189. /* Bprint(&tabout, ".if n .if \\n(%s%%24>0 .nr %s +12u\n",reg(icol,CMID), reg(icol,CMID)); */
  190. }
  191. tsep = sep[icol] * 2;
  192. }
  193. if (rightl)
  194. Bprint(&tabout, ".nr %s (\\n(%s+\\n(%s)/2\n", reg(ncol - 1, CRIGHT),
  195. reg(ncol - 1, CLEFT), reg(ncol - 2, CRIGHT));
  196. Bprint(&tabout, ".nr TW \\n(%2s\n", reg(ncol - 1, CRIGHT));
  197. tsep = sep[ncol-1];
  198. if (boxflg || allflg || dboxflg)
  199. Bprint(&tabout, ".nr TW +((%d*\\n(%d)/2)\n", tsep, TMP);
  200. Bprint(&tabout,
  201. ".if t .if (\\n(TW>\\n(.l .tm Table at line %d file %s is too wide - \\n(TW units\n", iline - 1, ifile);
  202. /*
  203. * Used to be:
  204. ".if t .if (\\n(TW+\\n(.o)>7.65i .tm Table at line %d file %s is too wide - \\n(TW units\n", iline - 1, ifile);
  205. * but that gives warnings where none are necessary (or desired) [sape]
  206. */
  207. }
  208. void
  209. wide(char *s, char *fn, char *size)
  210. {
  211. if (point(s)) {
  212. Bprint(&tabout, "\\w%c", F1);
  213. if (*fn > 0)
  214. putfont(fn);
  215. if (*size)
  216. putsize(size);
  217. Bprint(&tabout, "%s", s);
  218. if (*fn > 0)
  219. putfont("P");
  220. if (*size)
  221. putsize("0");
  222. Bprint(&tabout, "%c", F1);
  223. } else
  224. Bprint(&tabout, "\\n(%c-", (int)(uintptr)s);
  225. }
  226. int
  227. filler(char *s)
  228. {
  229. return (point(s) && s[0] == '\\' && s[1] == 'R');
  230. }