tu.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* tu.c: draws horizontal lines */
  2. # include "t.h"
  3. void
  4. makeline(int i, int c, int lintype)
  5. {
  6. int cr, type, shortl;
  7. type = thish(i, c);
  8. if (type == 0)
  9. return;
  10. shortl = (table[i][c].col[0] == '\\');
  11. if (c > 0 && !shortl && thish(i, c - 1) == type)
  12. return;
  13. if (shortl == 0)
  14. for (cr = c; cr < ncol && (ctype(i, cr) == 's' || type == thish(i, cr)); cr++)
  15. ;
  16. else
  17. for (cr = c + 1; cr < ncol && ctype(i, cr) == 's'; cr++)
  18. ;
  19. drawline(i, c, cr - 1, lintype, 0, shortl);
  20. }
  21. void
  22. fullwide(int i, int lintype)
  23. {
  24. int cr, cl;
  25. if (!pr1403)
  26. Bprint(&tabout, ".nr %d \\n(.v\n.vs \\n(.vu-\\n(.sp\n", SVS);
  27. cr = 0;
  28. while (cr < ncol) {
  29. cl = cr;
  30. while (i > 0 && vspand(prev(i), cl, 1))
  31. cl++;
  32. for (cr = cl; cr < ncol; cr++)
  33. if (i > 0 && vspand(prev(i), cr, 1))
  34. break;
  35. if (cl < ncol)
  36. drawline(i, cl, (cr < ncol ? cr - 1 : cr), lintype, 1, 0);
  37. }
  38. Bprint(&tabout, "\n");
  39. if (!pr1403)
  40. Bprint(&tabout, ".vs \\n(%du\n", SVS);
  41. }
  42. void
  43. drawline(int i, int cl, int cr, int lintype, int noheight, int shortl)
  44. {
  45. char *exhr, *exhl, *lnch;
  46. int lcount, ln, linpos, oldpos, nodata;
  47. lcount = 0;
  48. exhr = exhl = "";
  49. switch (lintype) {
  50. case '-':
  51. lcount = 1;
  52. break;
  53. case '=':
  54. lcount = pr1403 ? 1 : 2;
  55. break;
  56. case SHORTLINE:
  57. lcount = 1;
  58. break;
  59. }
  60. if (lcount <= 0)
  61. return;
  62. nodata = cr - cl >= ncol || noheight || allh(i);
  63. if (!nodata)
  64. Bprint(&tabout, "\\v'-.5m'");
  65. for (ln = oldpos = 0; ln < lcount; ln++) {
  66. linpos = 2 * ln - lcount + 1;
  67. if (linpos != oldpos)
  68. Bprint(&tabout, "\\v'%dp'", linpos - oldpos);
  69. oldpos = linpos;
  70. if (shortl == 0) {
  71. tohcol(cl);
  72. if (lcount > 1) {
  73. switch (interv(i, cl)) {
  74. case TOP:
  75. exhl = ln == 0 ? "1p" : "-1p";
  76. break;
  77. case BOT:
  78. exhl = ln == 1 ? "1p" : "-1p";
  79. break;
  80. case THRU:
  81. exhl = "1p";
  82. break;
  83. }
  84. if (exhl[0])
  85. Bprint(&tabout, "\\h'%s'", exhl);
  86. } else if (lcount == 1) {
  87. switch (interv(i, cl)) {
  88. case TOP:
  89. case BOT:
  90. exhl = "-1p";
  91. break;
  92. case THRU:
  93. exhl = "1p";
  94. break;
  95. }
  96. if (exhl[0])
  97. Bprint(&tabout, "\\h'%s'", exhl);
  98. }
  99. if (lcount > 1) {
  100. switch (interv(i, cr + 1)) {
  101. case TOP:
  102. exhr = ln == 0 ? "-1p" : "+1p";
  103. break;
  104. case BOT:
  105. exhr = ln == 1 ? "-1p" : "+1p";
  106. break;
  107. case THRU:
  108. exhr = "-1p";
  109. break;
  110. }
  111. } else if (lcount == 1) {
  112. switch (interv(i, cr + 1)) {
  113. case TOP:
  114. case BOT:
  115. exhr = "+1p";
  116. break;
  117. case THRU:
  118. exhr = "-1p";
  119. break;
  120. }
  121. }
  122. } else
  123. Bprint(&tabout, "\\h'|\\n(%2su'", reg(cl, CLEFT));
  124. Bprint(&tabout, "\\s\\n(%d", LSIZE);
  125. if (linsize)
  126. Bprint(&tabout, "\\v'-\\n(%dp/6u'", LSIZE);
  127. if (shortl)
  128. Bprint(&tabout, "\\l'|\\n(%2su'", reg(cr, CRIGHT));
  129. else
  130. {
  131. lnch = "\\(ul";
  132. if (pr1403)
  133. lnch = lintype == 2 ? "=" : "\\(ru";
  134. if (cr + 1 >= ncol)
  135. Bprint(&tabout, "\\l'|\\n(TWu%s%s'", exhr, lnch);
  136. else
  137. Bprint(&tabout, "\\l'(|\\n(%2su+|\\n(%2su)/2u%s%s'", reg(cr, CRIGHT),
  138. reg(cr + 1, CLEFT), exhr, lnch);
  139. }
  140. if (linsize)
  141. Bprint(&tabout, "\\v'\\n(%dp/6u'", LSIZE);
  142. Bprint(&tabout, "\\s0");
  143. }
  144. if (oldpos != 0)
  145. Bprint(&tabout, "\\v'%dp'", -oldpos);
  146. if (!nodata)
  147. Bprint(&tabout, "\\v'+.5m'");
  148. }
  149. void
  150. getstop(void)
  151. {
  152. int i, c, k, junk, stopp;
  153. stopp = 1;
  154. for (i = 0; i < MAXLIN; i++)
  155. linestop[i] = 0;
  156. for (i = 0; i < nlin; i++)
  157. for (c = 0; c < ncol; c++) {
  158. k = left(i, c, &junk);
  159. if (k >= 0 && linestop[k] == 0)
  160. linestop[k] = ++stopp;
  161. }
  162. if (boxflg || allflg || dboxflg)
  163. linestop[0] = 1;
  164. }
  165. int
  166. left(int i, int c, int *lwidp)
  167. {
  168. int kind, li, lj;
  169. /* returns -1 if no line to left */
  170. /* returns number of line where it starts */
  171. /* stores into lwid the kind of line */
  172. *lwidp = 0;
  173. if (i < 0)
  174. return(-1);
  175. kind = lefdata(i, c);
  176. if (kind == 0)
  177. return(-1);
  178. if (i + 1 < nlin)
  179. if (lefdata(next(i), c) == kind)
  180. return(-1);
  181. li = i;
  182. while (i >= 0 && lefdata(i, c) == kind)
  183. i = prev(li = i);
  184. if (prev(li) == -1)
  185. li = 0;
  186. *lwidp = kind;
  187. for (lj = i + 1; lj < li; lj++)
  188. if (instead[lj] && strcmp(instead[lj], ".TH") == 0)
  189. return(li);
  190. for (i = i + 1; i < li; i++)
  191. if (fullbot[i])
  192. li = i;
  193. return(li);
  194. }
  195. int
  196. lefdata(int i, int c)
  197. {
  198. int ck;
  199. if (i >= nlin)
  200. i = nlin - 1;
  201. if (ctype(i, c) == 's') {
  202. for (ck = c; ctype(i, ck) == 's'; ck--)
  203. ;
  204. if (thish(i, ck) == 0)
  205. return(0);
  206. }
  207. i = stynum[i];
  208. i = lefline[c][i];
  209. if (i > 0)
  210. return(i);
  211. if (dboxflg && c == 0)
  212. return(2);
  213. if (allflg)
  214. return(1);
  215. if (boxflg && c == 0)
  216. return(1);
  217. return(0);
  218. }
  219. int
  220. next(int i)
  221. {
  222. while (i + 1 < nlin) {
  223. i++;
  224. if (!fullbot[i] && !instead[i])
  225. break;
  226. }
  227. return(i);
  228. }
  229. int
  230. prev(int i)
  231. {
  232. while (--i >= 0 && (fullbot[i] || instead[i]))
  233. ;
  234. return(i);
  235. }