t2.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include "a.h"
  2. /*
  3. * Section 2 - Font and character size control.
  4. */
  5. /* 2.1 - Character set */
  6. /* XXX
  7. *
  8. * \C'name' - character named name
  9. * \N'n' - character number
  10. * \(xx - two-letter character
  11. * \-
  12. * \`
  13. * \'
  14. * `
  15. * '
  16. * -
  17. */
  18. Rune*
  19. getqarg(void)
  20. {
  21. static Rune buf[MaxLine];
  22. int c;
  23. Rune *p, *e;
  24. p = buf;
  25. e = p+sizeof buf-1;
  26. if(getrune() != '\'')
  27. return nil;
  28. while(p < e){
  29. c = getrune();
  30. if(c < 0)
  31. return nil;
  32. if(c == '\'')
  33. break;
  34. *p++ = c;
  35. }
  36. *p = 0;
  37. return buf;
  38. }
  39. int
  40. e_N(void)
  41. {
  42. Rune *a;
  43. if((a = getqarg()) == nil)
  44. goto error;
  45. return eval(a);
  46. error:
  47. warn("malformed %CN'...'", backslash);
  48. return 0;
  49. }
  50. int
  51. e_paren(void)
  52. {
  53. int c, cc;
  54. Rune buf[2], r;
  55. if((c = getrune()) < 0 || c == '\n')
  56. goto error;
  57. if((cc = getrune()) < 0 || cc == '\n')
  58. goto error;
  59. buf[0] = c;
  60. buf[1] = cc;
  61. r = troff2rune(buf);
  62. if(r == Runeerror)
  63. warn("unknown char %C(%C%C", backslash, c, cc);
  64. return r;
  65. error:
  66. warn("malformed %C(xx", backslash);
  67. return 0;
  68. }
  69. /* 2.2 - Fonts */
  70. Rune fonttab[10][100];
  71. /*
  72. * \fx \f(xx \fN - font change
  73. * number register .f - current font
  74. * \f0 previous font (undocumented?)
  75. */
  76. /* change to font f. also \fx, \f(xx, \fN */
  77. /* .ft LongName is okay - temporarily at fp 0 */
  78. void
  79. ft(Rune *f)
  80. {
  81. int i;
  82. int fn;
  83. if(f && runestrcmp(f, L("P")) == 0)
  84. f = nil;
  85. if(f == nil)
  86. fn = 0;
  87. else if(isdigit(f[0]))
  88. fn = eval(f);
  89. else{
  90. for(i=0; i<nelem(fonttab); i++){
  91. if(runestrcmp(fonttab[i], f) == 0){
  92. fn = i;
  93. goto have;
  94. }
  95. }
  96. warn("unknown font %S", f);
  97. fn = 1;
  98. }
  99. have:
  100. if(fn < 0 || fn >= nelem(fonttab)){
  101. warn("unknown font %d", fn);
  102. fn = 1;
  103. }
  104. if(fn == 0)
  105. fn = getnr(L(".f0"));
  106. nr(L(".f0"), getnr(L(".f")));
  107. nr(L(".f"), fn);
  108. runmacro1(L("font"));
  109. }
  110. /* mount font named f on physical position N */
  111. void
  112. fp(int i, Rune *f)
  113. {
  114. if(i <= 0 || i >= nelem(fonttab)){
  115. warn("bad font position %d", i);
  116. return;
  117. }
  118. runestrecpy(fonttab[i], fonttab[i]+sizeof fonttab[i], f);
  119. }
  120. int
  121. e_f(void)
  122. {
  123. ft(getname());
  124. return 0;
  125. }
  126. void
  127. r_ft(int argc, Rune **argv)
  128. {
  129. if(argc == 1)
  130. ft(nil);
  131. else
  132. ft(argv[1]);
  133. }
  134. void
  135. r_fp(int argc, Rune **argv)
  136. {
  137. if(argc < 3){
  138. warn("missing arguments to %Cfp", dot);
  139. return;
  140. }
  141. fp(eval(argv[1]), argv[2]);
  142. }
  143. /* 2.3 - Character size */
  144. /* \H'±N' sets height */
  145. void
  146. ps(int s)
  147. {
  148. if(s == 0)
  149. s = getnr(L(".s0"));
  150. nr(L(".s0"), getnr(L(".s")));
  151. nr(L(".s"), s);
  152. runmacro1(L("font"));
  153. }
  154. /* set point size */
  155. void
  156. r_ps(int argc, Rune **argv)
  157. {
  158. Rune *p;
  159. if(argc == 1 || argv[1][0] == 0)
  160. ps(0);
  161. else{
  162. p = argv[1];
  163. if(p[0] == '-')
  164. ps(getnr(L(".s"))-eval(p+1));
  165. else if(p[0] == '+')
  166. ps(getnr(L(".s"))+eval(p+1));
  167. else
  168. ps(eval(p));
  169. }
  170. }
  171. int
  172. e_s(void)
  173. {
  174. int c, cc, ccc, n, twodigit;
  175. c = getnext();
  176. if(c < 0)
  177. return 0;
  178. if(c == '+' || c == '-'){
  179. cc = getnext();
  180. if(cc == '('){
  181. cc = getnext();
  182. ccc = getnext();
  183. if(cc < '0' || cc > '9' || ccc < '0' || ccc > '9'){
  184. warn("bad size %Cs%C(%C%C", backslash, c, cc, ccc);
  185. return 0;
  186. }
  187. n = (cc-'0')*10+ccc-'0';
  188. }else{
  189. if(cc < '0' || cc > '9'){
  190. warn("bad size %Cs%C%C", backslash, c, cc);
  191. return 0;
  192. }
  193. n = cc-'0';
  194. }
  195. if(c == '+')
  196. ps(getnr(L(".s"))+n);
  197. else
  198. ps(getnr(L(".s"))-n);
  199. return 0;
  200. }
  201. twodigit = 0;
  202. if(c == '('){
  203. twodigit = 1;
  204. c = getnext();
  205. if(c < 0)
  206. return 0;
  207. }
  208. if(c < '0' || c > '9'){
  209. warn("bad size %Cs%C", backslash, c);
  210. ungetnext(c);
  211. return 0;
  212. }
  213. if(twodigit || (c < '4' && c != '0')){
  214. cc = getnext();
  215. if(c < 0)
  216. return 0;
  217. n = (c-'0')*10+cc-'0';
  218. }else
  219. n = c-'0';
  220. ps(n);
  221. return 0;
  222. }
  223. void
  224. t2init(void)
  225. {
  226. fp(1, L("R"));
  227. fp(2, L("I"));
  228. fp(3, L("B"));
  229. fp(4, L("BI"));
  230. fp(5, L("CW"));
  231. nr(L(".s"), 10);
  232. nr(L(".s0"), 10);
  233. addreq(L("ft"), r_ft, -1);
  234. addreq(L("fp"), r_fp, -1);
  235. addreq(L("ps"), r_ps, -1);
  236. addreq(L("ss"), r_warn, -1);
  237. addreq(L("cs"), r_warn, -1);
  238. addreq(L("bd"), r_warn, -1);
  239. addesc('f', e_f, 0);
  240. addesc('s', e_s, 0);
  241. addesc('(', e_paren, 0); /* ) */
  242. addesc('C', e_warn, 0);
  243. addesc('N', e_N, 0);
  244. /* \- \' \` are handled in html.c */
  245. }