paren.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "e.h"
  2. #define abs(x) ((x) > 0 ? (x) : (-(x)))
  3. extern void brack(int, char *, char *, char *);
  4. void paren(int leftc, int p1, int rightc)
  5. {
  6. int n, m, j;
  7. double h1, b1;
  8. double v, bv; /* v = shift of inside, bv = shift of brackets */
  9. extern double Parenbase, Parenshift, Parenheight;
  10. bv = ttype == DEVPOST ? Parenshift : 0; /* move brackets down this much */
  11. h1 = eht[p1];
  12. b1 = ebase[p1];
  13. yyval = p1;
  14. lfont[yyval] = rfont[yyval] = 0;
  15. n = REL(h1,ps) + 0.99; /* ceiling */
  16. if (n < 2)
  17. n = 1;
  18. m = n - 2;
  19. if (leftc == '{' || rightc == '}') {
  20. n = n%2 ? n : ++n;
  21. if (n < 3)
  22. n = 3;
  23. m = n-3;
  24. }
  25. eht[yyval] = EM((double) n + Parenheight, ps);
  26. ebase[yyval] = eht[yyval]/2 - EM(Parenbase, ps);
  27. /* try to cope with things that are badly centered */
  28. /* (top heavy or bottom heavy) */
  29. if (abs(h1/2 - b1) >= EM(0.5, ps))
  30. v = REL(-ebase[yyval] + (eht[yyval]-h1)/2 + b1, ps);
  31. else
  32. v = 0; /* don't shift it at all */
  33. printf(".ds %d \\^", yyval); /* was \| */
  34. if (bv)
  35. printf("\\v'%gm'", bv);
  36. switch (leftc) {
  37. case 'n': /* nothing */
  38. case '\0':
  39. break;
  40. case 'f': /* floor */
  41. if (n <= 1)
  42. printf("\\(lf");
  43. else
  44. brack(m, "\\(bv", "\\(bv", "\\(lf");
  45. break;
  46. case 'c': /* ceiling */
  47. if (n <= 1)
  48. printf("\\(lc");
  49. else
  50. brack(m, "\\(lc", "\\(bv", "\\(bv");
  51. break;
  52. case '{':
  53. printf("\\b'\\(lt");
  54. for(j = 0; j < m; j += 2) printf("\\(bv");
  55. printf("\\(lk");
  56. for(j = 0; j < m; j += 2) printf("\\(bv");
  57. printf("\\(lb'");
  58. break;
  59. case '(':
  60. brack(m, "\\(lt", "\\(bv", "\\(lb");
  61. break;
  62. case '[':
  63. brack(m, "\\(lc", "\\(bv", "\\(lf");
  64. break;
  65. case '|':
  66. brack(m, "|", "|", "|");
  67. break;
  68. default:
  69. brack(m, (char *) &leftc, (char *) &leftc, (char *) &leftc);
  70. break;
  71. }
  72. if (bv)
  73. printf("\\v'%gm'", -bv);
  74. if (v)
  75. printf("\\v'%gm'\\*(%d\\v'%gm'", -v, p1, v);
  76. else
  77. printf("\\*(%d", p1);
  78. if (rightc) {
  79. if (bv)
  80. printf("\\v'%gm'", bv);
  81. switch (rightc) {
  82. case 'f': /* floor */
  83. if (n <= 1)
  84. printf("\\(rf");
  85. else
  86. brack(m, "\\(bv", "\\(bv", "\\(rf");
  87. break;
  88. case 'c': /* ceiling */
  89. if (n <= 1)
  90. printf("\\(rc");
  91. else
  92. brack(m, "\\(rc", "\\(bv", "\\(bv");
  93. break;
  94. case '}':
  95. printf("\\b'\\(rt");
  96. for(j = 0; j < m; j += 2) printf("\\(bv");
  97. printf("\\(rk");
  98. for(j = 0; j < m; j += 2) printf("\\(bv");
  99. printf("\\(rb'");
  100. break;
  101. case ']':
  102. brack(m, "\\(rc", "\\(bv", "\\(rf");
  103. break;
  104. case ')':
  105. brack(m, "\\(rt", "\\(bv", "\\(rb");
  106. break;
  107. case '|':
  108. brack(m, "|", "|", "|");
  109. break;
  110. default:
  111. brack(m, (char *) &rightc, (char *) &rightc, (char *) &rightc);
  112. break;
  113. }
  114. if (bv)
  115. printf("\\v'%gm'", -bv);
  116. }
  117. printf("\n");
  118. dprintf(".\tcurly: h=%g b=%g n=%d v=%g l=%c, r=%c\n",
  119. eht[yyval], ebase[yyval], n, v, leftc, rightc);
  120. }
  121. void brack(int m, char *t, char *c, char *b)
  122. {
  123. int j;
  124. printf("\\b'%s", t);
  125. for( j=0; j < m; j++)
  126. printf("%s", c);
  127. printf("%s'", b);
  128. }