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