]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/eqn/paren.c
ndb/dns: remove single-ip-address assuptions
[plan9front.git] / sys / src / cmd / eqn / paren.c
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;
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 \\^", 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 }