aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/htmlroff/t1.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-02-21 18:37:05 +0000
committerrsc <devnull@localhost>2006-02-21 18:37:05 +0000
commitc42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4 (patch)
tree400f263e56681842ba1e6e1fdd8be453856474ef /src/cmd/htmlroff/t1.c
parent49a1496cbbb871bc623cfd0925566628e246c9ba (diff)
downloadplan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.tar.gz
plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.tar.bz2
plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.zip
add
Diffstat (limited to 'src/cmd/htmlroff/t1.c')
-rw-r--r--src/cmd/htmlroff/t1.c186
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);
+}
+