]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/htmlroff/t2.c
ndb/dns: remove single-ip-address assuptions
[plan9front.git] / sys / src / cmd / htmlroff / t2.c
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+sizeof 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 }
274