diff options
Diffstat (limited to 'src/cmd/eqn/paren.c')
-rw-r--r-- | src/cmd/eqn/paren.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/cmd/eqn/paren.c b/src/cmd/eqn/paren.c new file mode 100644 index 00000000..bb019bf7 --- /dev/null +++ b/src/cmd/eqn/paren.c @@ -0,0 +1,135 @@ +#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; + 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 \\^", 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); +} |