| #include "a.h" |
| |
| /* |
| * Section 2 - Font and character size control. |
| */ |
| |
| /* 2.1 - Character set */ |
| /* XXX |
| * |
| * \C'name' - character named name |
| * \N'n' - character number |
| * \(xx - two-letter character |
| * \- |
| * \` |
| * \' |
| * ` |
| * ' |
| * - |
| */ |
| |
| Rune* |
| getqarg(void) |
| { |
| static Rune buf[MaxLine]; |
| int c; |
| Rune *p, *e; |
| |
| p = buf; |
| e = p+sizeof buf-1; |
| |
| if(getrune() != '\'') |
| return nil; |
| while(p < e){ |
| c = getrune(); |
| if(c < 0) |
| return nil; |
| if(c == '\'') |
| break; |
| *p++ = c; |
| } |
| *p = 0; |
| return buf; |
| } |
| |
| int |
| e_N(void) |
| { |
| Rune *a; |
| if((a = getqarg()) == nil) |
| goto error; |
| return eval(a); |
| |
| error: |
| warn("malformed %CN'...'", backslash); |
| return 0; |
| } |
| |
| int |
| e_paren(void) |
| { |
| int c, cc; |
| Rune buf[2], r; |
| |
| if((c = getrune()) < 0 || c == '\n') |
| goto error; |
| if((cc = getrune()) < 0 || cc == '\n') |
| goto error; |
| buf[0] = c; |
| buf[1] = cc; |
| r = troff2rune(buf); |
| if(r == Runeerror) |
| warn("unknown char %C(%C%C", backslash, c, cc); |
| return r; |
| |
| error: |
| warn("malformed %C(xx", backslash); |
| return 0; |
| } |
| |
| /* 2.2 - Fonts */ |
| Rune fonttab[10][100]; |
| |
| /* |
| * \fx \f(xx \fN - font change |
| * number register .f - current font |
| * \f0 previous font (undocumented?) |
| */ |
| /* change to font f. also \fx, \f(xx, \fN */ |
| /* .ft LongName is okay - temporarily at fp 0 */ |
| void |
| ft(Rune *f) |
| { |
| int i; |
| int fn; |
| |
| if(f && runestrcmp(f, L("P")) == 0) |
| f = nil; |
| if(f == nil) |
| fn = 0; |
| else if(isdigit(f[0])) |
| fn = eval(f); |
| else{ |
| for(i=0; i<nelem(fonttab); i++){ |
| if(runestrcmp(fonttab[i], f) == 0){ |
| fn = i; |
| goto have; |
| } |
| } |
| warn("unknown font %S", f); |
| fn = 1; |
| } |
| have: |
| if(fn < 0 || fn >= nelem(fonttab)){ |
| warn("unknown font %d", fn); |
| fn = 1; |
| } |
| if(fn == 0) |
| fn = getnr(L(".f0")); |
| nr(L(".f0"), getnr(L(".f"))); |
| nr(L(".f"), fn); |
| runmacro1(L("font")); |
| } |
| |
| /* mount font named f on physical position N */ |
| void |
| fp(int i, Rune *f) |
| { |
| if(i <= 0 || i >= nelem(fonttab)){ |
| warn("bad font position %d", i); |
| return; |
| } |
| runestrecpy(fonttab[i], fonttab[i]+sizeof fonttab[i], f); |
| } |
| |
| int |
| e_f(void) |
| { |
| ft(getname()); |
| return 0; |
| } |
| |
| void |
| r_ft(int argc, Rune **argv) |
| { |
| if(argc == 1) |
| ft(nil); |
| else |
| ft(argv[1]); |
| } |
| |
| void |
| r_fp(int argc, Rune **argv) |
| { |
| if(argc < 3){ |
| warn("missing arguments to %Cfp", dot); |
| return; |
| } |
| fp(eval(argv[1]), argv[2]); |
| } |
| |
| /* 2.3 - Character size */ |
| |
| /* \H'±N' sets height */ |
| |
| void |
| ps(int s) |
| { |
| if(s == 0) |
| s = getnr(L(".s0")); |
| nr(L(".s0"), getnr(L(".s"))); |
| nr(L(".s"), s); |
| runmacro1(L("font")); |
| } |
| |
| /* set point size */ |
| void |
| r_ps(int argc, Rune **argv) |
| { |
| Rune *p; |
| |
| if(argc == 1 || argv[1][0] == 0) |
| ps(0); |
| else{ |
| p = argv[1]; |
| if(p[0] == '-') |
| ps(getnr(L(".s"))-eval(p+1)); |
| else if(p[0] == '+') |
| ps(getnr(L(".s"))+eval(p+1)); |
| else |
| ps(eval(p)); |
| } |
| } |
| |
| int |
| e_s(void) |
| { |
| int c, cc, ccc, n, twodigit; |
| |
| c = getnext(); |
| if(c < 0) |
| return 0; |
| if(c == '+' || c == '-'){ |
| cc = getnext(); |
| if(cc == '('){ |
| cc = getnext(); |
| ccc = getnext(); |
| if(cc < '0' || cc > '9' || ccc < '0' || ccc > '9'){ |
| warn("bad size %Cs%C(%C%C", backslash, c, cc, ccc); |
| return 0; |
| } |
| n = (cc-'0')*10+ccc-'0'; |
| }else{ |
| if(cc < '0' || cc > '9'){ |
| warn("bad size %Cs%C%C", backslash, c, cc); |
| return 0; |
| } |
| n = cc-'0'; |
| } |
| if(c == '+') |
| ps(getnr(L(".s"))+n); |
| else |
| ps(getnr(L(".s"))-n); |
| return 0; |
| } |
| twodigit = 0; |
| if(c == '('){ |
| twodigit = 1; |
| c = getnext(); |
| if(c < 0) |
| return 0; |
| } |
| if(c < '0' || c > '9'){ |
| warn("bad size %Cs%C", backslash, c); |
| ungetnext(c); |
| return 0; |
| } |
| if(twodigit || (c < '4' && c != '0')){ |
| cc = getnext(); |
| if(c < 0) |
| return 0; |
| n = (c-'0')*10+cc-'0'; |
| }else |
| n = c-'0'; |
| ps(n); |
| return 0; |
| } |
| |
| void |
| t2init(void) |
| { |
| fp(1, L("R")); |
| fp(2, L("I")); |
| fp(3, L("B")); |
| fp(4, L("BI")); |
| fp(5, L("CW")); |
| |
| nr(L(".s"), 10); |
| nr(L(".s0"), 10); |
| |
| addreq(L("ft"), r_ft, -1); |
| addreq(L("fp"), r_fp, -1); |
| addreq(L("ps"), r_ps, -1); |
| addreq(L("ss"), r_warn, -1); |
| addreq(L("cs"), r_warn, -1); |
| addreq(L("bd"), r_warn, -1); |
| |
| addesc('f', e_f, 0); |
| addesc('s', e_s, 0); |
| addesc('(', e_paren, 0); /* ) */ |
| addesc('C', e_warn, 0); |
| addesc('N', e_N, 0); |
| /* \- \' \` are handled in html.c */ |
| } |
| |