URI:
       tt2.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tt2.c (4071B)
       ---
            1 #include "a.h"
            2 
            3 /*
            4  * Section 2 - Font and character size control.
            5  */
            6 
            7 /* 2.1 - Character set */
            8 /* XXX
            9  *
           10  * \C'name' - character named name
           11  * \N'n' - character number
           12  * \(xx - two-letter character
           13  * \-
           14  * \`
           15  * \'
           16  * `
           17  * '
           18  * -
           19  */
           20 
           21 Rune*
           22 getqarg(void)
           23 {
           24         static Rune buf[MaxLine];
           25         int c;
           26         Rune *p, *e;
           27 
           28         p = buf;
           29         e = p + nelem(buf) - 1;
           30 
           31         if(getrune() != '\'')
           32                 return nil;
           33         while(p < e){
           34                 c = getrune();
           35                 if(c < 0)
           36                         return nil;
           37                 if(c == '\'')
           38                         break;
           39                 *p++ = c;
           40         }
           41         *p = 0;
           42         return buf;
           43 }
           44 
           45 int
           46 e_N(void)
           47 {
           48         Rune *a;
           49         if((a = getqarg()) == nil)
           50                 goto error;
           51         return eval(a);
           52 
           53 error:
           54         warn("malformed %CN'...'", backslash);
           55         return 0;
           56 }
           57 
           58 int
           59 e_paren(void)
           60 {
           61         int c, cc;
           62         Rune buf[2], r;
           63 
           64         if((c = getrune()) < 0 || c == '\n')
           65                 goto error;
           66         if((cc = getrune()) < 0 || cc == '\n')
           67                 goto error;
           68         buf[0] = c;
           69         buf[1] = cc;
           70         r = troff2rune(buf);
           71          if(r == Runeerror)
           72                 warn("unknown char %C(%C%C", backslash, c, cc);
           73         return r;
           74 
           75 error:
           76         warn("malformed %C(xx", backslash);
           77         return 0;
           78 }
           79 
           80 /* 2.2 - Fonts */
           81 Rune fonttab[10][100];
           82 
           83 /*
           84  * \fx \f(xx \fN - font change
           85  * number register .f - current font
           86  * \f0 previous font (undocumented?)
           87  */
           88 /* change to font f.  also \fx, \f(xx, \fN */
           89 /* .ft LongName is okay - temporarily at fp 0 */
           90 void
           91 ft(Rune *f)
           92 {
           93         int i;
           94         int fn;
           95 
           96         if(f && runestrcmp(f, L("P")) == 0)
           97                 f = nil;
           98         if(f == nil)
           99                 fn = 0;
          100         else if(isdigit(f[0]))
          101                 fn = eval(f);
          102         else{
          103                 for(i=0; i<nelem(fonttab); i++){
          104                         if(runestrcmp(fonttab[i], f) == 0){
          105                                 fn = i;
          106                                 goto have;
          107                         }
          108                 }
          109                 warn("unknown font %S", f);
          110                 fn = 1;
          111         }
          112 have:
          113         if(fn < 0 || fn >= nelem(fonttab)){
          114                 warn("unknown font %d", fn);
          115                 fn = 1;
          116         }
          117         if(fn == 0)
          118                 fn = getnr(L(".f0"));
          119         nr(L(".f0"), getnr(L(".f")));
          120         nr(L(".f"), fn);
          121         runmacro1(L("font"));
          122 }
          123 
          124 /* mount font named f on physical position N */
          125 void
          126 fp(int i, Rune *f)
          127 {
          128         if(i <= 0 || i >= nelem(fonttab)){
          129                 warn("bad font position %d", i);
          130                 return;
          131         }
          132         runestrecpy(fonttab[i], fonttab[i]+sizeof fonttab[i], f);
          133 }
          134 
          135 int
          136 e_f(void)
          137 {
          138         ft(getname());
          139         return 0;
          140 }
          141 
          142 void
          143 r_ft(int argc, Rune **argv)
          144 {
          145         if(argc == 1)
          146                 ft(nil);
          147         else
          148                 ft(argv[1]);
          149 }
          150 
          151 void
          152 r_fp(int argc, Rune **argv)
          153 {
          154         if(argc < 3){
          155                 warn("missing arguments to %Cfp", dot);
          156                 return;
          157         }
          158         fp(eval(argv[1]), argv[2]);
          159 }
          160 
          161 /* 2.3 - Character size */
          162 
          163 /* \H'±N' sets height */
          164 
          165 void
          166 ps(int s)
          167 {
          168         if(s == 0)
          169                 s = getnr(L(".s0"));
          170         nr(L(".s0"), getnr(L(".s")));
          171         nr(L(".s"), s);
          172         runmacro1(L("font"));
          173 }
          174 
          175 /* set point size */
          176 void
          177 r_ps(int argc, Rune **argv)
          178 {
          179         Rune *p;
          180 
          181         if(argc == 1 || argv[1][0] == 0)
          182                 ps(0);
          183         else{
          184                 p = argv[1];
          185                 if(p[0] == '-')
          186                         ps(getnr(L(".s"))-eval(p+1));
          187                 else if(p[0] == '+')
          188                         ps(getnr(L(".s"))+eval(p+1));
          189                 else
          190                         ps(eval(p));
          191         }
          192 }
          193 
          194 int
          195 e_s(void)
          196 {
          197         int c, cc, ccc, n, twodigit;
          198 
          199         c = getnext();
          200         if(c < 0)
          201                 return 0;
          202         if(c == '+' || c == '-'){
          203                 cc = getnext();
          204                 if(cc == '('){
          205                         cc = getnext();
          206                         ccc = getnext();
          207                         if(cc < '0' || cc > '9' || ccc < '0' || ccc > '9'){
          208                                 warn("bad size %Cs%C(%C%C", backslash, c, cc, ccc);
          209                                 return 0;
          210                         }
          211                         n = (cc-'0')*10+ccc-'0';
          212                 }else{
          213                         if(cc < '0' || cc > '9'){
          214                                 warn("bad size %Cs%C%C", backslash, c, cc);
          215                                 return 0;
          216                         }
          217                         n = cc-'0';
          218                 }
          219                 if(c == '+')
          220                         ps(getnr(L(".s"))+n);
          221                 else
          222                         ps(getnr(L(".s"))-n);
          223                 return 0;
          224         }
          225         twodigit = 0;
          226         if(c == '('){
          227                 twodigit = 1;
          228                 c = getnext();
          229                 if(c < 0)
          230                         return 0;
          231         }
          232         if(c < '0' || c > '9'){
          233                 warn("bad size %Cs%C", backslash, c);
          234                 ungetnext(c);
          235                 return 0;
          236         }
          237         if(twodigit || (c < '4' && c != '0')){
          238                 cc = getnext();
          239                 if(c < 0)
          240                         return 0;
          241                 n = (c-'0')*10+cc-'0';
          242         }else
          243                 n = c-'0';
          244         ps(n);
          245         return 0;
          246 }
          247 
          248 void
          249 t2init(void)
          250 {
          251         fp(1, L("R"));
          252         fp(2, L("I"));
          253         fp(3, L("B"));
          254         fp(4, L("BI"));
          255         fp(5, L("CW"));
          256 
          257         nr(L(".s"), 10);
          258         nr(L(".s0"), 10);
          259 
          260         addreq(L("ft"), r_ft, -1);
          261         addreq(L("fp"), r_fp, -1);
          262         addreq(L("ps"), r_ps, -1);
          263         addreq(L("ss"), r_warn, -1);
          264         addreq(L("cs"), r_warn, -1);
          265         addreq(L("bd"), r_warn, -1);
          266 
          267         addesc('f', e_f, 0);
          268         addesc('s', e_s, 0);
          269         addesc('(', e_paren, 0);        /* ) */
          270         addesc('C', e_warn, 0);
          271         addesc('N', e_N, 0);
          272         /* \- \' \` are handled in html.c */
          273 }