| #include "e.h" |
| |
| #define abs(x) ((x) > 0 ? (x) : (-(x))) |
| |
| extern void brack(int, char *, char *, char *); |
| |
| void paren(int leftc, int p1, int rightc) |
| { |
| int n, m, j; |
| double h1, b1; |
| double v, bv; /* v = shift of inside, bv = shift of brackets */ |
| extern double Parenbase, Parenshift, Parenheight; |
| |
| bv = ttype == DEVPOST ? Parenshift : 0; /* move brackets down this much */ |
| h1 = eht[p1]; |
| b1 = ebase[p1]; |
| yyval = p1; |
| lfont[yyval] = rfont[yyval] = 0; |
| n = REL(h1,ps) + 0.99; /* ceiling */ |
| if (n < 2) |
| n = 1; |
| m = n - 2; |
| if (leftc == '{' || rightc == '}') { |
| n = n%2 ? n : n+1; |
| if (n < 3) |
| n = 3; |
| m = n-3; |
| } |
| eht[yyval] = EM((double) n + Parenheight, ps); |
| ebase[yyval] = eht[yyval]/2 - EM(Parenbase, ps); |
| |
| /* try to cope with things that are badly centered */ |
| /* (top heavy or bottom heavy) */ |
| if (abs(h1/2 - b1) >= EM(0.5, ps)) |
| v = REL(-ebase[yyval] + (eht[yyval]-h1)/2 + b1, ps); |
| else |
| v = 0; /* don't shift it at all */ |
| |
| printf(".ds %d \\^", (int)yyval); /* was \| */ |
| if (bv) |
| printf("\\v'%gm'", bv); |
| switch (leftc) { |
| case 'n': /* nothing */ |
| case '\0': |
| break; |
| case 'f': /* floor */ |
| if (n <= 1) |
| printf("\\(lf"); |
| else |
| brack(m, "\\(bv", "\\(bv", "\\(lf"); |
| break; |
| case 'c': /* ceiling */ |
| if (n <= 1) |
| printf("\\(lc"); |
| else |
| brack(m, "\\(lc", "\\(bv", "\\(bv"); |
| break; |
| case '{': |
| printf("\\b'\\(lt"); |
| for(j = 0; j < m; j += 2) printf("\\(bv"); |
| printf("\\(lk"); |
| for(j = 0; j < m; j += 2) printf("\\(bv"); |
| printf("\\(lb'"); |
| break; |
| case '(': |
| brack(m, "\\(lt", "\\(bv", "\\(lb"); |
| break; |
| case '[': |
| brack(m, "\\(lc", "\\(bv", "\\(lf"); |
| break; |
| case '|': |
| brack(m, "|", "|", "|"); |
| break; |
| default: |
| brack(m, (char *) &leftc, (char *) &leftc, (char *) &leftc); |
| break; |
| } |
| if (bv) |
| printf("\\v'%gm'", -bv); |
| if (v) |
| printf("\\v'%gm'\\*(%d\\v'%gm'", -v, p1, v); |
| else |
| printf("\\*(%d", p1); |
| if (rightc) { |
| if (bv) |
| printf("\\v'%gm'", bv); |
| switch (rightc) { |
| case 'f': /* floor */ |
| if (n <= 1) |
| printf("\\(rf"); |
| else |
| brack(m, "\\(bv", "\\(bv", "\\(rf"); |
| break; |
| case 'c': /* ceiling */ |
| if (n <= 1) |
| printf("\\(rc"); |
| else |
| brack(m, "\\(rc", "\\(bv", "\\(bv"); |
| break; |
| case '}': |
| printf("\\b'\\(rt"); |
| for(j = 0; j < m; j += 2) printf("\\(bv"); |
| printf("\\(rk"); |
| for(j = 0; j < m; j += 2) printf("\\(bv"); |
| printf("\\(rb'"); |
| break; |
| case ']': |
| brack(m, "\\(rc", "\\(bv", "\\(rf"); |
| break; |
| case ')': |
| brack(m, "\\(rt", "\\(bv", "\\(rb"); |
| break; |
| case '|': |
| brack(m, "|", "|", "|"); |
| break; |
| default: |
| brack(m, (char *) &rightc, (char *) &rightc, (char *) &rightc); |
| break; |
| } |
| if (bv) |
| printf("\\v'%gm'", -bv); |
| } |
| printf("\n"); |
| dprintf(".\tcurly: h=%g b=%g n=%d v=%g l=%c, r=%c\n", |
| eht[yyval], ebase[yyval], n, v, leftc, rightc); |
| } |
| |
| void brack(int m, char *t, char *c, char *b) |
| { |
| int j; |
| printf("\\b'%s", t); |
| for( j=0; j < m; j++) |
| printf("%s", c); |
| printf("%s'", b); |
| } |