diff options
Diffstat (limited to 'src/cmd/htmlroff/t1.c')
-rw-r--r-- | src/cmd/htmlroff/t1.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/cmd/htmlroff/t1.c b/src/cmd/htmlroff/t1.c new file mode 100644 index 00000000..8236694d --- /dev/null +++ b/src/cmd/htmlroff/t1.c @@ -0,0 +1,186 @@ +#include "a.h" + +/* + * Section 1 - General Explanation. + */ + +/* 1.3 - Numerical parameter input. */ +char *units = "icPmnpuvx"; +int +scale2units(char c) +{ + int x; + + switch(c){ + case 'i': /* inch */ + return UPI; + case 'c': /* centimeter */ + return 0.3937008 * UPI; + case 'P': /* pica = 1/6 inch */ + return UPI / 6; + case 'm': /* em = S points */ + return UPI / 72.0 * getnr(L(".s")); + case 'n': /* en = em/2 */ + return UPI / 72.0 * getnr(L(".s")) / 2; + case 'p': /* point = 1/72 inch */ + return UPI / 72; + case 'u': /* basic unit */ + return 1; + case 'v': /* vertical line space V */ + x = getnr(L(".v")); + if(x == 0) + x = 12 * UPI / 72; + return x; + case 'x': /* pixel (htmlroff addition) */ + return UPX; + default: + return 1; + } +} + +/* 1.4 - Numerical expressions. */ +int eval0(Rune**, int, int); +int +eval(Rune *s) +{ + return eval0(&s, 1, 1); +} +long +runestrtol(Rune *a, Rune **p) +{ + long n; + + n = 0; + while('0' <= *a && *a <= '9'){ + n = n*10 + *a-'0'; + a++; + } + *p = a; + return n; +} + +int +evalscale(Rune *s, int c) +{ + return eval0(&s, scale2units(c), 1); +} + +int +eval0(Rune **pline, int scale, int recur) +{ + Rune *p; + int neg; + double f, p10; + int x, y; + + neg = 0; + p = *pline; + while(*p == '-'){ + neg = 1 - neg; + p++; + } + if(*p == '('){ + p++; + x = eval0(&p, scale, 1); + if (*p != ')'){ + *pline = p; + return x; + } + p++; + }else{ + f = runestrtol(p, &p); + if(*p == '.'){ + p10 = 1.0; + p++; + while('0' <= *p && *p <= '9'){ + p10 /= 10; + f += p10*(*p++ - '0'); + } + } + if(*p && strchr(units, *p)){ + if(scale) + f *= scale2units(*p); + p++; + }else if(scale) + f *= scale; + x = f; + } + if(neg) + x = -x; + if(!recur){ + *pline = p; + return x; + } + + while(*p){ + switch(*p++) { + case '+': + x += eval0(&p, scale, 0); + continue; + case '-': + x -= eval0(&p, scale, 0); + continue; + case '*': + x *= eval0(&p, scale, 0); + continue; + case '/': + y = eval0(&p, scale, 0); + if (y == 0) { + fprint(2, "%L: divide by zero %S\n", p); + y = 1; + } + x /= y; + continue; + case '%': + y = eval0(&p, scale, 0); + if (!y) { + fprint(2, "%L: modulo by zero %S\n", p); + y = 1; + } + x %= y; + continue; + case '<': + if (*p == '=') { + p++; + x = x <= eval0(&p, scale, 0); + continue; + } + x = x < eval0(&p, scale, 0); + continue; + case '>': + if (*p == '=') { + p++; + x = x >= eval0(&p, scale, 0); + continue; + } + x = x > eval0(&p, scale, 0); + continue; + case '=': + if (*p == '=') + p++; + x = x == eval0(&p, scale, 0); + continue; + case '&': + x &= eval0(&p, scale, 0); + continue; + case ':': + x |= eval0(&p, scale, 0); + continue; + } + } + *pline = p; + return x; +} + +void +t1init(void) +{ + Tm tm; + + tm = *localtime(time(0)); + nr(L("dw"), tm.wday+1); + nr(L("dy"), tm.mday); + nr(L("mo"), tm.mon); + nr(L("yr"), tm.year%100); +} + |