t4.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "a.h"
  2. /*
  3. * 4 - Text filling, centering, and adjusting.
  4. * "\ " - unbreakable space
  5. * .n register - length of last line
  6. * nl register - text baseline position on this page
  7. * .h register - baseline high water mark
  8. * .k register - current horizontal output position
  9. * \p - cause break at end of word, justify
  10. * \& - non-printing zero-width filler
  11. * tr - output translation
  12. * \c - break (but don't) input line in .nf mode
  13. * \c - break (but don't) word in .fi mode
  14. */
  15. int
  16. e_space(void)
  17. {
  18. return 0xA0; /* non-breaking space */
  19. }
  20. int
  21. e_amp(void)
  22. {
  23. return Uempty;
  24. }
  25. int
  26. e_c(void)
  27. {
  28. getrune();
  29. bol = 1;
  30. return 0;
  31. }
  32. void
  33. r_br(int argc, Rune **argv)
  34. {
  35. USED(argc);
  36. USED(argv);
  37. br();
  38. }
  39. /* fill mode on */
  40. void
  41. r_fi(int argc, Rune **argv)
  42. {
  43. USED(argc);
  44. USED(argv);
  45. nr(L(".fi"), 1);
  46. // warn(".fi");
  47. }
  48. /* no-fill mode */
  49. void
  50. r_nf(int argc, Rune **argv)
  51. {
  52. USED(argc);
  53. USED(argv);
  54. nr(L(".fi"), 0);
  55. }
  56. /* adjust */
  57. void
  58. r_ad(int argc, Rune **argv)
  59. {
  60. int c, n;
  61. nr(L(".j"), getnr(L(".j"))|1);
  62. if(argc < 2)
  63. return;
  64. c = argv[1][0];
  65. switch(c){
  66. default:
  67. fprint(2, "%L: bad adjust %C\n", c);
  68. return;
  69. case 'r':
  70. n = 2*2|1;
  71. break;
  72. case 'l':
  73. n = 0;
  74. break;
  75. case 'c':
  76. n = 1*2|1;
  77. break;
  78. case 'b':
  79. case 'n':
  80. n = 0*2|1;
  81. break;
  82. case '0':
  83. case '1':
  84. case '2':
  85. case '3':
  86. case '4':
  87. case '5':
  88. n = c-'0';
  89. break;
  90. }
  91. nr(L(".j"), n);
  92. }
  93. /* no adjust */
  94. void
  95. r_na(int argc, Rune **argv)
  96. {
  97. USED(argc);
  98. USED(argv);
  99. nr(L(".j"), getnr(L(".j"))&~1);
  100. }
  101. /* center next N lines */
  102. void
  103. r_ce(int argc, Rune **argv)
  104. {
  105. if(argc < 2)
  106. nr(L(".ce"), 1);
  107. else
  108. nr(L(".ce"), eval(argv[1]));
  109. /* XXX set trap */
  110. }
  111. void
  112. t4init(void)
  113. {
  114. nr(L(".fi"), 1);
  115. nr(L(".j"), 1);
  116. addreq(L("br"), r_br, 0);
  117. addreq(L("fi"), r_fi, 0);
  118. addreq(L("nf"), r_nf, 0);
  119. addreq(L("ad"), r_ad, -1);
  120. addreq(L("na"), r_na, 0);
  121. addreq(L("ce"), r_ce, -1);
  122. addesc(' ', e_space, 0);
  123. addesc('p', e_warn, 0);
  124. addesc('&', e_amp, 0);
  125. addesc('c', e_c, 0);
  126. }