Blob


1 #include "a.h"
3 /*
4 * Section 2 - Font and character size control.
5 */
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 */
21 Rune*
22 getqarg(void)
23 {
24 static Rune buf[MaxLine];
25 int c;
26 Rune *p, *e;
28 p = buf;
29 e = p+sizeof buf-1;
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 }
45 int
46 e_N(void)
47 {
48 Rune *a;
49 if((a = getqarg()) == nil)
50 goto error;
51 return eval(a);
53 error:
54 warn("malformed %CN'...'", backslash);
55 return 0;
56 }
58 int
59 e_paren(void)
60 {
61 int c, cc;
62 Rune buf[2], r;
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;
75 error:
76 warn("malformed %C(xx", backslash);
77 return 0;
78 }
80 /* 2.2 - Fonts */
81 Rune fonttab[10][100];
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;
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;
109 warn("unknown font %S", f);
110 fn = 1;
112 have:
113 if(fn < 0 || fn >= nelem(fonttab)){
114 warn("unknown font %d", fn);
115 fn = 1;
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"));
124 /* mount font named f on physical position N */
125 void
126 fp(int i, Rune *f)
128 if(i <= 0 || i >= nelem(fonttab)){
129 warn("bad font position %d", i);
130 return;
132 runestrecpy(fonttab[i], fonttab[i]+sizeof fonttab[i], f);
135 int
136 e_f(void)
138 ft(getname());
139 return 0;
142 void
143 r_ft(int argc, Rune **argv)
145 if(argc == 1)
146 ft(nil);
147 else
148 ft(argv[1]);
151 void
152 r_fp(int argc, Rune **argv)
154 if(argc < 3){
155 warn("missing arguments to %Cfp", dot);
156 return;
158 fp(eval(argv[1]), argv[2]);
161 /* 2.3 - Character size */
163 /* \H'±N' sets height */
165 void
166 ps(int s)
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"));
175 /* set point size */
176 void
177 r_ps(int argc, Rune **argv)
179 Rune *p;
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));
194 int
195 e_s(void)
197 int c, cc, ccc, n, twodigit;
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;
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;
217 n = cc-'0';
219 if(c == '+')
220 ps(getnr(L(".s"))+n);
221 else
222 ps(getnr(L(".s"))-n);
223 return 0;
225 twodigit = 0;
226 if(c == '('){
227 twodigit = 1;
228 c = getnext();
229 if(c < 0)
230 return 0;
232 if(c < '0' || c > '9'){
233 warn("bad size %Cs%C", backslash, c);
234 ungetnext(c);
235 return 0;
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;
248 void
249 t2init(void)
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"));
257 nr(L(".s"), 10);
258 nr(L(".s0"), 10);
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);
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 */