Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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