plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }