Blame


1 357621cd 2005-01-13 devnull #include <u.h>
2 357621cd 2005-01-13 devnull #include <libc.h>
3 357621cd 2005-01-13 devnull #include <bio.h>
4 78e51a8c 2005-01-14 devnull #include <ctype.h>
5 357621cd 2005-01-13 devnull
6 357621cd 2005-01-13 devnull enum{
7 357621cd 2005-01-13 devnull Nfont = 11,
8 cbeb0b26 2006-04-01 devnull Wid = 20 /* tmac.anhtml sets page width to 20" so we can recognize .nf text */
9 357621cd 2005-01-13 devnull };
10 357621cd 2005-01-13 devnull
11 357621cd 2005-01-13 devnull typedef ulong Char;
12 357621cd 2005-01-13 devnull typedef struct Troffchar Troffchar;
13 357621cd 2005-01-13 devnull typedef struct Htmlchar Htmlchar;
14 357621cd 2005-01-13 devnull typedef struct Font Font;
15 357621cd 2005-01-13 devnull typedef struct HTMLfont HTMLfont;
16 357621cd 2005-01-13 devnull
17 357621cd 2005-01-13 devnull /* a Char is 32 bits. low 16 bits are the rune. higher are attributes */
18 357621cd 2005-01-13 devnull enum
19 357621cd 2005-01-13 devnull {
20 357621cd 2005-01-13 devnull Italic = 16,
21 357621cd 2005-01-13 devnull Bold,
22 357621cd 2005-01-13 devnull CW,
23 357621cd 2005-01-13 devnull Indent1,
24 357621cd 2005-01-13 devnull Indent2,
25 357621cd 2005-01-13 devnull Indent3,
26 357621cd 2005-01-13 devnull Heading = 25,
27 cbeb0b26 2006-04-01 devnull Anchor = 26 /* must be last */
28 357621cd 2005-01-13 devnull };
29 357621cd 2005-01-13 devnull
30 357621cd 2005-01-13 devnull enum /* magic emissions */
31 357621cd 2005-01-13 devnull {
32 357621cd 2005-01-13 devnull Estring = 0,
33 cbeb0b26 2006-04-01 devnull Epp = 1<<16
34 357621cd 2005-01-13 devnull };
35 357621cd 2005-01-13 devnull
36 357621cd 2005-01-13 devnull int attrorder[] = { Indent1, Indent2, Indent3, Heading, Anchor, Italic, Bold, CW };
37 357621cd 2005-01-13 devnull
38 357621cd 2005-01-13 devnull int nest[10];
39 357621cd 2005-01-13 devnull int nnest;
40 357621cd 2005-01-13 devnull
41 357621cd 2005-01-13 devnull struct Troffchar
42 357621cd 2005-01-13 devnull {
43 357621cd 2005-01-13 devnull char *name;
44 357621cd 2005-01-13 devnull char *value;
45 357621cd 2005-01-13 devnull };
46 357621cd 2005-01-13 devnull
47 357621cd 2005-01-13 devnull struct Htmlchar
48 357621cd 2005-01-13 devnull {
49 357621cd 2005-01-13 devnull char *utf;
50 357621cd 2005-01-13 devnull char *name;
51 357621cd 2005-01-13 devnull int value;
52 357621cd 2005-01-13 devnull };
53 357621cd 2005-01-13 devnull
54 357621cd 2005-01-13 devnull #include "chars.h"
55 357621cd 2005-01-13 devnull
56 357621cd 2005-01-13 devnull struct Font{
57 357621cd 2005-01-13 devnull char *name;
58 357621cd 2005-01-13 devnull HTMLfont *htmlfont;
59 357621cd 2005-01-13 devnull };
60 357621cd 2005-01-13 devnull
61 357621cd 2005-01-13 devnull struct HTMLfont{
62 357621cd 2005-01-13 devnull char *name;
63 357621cd 2005-01-13 devnull char *htmlname;
64 357621cd 2005-01-13 devnull int bit;
65 357621cd 2005-01-13 devnull };
66 357621cd 2005-01-13 devnull
67 357621cd 2005-01-13 devnull /* R must be first; it's the default representation for fonts we don't recognize */
68 357621cd 2005-01-13 devnull HTMLfont htmlfonts[] =
69 357621cd 2005-01-13 devnull {
70 357621cd 2005-01-13 devnull "R", nil, 0,
71 4590ad02 2006-03-19 devnull "LuxiSans", nil, 0,
72 357621cd 2005-01-13 devnull "I", "i", Italic,
73 4590ad02 2006-03-19 devnull "LuxiSans-Oblique", "i", Italic,
74 357621cd 2005-01-13 devnull "CW", "tt", CW,
75 4590ad02 2006-03-19 devnull "LuxiMono", "tt", CW,
76 cbeb0b26 2006-04-01 devnull nil, nil
77 357621cd 2005-01-13 devnull };
78 357621cd 2005-01-13 devnull
79 357621cd 2005-01-13 devnull #define TABLE "<table border=0 cellpadding=0 cellspacing=0>"
80 357621cd 2005-01-13 devnull
81 357621cd 2005-01-13 devnull char*
82 357621cd 2005-01-13 devnull onattr[8*sizeof(ulong)] =
83 357621cd 2005-01-13 devnull {
84 357621cd 2005-01-13 devnull 0, 0, 0, 0, 0, 0, 0, 0,
85 357621cd 2005-01-13 devnull 0, 0, 0, 0, 0, 0, 0, 0,
86 357621cd 2005-01-13 devnull "<i>", /* italic */
87 357621cd 2005-01-13 devnull "<b>", /* bold */
88 357621cd 2005-01-13 devnull "<tt><font size=+1>", /* cw */
89 357621cd 2005-01-13 devnull "<+table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>\n", /* indent1 */
90 357621cd 2005-01-13 devnull "<+table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>\n", /* indent2 */
91 357621cd 2005-01-13 devnull "<+table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>\n", /* indent3 */
92 357621cd 2005-01-13 devnull 0,
93 357621cd 2005-01-13 devnull 0,
94 357621cd 2005-01-13 devnull 0,
95 357621cd 2005-01-13 devnull "<p><font size=+1><b>", /* heading 25 */
96 357621cd 2005-01-13 devnull "<unused>", /* anchor 26 */
97 357621cd 2005-01-13 devnull };
98 357621cd 2005-01-13 devnull
99 357621cd 2005-01-13 devnull char*
100 357621cd 2005-01-13 devnull offattr[8*sizeof(ulong)] =
101 357621cd 2005-01-13 devnull {
102 357621cd 2005-01-13 devnull 0, 0, 0, 0, 0, 0, 0, 0,
103 357621cd 2005-01-13 devnull 0, 0, 0, 0, 0, 0, 0, 0,
104 357621cd 2005-01-13 devnull "</i>", /* italic */
105 357621cd 2005-01-13 devnull "</b>", /* bold */
106 357621cd 2005-01-13 devnull "</font></tt>", /* cw */
107 357621cd 2005-01-13 devnull "<-/table>", /* indent1 */
108 357621cd 2005-01-13 devnull "<-/table>", /* indent2 */
109 357621cd 2005-01-13 devnull "<-/table>", /* indent3 */
110 357621cd 2005-01-13 devnull 0,
111 357621cd 2005-01-13 devnull 0,
112 357621cd 2005-01-13 devnull 0,
113 357621cd 2005-01-13 devnull "</b></font>", /* heading 25 */
114 357621cd 2005-01-13 devnull "</a>", /* anchor 26 */
115 357621cd 2005-01-13 devnull };
116 357621cd 2005-01-13 devnull
117 357621cd 2005-01-13 devnull Font *font[Nfont];
118 357621cd 2005-01-13 devnull
119 357621cd 2005-01-13 devnull Biobuf bout;
120 357621cd 2005-01-13 devnull int debug = 0;
121 357621cd 2005-01-13 devnull
122 357621cd 2005-01-13 devnull /* troff state */
123 357621cd 2005-01-13 devnull int page = 1;
124 357621cd 2005-01-13 devnull int ft = 1;
125 357621cd 2005-01-13 devnull int vp = 0;
126 357621cd 2005-01-13 devnull int hp = 0;
127 357621cd 2005-01-13 devnull int ps = 1;
128 357621cd 2005-01-13 devnull int res = 720;
129 357621cd 2005-01-13 devnull
130 357621cd 2005-01-13 devnull int didP = 0;
131 357621cd 2005-01-13 devnull int atnewline = 1;
132 357621cd 2005-01-13 devnull int prevlineH = 0;
133 357621cd 2005-01-13 devnull ulong attr = 0; /* or'ed into each Char */
134 357621cd 2005-01-13 devnull
135 357621cd 2005-01-13 devnull Char *chars;
136 357621cd 2005-01-13 devnull int nchars;
137 357621cd 2005-01-13 devnull int nalloc;
138 357621cd 2005-01-13 devnull char** anchors; /* allocated in order */
139 357621cd 2005-01-13 devnull int nanchors;
140 357621cd 2005-01-13 devnull
141 357621cd 2005-01-13 devnull char *pagename;
142 357621cd 2005-01-13 devnull char *section;
143 357621cd 2005-01-13 devnull
144 357621cd 2005-01-13 devnull char *filename;
145 357621cd 2005-01-13 devnull int cno;
146 357621cd 2005-01-13 devnull char buf[8192];
147 357621cd 2005-01-13 devnull char *title = "Plan 9 man page";
148 357621cd 2005-01-13 devnull
149 357621cd 2005-01-13 devnull void process(Biobuf*, char*);
150 357621cd 2005-01-13 devnull void mountfont(int, char*);
151 357621cd 2005-01-13 devnull void switchfont(int);
152 357621cd 2005-01-13 devnull void header(char*);
153 357621cd 2005-01-13 devnull void flush(void);
154 357621cd 2005-01-13 devnull void trailer(void);
155 357621cd 2005-01-13 devnull
156 357621cd 2005-01-13 devnull void*
157 357621cd 2005-01-13 devnull emalloc(ulong n)
158 357621cd 2005-01-13 devnull {
159 357621cd 2005-01-13 devnull void *p;
160 357621cd 2005-01-13 devnull
161 357621cd 2005-01-13 devnull p = malloc(n);
162 357621cd 2005-01-13 devnull if(p == nil)
163 357621cd 2005-01-13 devnull sysfatal("malloc failed: %r");
164 357621cd 2005-01-13 devnull return p;
165 357621cd 2005-01-13 devnull }
166 357621cd 2005-01-13 devnull
167 357621cd 2005-01-13 devnull void*
168 357621cd 2005-01-13 devnull erealloc(void *p, ulong n)
169 357621cd 2005-01-13 devnull {
170 357621cd 2005-01-13 devnull
171 357621cd 2005-01-13 devnull p = realloc(p, n);
172 357621cd 2005-01-13 devnull if(p == nil)
173 357621cd 2005-01-13 devnull sysfatal("realloc failed: %r");
174 357621cd 2005-01-13 devnull return p;
175 357621cd 2005-01-13 devnull }
176 357621cd 2005-01-13 devnull
177 357621cd 2005-01-13 devnull char*
178 357621cd 2005-01-13 devnull estrdup(char *s)
179 357621cd 2005-01-13 devnull {
180 357621cd 2005-01-13 devnull char *t;
181 357621cd 2005-01-13 devnull
182 357621cd 2005-01-13 devnull t = strdup(s);
183 357621cd 2005-01-13 devnull if(t == nil)
184 357621cd 2005-01-13 devnull sysfatal("strdup failed: %r");
185 357621cd 2005-01-13 devnull return t;
186 357621cd 2005-01-13 devnull }
187 357621cd 2005-01-13 devnull
188 357621cd 2005-01-13 devnull void
189 357621cd 2005-01-13 devnull usage(void)
190 357621cd 2005-01-13 devnull {
191 357621cd 2005-01-13 devnull fprint(2, "usage: troff2html [-d] [-t title] [file ...]\n");
192 357621cd 2005-01-13 devnull exits("usage");
193 357621cd 2005-01-13 devnull }
194 357621cd 2005-01-13 devnull
195 357621cd 2005-01-13 devnull int
196 357621cd 2005-01-13 devnull hccmp(const void *va, const void *vb)
197 357621cd 2005-01-13 devnull {
198 357621cd 2005-01-13 devnull Htmlchar *a, *b;
199 357621cd 2005-01-13 devnull
200 357621cd 2005-01-13 devnull a = (Htmlchar*)va;
201 357621cd 2005-01-13 devnull b = (Htmlchar*)vb;
202 357621cd 2005-01-13 devnull return a->value - b->value;
203 357621cd 2005-01-13 devnull }
204 357621cd 2005-01-13 devnull
205 357621cd 2005-01-13 devnull void
206 357621cd 2005-01-13 devnull main(int argc, char *argv[])
207 357621cd 2005-01-13 devnull {
208 357621cd 2005-01-13 devnull int i;
209 357621cd 2005-01-13 devnull Biobuf in, *inp;
210 357621cd 2005-01-13 devnull Rune r;
211 357621cd 2005-01-13 devnull
212 357621cd 2005-01-13 devnull for(i=0; i<nelem(htmlchars); i++){
213 357621cd 2005-01-13 devnull chartorune(&r, htmlchars[i].utf);
214 357621cd 2005-01-13 devnull htmlchars[i].value = r;
215 357621cd 2005-01-13 devnull }
216 357621cd 2005-01-13 devnull qsort(htmlchars, nelem(htmlchars), sizeof(htmlchars[0]), hccmp);
217 357621cd 2005-01-13 devnull
218 357621cd 2005-01-13 devnull ARGBEGIN{
219 357621cd 2005-01-13 devnull case 't':
220 357621cd 2005-01-13 devnull title = ARGF();
221 357621cd 2005-01-13 devnull if(title == nil)
222 357621cd 2005-01-13 devnull usage();
223 357621cd 2005-01-13 devnull break;
224 357621cd 2005-01-13 devnull case 'd':
225 357621cd 2005-01-13 devnull debug++;
226 357621cd 2005-01-13 devnull break;
227 357621cd 2005-01-13 devnull default:
228 357621cd 2005-01-13 devnull usage();
229 357621cd 2005-01-13 devnull }ARGEND
230 357621cd 2005-01-13 devnull
231 357621cd 2005-01-13 devnull Binit(&bout, 1, OWRITE);
232 357621cd 2005-01-13 devnull if(argc == 0){
233 357621cd 2005-01-13 devnull Binit(&in, 0, OREAD);
234 357621cd 2005-01-13 devnull process(&in, "<stdin>");
235 357621cd 2005-01-13 devnull }else{
236 357621cd 2005-01-13 devnull for(i=0; i<argc; i++){
237 357621cd 2005-01-13 devnull inp = Bopen(argv[i], OREAD);
238 357621cd 2005-01-13 devnull if(inp == nil)
239 357621cd 2005-01-13 devnull sysfatal("can't open %s: %r", argv[i]);
240 357621cd 2005-01-13 devnull process(inp, argv[i]);
241 357621cd 2005-01-13 devnull Bterm(inp);
242 357621cd 2005-01-13 devnull }
243 357621cd 2005-01-13 devnull }
244 357621cd 2005-01-13 devnull header(title);
245 357621cd 2005-01-13 devnull flush();
246 357621cd 2005-01-13 devnull trailer();
247 357621cd 2005-01-13 devnull exits(nil);
248 357621cd 2005-01-13 devnull }
249 357621cd 2005-01-13 devnull
250 357621cd 2005-01-13 devnull void
251 357621cd 2005-01-13 devnull emitul(ulong ul, int special)
252 357621cd 2005-01-13 devnull {
253 357621cd 2005-01-13 devnull ulong a, c;
254 357621cd 2005-01-13 devnull
255 357621cd 2005-01-13 devnull if(nalloc == nchars){
256 357621cd 2005-01-13 devnull nalloc += 10000;
257 357621cd 2005-01-13 devnull chars = realloc(chars, nalloc*sizeof(chars[0]));
258 357621cd 2005-01-13 devnull if(chars == nil)
259 357621cd 2005-01-13 devnull sysfatal("malloc failed: %r");
260 357621cd 2005-01-13 devnull }
261 357621cd 2005-01-13 devnull
262 357621cd 2005-01-13 devnull if(!special){
263 357621cd 2005-01-13 devnull a = ul&~0xFFFF;
264 357621cd 2005-01-13 devnull c = ul&0xFFFF;
265 357621cd 2005-01-13 devnull /*
266 357621cd 2005-01-13 devnull * Attr-specific transformations.
267 357621cd 2005-01-13 devnull */
268 357621cd 2005-01-13 devnull if((a&(1<<CW)) && c=='-')
269 357621cd 2005-01-13 devnull c = 0x2212;
270 357621cd 2005-01-13 devnull if(!(a&(1<<CW))){
271 357621cd 2005-01-13 devnull if(c == '`')
272 357621cd 2005-01-13 devnull c = 0x2018;
273 357621cd 2005-01-13 devnull if(c == '\'')
274 357621cd 2005-01-13 devnull c = 0x2019;
275 357621cd 2005-01-13 devnull }
276 357621cd 2005-01-13 devnull ul = a|c;
277 357621cd 2005-01-13 devnull
278 357621cd 2005-01-13 devnull /*
279 357621cd 2005-01-13 devnull * Turn single quotes into double quotes.
280 357621cd 2005-01-13 devnull */
281 357621cd 2005-01-13 devnull if(nchars > 0){
282 357621cd 2005-01-13 devnull if(c == 0x2018 && (chars[nchars-1]&0xFFFF) == 0x2018
283 357621cd 2005-01-13 devnull && a==(chars[nchars-1]&~0xFFFF)){
284 357621cd 2005-01-13 devnull chars[nchars-1] = (ul&~0xFFFF) | 0x201C;
285 357621cd 2005-01-13 devnull return;
286 357621cd 2005-01-13 devnull }
287 357621cd 2005-01-13 devnull if(c == 0x2019 && (chars[nchars-1]&0xFFFF) == 0x2019
288 357621cd 2005-01-13 devnull && a==(chars[nchars-1]&~0xFFFF)){
289 357621cd 2005-01-13 devnull chars[nchars-1] = (ul&~0xFFFF) | 0x201D;
290 357621cd 2005-01-13 devnull return;
291 357621cd 2005-01-13 devnull }
292 357621cd 2005-01-13 devnull }
293 357621cd 2005-01-13 devnull }
294 357621cd 2005-01-13 devnull chars[nchars++] = ul;
295 357621cd 2005-01-13 devnull }
296 357621cd 2005-01-13 devnull
297 357621cd 2005-01-13 devnull void
298 357621cd 2005-01-13 devnull emit(Rune r)
299 357621cd 2005-01-13 devnull {
300 357621cd 2005-01-13 devnull emitul(r | attr, 0);
301 357621cd 2005-01-13 devnull /*
302 357621cd 2005-01-13 devnull * Close man page references early, so that
303 357621cd 2005-01-13 devnull * .IR proof (1),
304 357621cd 2005-01-13 devnull * doesn't make the comma part of the link.
305 357621cd 2005-01-13 devnull */
306 357621cd 2005-01-13 devnull if(r == ')')
307 357621cd 2005-01-13 devnull attr &= ~(1<<Anchor);
308 357621cd 2005-01-13 devnull }
309 357621cd 2005-01-13 devnull
310 357621cd 2005-01-13 devnull void
311 357621cd 2005-01-13 devnull emitstr(char *s)
312 357621cd 2005-01-13 devnull {
313 357621cd 2005-01-13 devnull emitul(Estring | attr, 0);
314 357621cd 2005-01-13 devnull emitul((ulong)s, 1);
315 357621cd 2005-01-13 devnull }
316 357621cd 2005-01-13 devnull
317 357621cd 2005-01-13 devnull int indentlevel;
318 357621cd 2005-01-13 devnull int linelen;
319 357621cd 2005-01-13 devnull
320 357621cd 2005-01-13 devnull void
321 357621cd 2005-01-13 devnull iputrune(Biobuf *b, Rune r)
322 357621cd 2005-01-13 devnull {
323 357621cd 2005-01-13 devnull int i;
324 357621cd 2005-01-13 devnull
325 357621cd 2005-01-13 devnull if(linelen++ > 60 && r == ' ')
326 357621cd 2005-01-13 devnull r = '\n';
327 357621cd 2005-01-13 devnull if(r >= 0x80)
328 357621cd 2005-01-13 devnull Bprint(b, "&#%d;", r);
329 357621cd 2005-01-13 devnull else
330 357621cd 2005-01-13 devnull Bputrune(b, r);
331 357621cd 2005-01-13 devnull if(r == '\n'){
332 357621cd 2005-01-13 devnull for(i=0; i<indentlevel; i++)
333 357621cd 2005-01-13 devnull Bprint(b, " ");
334 357621cd 2005-01-13 devnull linelen = 0;
335 357621cd 2005-01-13 devnull }
336 357621cd 2005-01-13 devnull }
337 357621cd 2005-01-13 devnull
338 357621cd 2005-01-13 devnull void
339 357621cd 2005-01-13 devnull iputs(Biobuf *b, char *s)
340 357621cd 2005-01-13 devnull {
341 357621cd 2005-01-13 devnull if(s[0]=='<' && s[1]=='+'){
342 357621cd 2005-01-13 devnull iputrune(b, '\n');
343 357621cd 2005-01-13 devnull Bprint(b, "<%s", s+2);
344 357621cd 2005-01-13 devnull indentlevel++;
345 357621cd 2005-01-13 devnull iputrune(b, '\n');
346 357621cd 2005-01-13 devnull }else if(s[0]=='<' && s[1]=='-'){
347 357621cd 2005-01-13 devnull indentlevel--;
348 357621cd 2005-01-13 devnull iputrune(b, '\n');
349 357621cd 2005-01-13 devnull Bprint(b, "<%s", s+2);
350 357621cd 2005-01-13 devnull iputrune(b, '\n');
351 357621cd 2005-01-13 devnull }else
352 357621cd 2005-01-13 devnull Bprint(b, "%s", s);
353 357621cd 2005-01-13 devnull }
354 357621cd 2005-01-13 devnull
355 357621cd 2005-01-13 devnull void
356 357621cd 2005-01-13 devnull setattr(ulong a)
357 357621cd 2005-01-13 devnull {
358 357621cd 2005-01-13 devnull int on, off, i, j;
359 357621cd 2005-01-13 devnull
360 357621cd 2005-01-13 devnull on = a & ~attr;
361 357621cd 2005-01-13 devnull off = attr & ~a;
362 357621cd 2005-01-13 devnull
363 357621cd 2005-01-13 devnull /* walk up the nest stack until we reach something we need to turn off. */
364 357621cd 2005-01-13 devnull for(i=0; i<nnest; i++)
365 357621cd 2005-01-13 devnull if(off&(1<<nest[i]))
366 357621cd 2005-01-13 devnull break;
367 357621cd 2005-01-13 devnull
368 357621cd 2005-01-13 devnull /* turn off everything above that */
369 357621cd 2005-01-13 devnull for(j=nnest-1; j>=i; j--)
370 357621cd 2005-01-13 devnull iputs(&bout, offattr[nest[j]]);
371 357621cd 2005-01-13 devnull
372 357621cd 2005-01-13 devnull /* turn on everything we just turned off but didn't want to */
373 357621cd 2005-01-13 devnull for(j=i; j<nnest; j++)
374 357621cd 2005-01-13 devnull if(a&(1<<nest[j]))
375 357621cd 2005-01-13 devnull iputs(&bout, onattr[nest[j]]);
376 357621cd 2005-01-13 devnull else
377 357621cd 2005-01-13 devnull nest[j] = 0;
378 357621cd 2005-01-13 devnull
379 357621cd 2005-01-13 devnull /* shift the zeros (turned off things) up */
380 357621cd 2005-01-13 devnull for(i=j=0; i<nnest; i++)
381 357621cd 2005-01-13 devnull if(nest[i] != 0)
382 357621cd 2005-01-13 devnull nest[j++] = nest[i];
383 357621cd 2005-01-13 devnull nnest = j;
384 357621cd 2005-01-13 devnull
385 357621cd 2005-01-13 devnull /* now turn on the new attributes */
386 357621cd 2005-01-13 devnull for(i=0; i<nelem(attrorder); i++){
387 357621cd 2005-01-13 devnull j = attrorder[i];
388 357621cd 2005-01-13 devnull if(on&(1<<j)){
389 357621cd 2005-01-13 devnull if(j == Anchor)
390 357621cd 2005-01-13 devnull onattr[j] = anchors[nanchors++];
391 357621cd 2005-01-13 devnull iputs(&bout, onattr[j]);
392 357621cd 2005-01-13 devnull nest[nnest++] = j;
393 357621cd 2005-01-13 devnull }
394 357621cd 2005-01-13 devnull }
395 357621cd 2005-01-13 devnull attr = a;
396 357621cd 2005-01-13 devnull }
397 357621cd 2005-01-13 devnull
398 357621cd 2005-01-13 devnull void
399 357621cd 2005-01-13 devnull flush(void)
400 357621cd 2005-01-13 devnull {
401 357621cd 2005-01-13 devnull int i;
402 357621cd 2005-01-13 devnull ulong c, a;
403 357621cd 2005-01-13 devnull
404 357621cd 2005-01-13 devnull nanchors = 0;
405 357621cd 2005-01-13 devnull for(i=0; i<nchars; i++){
406 357621cd 2005-01-13 devnull c = chars[i];
407 357621cd 2005-01-13 devnull if(c == Epp){
408 357621cd 2005-01-13 devnull iputrune(&bout, '\n');
409 357621cd 2005-01-13 devnull iputs(&bout, TABLE "<tr height=5><td></table>");
410 357621cd 2005-01-13 devnull iputrune(&bout, '\n');
411 357621cd 2005-01-13 devnull continue;
412 357621cd 2005-01-13 devnull }
413 357621cd 2005-01-13 devnull a = c & ~0xFFFF;
414 357621cd 2005-01-13 devnull c &= 0xFFFF;
415 357621cd 2005-01-13 devnull /*
416 357621cd 2005-01-13 devnull * If we're going to something off after a space,
417 357621cd 2005-01-13 devnull * let's just turn it off before.
418 357621cd 2005-01-13 devnull */
419 357621cd 2005-01-13 devnull if(c==' ' && i<nchars-1 && (chars[i+1]&0xFFFF) >= 32)
420 357621cd 2005-01-13 devnull a ^= a & ~chars[i+1];
421 357621cd 2005-01-13 devnull setattr(a);
422 357621cd 2005-01-13 devnull if(c == Estring){
423 357621cd 2005-01-13 devnull /* next word is string to print */
424 357621cd 2005-01-13 devnull iputs(&bout, (char*)chars[++i]);
425 357621cd 2005-01-13 devnull continue;
426 357621cd 2005-01-13 devnull }
427 357621cd 2005-01-13 devnull iputrune(&bout, c & 0xFFFF);
428 357621cd 2005-01-13 devnull }
429 357621cd 2005-01-13 devnull }
430 357621cd 2005-01-13 devnull
431 357621cd 2005-01-13 devnull void
432 357621cd 2005-01-13 devnull header(char *s)
433 357621cd 2005-01-13 devnull {
434 78e51a8c 2005-01-14 devnull char *p;
435 78e51a8c 2005-01-14 devnull
436 357621cd 2005-01-13 devnull Bprint(&bout, "<head>\n");
437 78e51a8c 2005-01-14 devnull if(pagename && section){
438 78e51a8c 2005-01-14 devnull char buf[512];
439 78e51a8c 2005-01-14 devnull strecpy(buf, buf+sizeof buf, pagename);
440 78e51a8c 2005-01-14 devnull for(p=buf; *p; p++)
441 3bd56b04 2005-09-09 devnull *p = tolower((uchar)*p);
442 78e51a8c 2005-01-14 devnull Bprint(&bout, "<title>%s(%s) - %s</title>\n", buf, section, s);
443 78e51a8c 2005-01-14 devnull }else
444 78e51a8c 2005-01-14 devnull Bprint(&bout, "<title>%s</title>\n", s);
445 357621cd 2005-01-13 devnull Bprint(&bout, "<meta content=\"text/html; charset=utf-8\" http-equiv=Content-Type>\n");
446 357621cd 2005-01-13 devnull Bprint(&bout, "</head>\n");
447 357621cd 2005-01-13 devnull Bprint(&bout, "<body bgcolor=#ffffff>\n");
448 78e51a8c 2005-01-14 devnull Bprint(&bout, "<table border=0 cellpadding=0 cellspacing=0 width=100%%>\n");
449 357621cd 2005-01-13 devnull Bprint(&bout, "<tr height=10><td>\n");
450 78e51a8c 2005-01-14 devnull Bprint(&bout, "<tr><td width=20><td>\n");
451 357621cd 2005-01-13 devnull if(pagename && section){
452 357621cd 2005-01-13 devnull Bprint(&bout, "<tr><td width=20><td><b>%s(%s)</b><td align=right><b>%s(%s)</b>\n",
453 357621cd 2005-01-13 devnull pagename, section, pagename, section);
454 357621cd 2005-01-13 devnull }
455 78e51a8c 2005-01-14 devnull Bprint(&bout, "<tr><td width=20><td colspan=2>\n");
456 357621cd 2005-01-13 devnull }
457 357621cd 2005-01-13 devnull
458 357621cd 2005-01-13 devnull void
459 357621cd 2005-01-13 devnull trailer(void)
460 357621cd 2005-01-13 devnull {
461 357621cd 2005-01-13 devnull Bprint(&bout, "<td width=20>\n");
462 357621cd 2005-01-13 devnull Bprint(&bout, "<tr height=20><td>\n");
463 357621cd 2005-01-13 devnull Bprint(&bout, "</table>\n");
464 357621cd 2005-01-13 devnull
465 357621cd 2005-01-13 devnull #ifdef LUCENT
466 357621cd 2005-01-13 devnull {
467 357621cd 2005-01-13 devnull Tm *t;
468 357621cd 2005-01-13 devnull
469 357621cd 2005-01-13 devnull t = localtime(time(nil));
470 357621cd 2005-01-13 devnull Bprint(&bout, TABLE "<tr height=20><td></table>\n");
471 cbeb0b26 2006-04-01 devnull Bprint(&bout, "<font size=-1><a href=\"http:/*www.lucent.com/copyright.html\">\n"); */
472 357621cd 2005-01-13 devnull Bprint(&bout, "Portions Copyright</A> &#169; %d Lucent Technologies. All rights reserved.</font>\n", t->year+1900);
473 357621cd 2005-01-13 devnull }
474 357621cd 2005-01-13 devnull #endif
475 357621cd 2005-01-13 devnull Bprint(&bout, "<!-- TRAILER -->\n");
476 357621cd 2005-01-13 devnull Bprint(&bout, "</body></html>\n");
477 357621cd 2005-01-13 devnull }
478 357621cd 2005-01-13 devnull
479 357621cd 2005-01-13 devnull int
480 357621cd 2005-01-13 devnull getc(Biobuf *b)
481 357621cd 2005-01-13 devnull {
482 357621cd 2005-01-13 devnull cno++;
483 357621cd 2005-01-13 devnull return Bgetrune(b);
484 357621cd 2005-01-13 devnull }
485 357621cd 2005-01-13 devnull
486 357621cd 2005-01-13 devnull void
487 357621cd 2005-01-13 devnull ungetc(Biobuf *b)
488 357621cd 2005-01-13 devnull {
489 357621cd 2005-01-13 devnull cno--;
490 357621cd 2005-01-13 devnull Bungetrune(b);
491 357621cd 2005-01-13 devnull }
492 357621cd 2005-01-13 devnull
493 357621cd 2005-01-13 devnull char*
494 357621cd 2005-01-13 devnull getline(Biobuf *b)
495 357621cd 2005-01-13 devnull {
496 357621cd 2005-01-13 devnull int i, c;
497 357621cd 2005-01-13 devnull
498 357621cd 2005-01-13 devnull for(i=0; i<sizeof buf; i++){
499 357621cd 2005-01-13 devnull c = getc(b);
500 357621cd 2005-01-13 devnull if(c == Beof)
501 357621cd 2005-01-13 devnull return nil;
502 357621cd 2005-01-13 devnull buf[i] = c;
503 357621cd 2005-01-13 devnull if(c == '\n'){
504 357621cd 2005-01-13 devnull buf[i] = '\0';
505 357621cd 2005-01-13 devnull break;
506 357621cd 2005-01-13 devnull }
507 357621cd 2005-01-13 devnull }
508 357621cd 2005-01-13 devnull return buf;
509 357621cd 2005-01-13 devnull }
510 357621cd 2005-01-13 devnull
511 357621cd 2005-01-13 devnull int
512 357621cd 2005-01-13 devnull getnum(Biobuf *b)
513 357621cd 2005-01-13 devnull {
514 357621cd 2005-01-13 devnull int i, c;
515 357621cd 2005-01-13 devnull
516 357621cd 2005-01-13 devnull i = 0;
517 357621cd 2005-01-13 devnull for(;;){
518 357621cd 2005-01-13 devnull c = getc(b);
519 357621cd 2005-01-13 devnull if(c<'0' || '9'<c){
520 357621cd 2005-01-13 devnull ungetc(b);
521 357621cd 2005-01-13 devnull break;
522 357621cd 2005-01-13 devnull }
523 357621cd 2005-01-13 devnull i = i*10 + (c-'0');
524 357621cd 2005-01-13 devnull }
525 357621cd 2005-01-13 devnull return i;
526 357621cd 2005-01-13 devnull }
527 357621cd 2005-01-13 devnull
528 357621cd 2005-01-13 devnull char*
529 357621cd 2005-01-13 devnull getstr(Biobuf *b)
530 357621cd 2005-01-13 devnull {
531 357621cd 2005-01-13 devnull int i, c;
532 357621cd 2005-01-13 devnull
533 357621cd 2005-01-13 devnull for(i=0; i<sizeof buf; i++){
534 357621cd 2005-01-13 devnull /* must get bytes not runes */
535 357621cd 2005-01-13 devnull cno++;
536 357621cd 2005-01-13 devnull c = Bgetc(b);
537 357621cd 2005-01-13 devnull if(c == Beof)
538 357621cd 2005-01-13 devnull return nil;
539 357621cd 2005-01-13 devnull buf[i] = c;
540 357621cd 2005-01-13 devnull if(c == '\n' || c==' ' || c=='\t'){
541 357621cd 2005-01-13 devnull ungetc(b);
542 357621cd 2005-01-13 devnull buf[i] = '\0';
543 357621cd 2005-01-13 devnull break;
544 357621cd 2005-01-13 devnull }
545 357621cd 2005-01-13 devnull }
546 357621cd 2005-01-13 devnull return buf;
547 357621cd 2005-01-13 devnull }
548 357621cd 2005-01-13 devnull
549 357621cd 2005-01-13 devnull int
550 357621cd 2005-01-13 devnull setnum(Biobuf *b, char *name, int min, int max)
551 357621cd 2005-01-13 devnull {
552 357621cd 2005-01-13 devnull int i;
553 357621cd 2005-01-13 devnull
554 357621cd 2005-01-13 devnull i = getnum(b);
555 357621cd 2005-01-13 devnull if(debug > 2)
556 357621cd 2005-01-13 devnull fprint(2, "set %s = %d\n", name, i);
557 357621cd 2005-01-13 devnull if(min<=i && i<max)
558 357621cd 2005-01-13 devnull return i;
559 357621cd 2005-01-13 devnull sysfatal("value of %s is %d; min %d max %d at %s:#%d", name, i, min, max, filename, cno);
560 357621cd 2005-01-13 devnull return i;
561 357621cd 2005-01-13 devnull }
562 357621cd 2005-01-13 devnull
563 357621cd 2005-01-13 devnull void
564 357621cd 2005-01-13 devnull xcmd(Biobuf *b)
565 357621cd 2005-01-13 devnull {
566 357621cd 2005-01-13 devnull char *p, *fld[16], buf[1024];
567 357621cd 2005-01-13 devnull
568 357621cd 2005-01-13 devnull int i, nfld;
569 357621cd 2005-01-13 devnull
570 357621cd 2005-01-13 devnull p = getline(b);
571 357621cd 2005-01-13 devnull if(p == nil)
572 357621cd 2005-01-13 devnull sysfatal("xcmd error: %r");
573 357621cd 2005-01-13 devnull if(debug)
574 357621cd 2005-01-13 devnull fprint(2, "x command '%s'\n", p);
575 357621cd 2005-01-13 devnull nfld = tokenize(p, fld, nelem(fld));
576 357621cd 2005-01-13 devnull if(nfld == 0)
577 357621cd 2005-01-13 devnull return;
578 357621cd 2005-01-13 devnull switch(fld[0][0]){
579 357621cd 2005-01-13 devnull case 'f':
580 357621cd 2005-01-13 devnull /* mount font */
581 357621cd 2005-01-13 devnull if(nfld != 3)
582 357621cd 2005-01-13 devnull break;
583 357621cd 2005-01-13 devnull i = atoi(fld[1]);
584 357621cd 2005-01-13 devnull if(i<0 || Nfont<=i)
585 357621cd 2005-01-13 devnull sysfatal("font %d out of range at %s:#%d", i, filename, cno);
586 357621cd 2005-01-13 devnull mountfont(i, fld[2]);
587 357621cd 2005-01-13 devnull return;
588 357621cd 2005-01-13 devnull case 'i':
589 357621cd 2005-01-13 devnull /* init */
590 357621cd 2005-01-13 devnull return;
591 357621cd 2005-01-13 devnull case 'r':
592 357621cd 2005-01-13 devnull if(nfld<2 || atoi(fld[1])!=res)
593 357621cd 2005-01-13 devnull sysfatal("typesetter has unexpected resolution %s", fld[1]? fld[1] : "<unspecified>");
594 357621cd 2005-01-13 devnull return;
595 357621cd 2005-01-13 devnull case 's':
596 357621cd 2005-01-13 devnull /* stop */
597 357621cd 2005-01-13 devnull return;
598 357621cd 2005-01-13 devnull case 't':
599 357621cd 2005-01-13 devnull /* trailer */
600 357621cd 2005-01-13 devnull return;
601 357621cd 2005-01-13 devnull case 'T':
602 357621cd 2005-01-13 devnull if(nfld!=2 || strcmp(fld[1], "utf")!=0)
603 357621cd 2005-01-13 devnull sysfatal("output for unknown typesetter type %s", fld[1]);
604 357621cd 2005-01-13 devnull return;
605 357621cd 2005-01-13 devnull case 'X':
606 357621cd 2005-01-13 devnull if(nfld<3 || strcmp(fld[1], "html")!=0)
607 357621cd 2005-01-13 devnull break;
608 357621cd 2005-01-13 devnull /* is it a man reference of the form cp(1)? */
609 357621cd 2005-01-13 devnull /* X manref start/end cp (1) */
610 357621cd 2005-01-13 devnull if(nfld==6 && strcmp(fld[2], "manref")==0){
611 357621cd 2005-01-13 devnull /* was the right macro; is it the right form? */
612 357621cd 2005-01-13 devnull if(strlen(fld[5])>=3 &&
613 b50e9caf 2005-01-16 devnull fld[5][0]=='('/*)*/ && (fld[5][2]==/*(*/')' || (isalpha((uchar)fld[5][2]) && fld[5][3]==/*(*/')')) &&
614 357621cd 2005-01-13 devnull '0'<=fld[5][1] && fld[5][1]<='9'){
615 357621cd 2005-01-13 devnull if(strcmp(fld[3], "start") == 0){
616 357621cd 2005-01-13 devnull /* set anchor attribute and remember string */
617 357621cd 2005-01-13 devnull attr |= (1<<Anchor);
618 78e51a8c 2005-01-14 devnull #if 0
619 357621cd 2005-01-13 devnull snprint(buf, sizeof buf,
620 78e51a8c 2005-01-14 devnull "<a href=\"/magic/man2html/man%c/%s\">",
621 357621cd 2005-01-13 devnull fld[5][1], fld[4]);
622 78e51a8c 2005-01-14 devnull #else
623 78e51a8c 2005-01-14 devnull snprint(buf, sizeof buf,
624 78e51a8c 2005-01-14 devnull "<a href=\"../man%c/%s.html\">", fld[5][1], fld[4]);
625 b50e9caf 2005-01-16 devnull for(p=buf; *p; p++)
626 b50e9caf 2005-01-16 devnull if('A' <= *p && *p <= 'Z')
627 b50e9caf 2005-01-16 devnull *p += 'a'-'A';
628 78e51a8c 2005-01-14 devnull #endif
629 357621cd 2005-01-13 devnull nanchors++;
630 357621cd 2005-01-13 devnull anchors = erealloc(anchors, nanchors*sizeof(char*));
631 357621cd 2005-01-13 devnull anchors[nanchors-1] = estrdup(buf);
632 357621cd 2005-01-13 devnull }else if(strcmp(fld[3], "end") == 0)
633 357621cd 2005-01-13 devnull attr &= ~(1<<Anchor);
634 357621cd 2005-01-13 devnull }
635 78e51a8c 2005-01-14 devnull }else if(nfld >= 4 && strcmp(fld[2], "href") == 0){
636 78e51a8c 2005-01-14 devnull attr |= 1<<Anchor;
637 78e51a8c 2005-01-14 devnull nanchors++;
638 78e51a8c 2005-01-14 devnull anchors = erealloc(anchors, nanchors*sizeof(char*));
639 78e51a8c 2005-01-14 devnull anchors[nanchors-1] = smprint("<a href=\"%s\">", fld[3]);
640 78e51a8c 2005-01-14 devnull }else if(strcmp(fld[2], "/href") == 0){
641 78e51a8c 2005-01-14 devnull attr &= ~(1<<Anchor);
642 357621cd 2005-01-13 devnull }else if(strcmp(fld[2], "manPP") == 0){
643 357621cd 2005-01-13 devnull didP = 1;
644 357621cd 2005-01-13 devnull emitul(Epp, 1);
645 357621cd 2005-01-13 devnull }else if(nfld>=5 && strcmp(fld[2], "manhead") == 0){
646 357621cd 2005-01-13 devnull pagename = strdup(fld[3]);
647 357621cd 2005-01-13 devnull section = strdup(fld[4]);
648 357621cd 2005-01-13 devnull }else if(nfld<4 || strcmp(fld[2], "manref")!=0){
649 357621cd 2005-01-13 devnull if(nfld>2 && strcmp(fld[2], "<P>")==0){ /* avoid triggering extra <br> */
650 357621cd 2005-01-13 devnull didP = 1;
651 357621cd 2005-01-13 devnull /* clear all font attributes before paragraph */
652 357621cd 2005-01-13 devnull emitul(' ' | (attr & ~(0xFFFF|((1<<Italic)|(1<<Bold)|(1<<CW)))), 0);
653 357621cd 2005-01-13 devnull emitstr("<P>");
654 357621cd 2005-01-13 devnull /* next emittec char will turn font attributes back on */
655 357621cd 2005-01-13 devnull }else if(nfld>2 && strcmp(fld[2], "<H4>")==0)
656 357621cd 2005-01-13 devnull attr |= (1<<Heading);
657 357621cd 2005-01-13 devnull else if(nfld>2 && strcmp(fld[2], "</H4>")==0)
658 357621cd 2005-01-13 devnull attr &= ~(1<<Heading);
659 357621cd 2005-01-13 devnull else if(debug)
660 357621cd 2005-01-13 devnull fprint(2, "unknown in-line html %s... at %s:%#d\n",
661 357621cd 2005-01-13 devnull fld[2], filename, cno);
662 357621cd 2005-01-13 devnull }
663 357621cd 2005-01-13 devnull return;
664 357621cd 2005-01-13 devnull }
665 357621cd 2005-01-13 devnull if(debug)
666 357621cd 2005-01-13 devnull fprint(2, "unknown or badly formatted x command %s\n", fld[0]);
667 357621cd 2005-01-13 devnull }
668 357621cd 2005-01-13 devnull
669 357621cd 2005-01-13 devnull int
670 357621cd 2005-01-13 devnull lookup(int c, Htmlchar tab[], int ntab)
671 357621cd 2005-01-13 devnull {
672 357621cd 2005-01-13 devnull int low, high, mid;
673 357621cd 2005-01-13 devnull
674 357621cd 2005-01-13 devnull low = 0;
675 357621cd 2005-01-13 devnull high = ntab - 1;
676 357621cd 2005-01-13 devnull while(low <= high){
677 357621cd 2005-01-13 devnull mid = (low+high)/2;
678 357621cd 2005-01-13 devnull if(c < tab[mid].value)
679 357621cd 2005-01-13 devnull high = mid - 1;
680 357621cd 2005-01-13 devnull else if(c > tab[mid].value)
681 357621cd 2005-01-13 devnull low = mid + 1;
682 357621cd 2005-01-13 devnull else
683 357621cd 2005-01-13 devnull return mid;
684 357621cd 2005-01-13 devnull }
685 357621cd 2005-01-13 devnull return -1; /* no match */
686 357621cd 2005-01-13 devnull }
687 357621cd 2005-01-13 devnull
688 357621cd 2005-01-13 devnull void
689 357621cd 2005-01-13 devnull emithtmlchar(int r)
690 357621cd 2005-01-13 devnull {
691 357621cd 2005-01-13 devnull int i;
692 357621cd 2005-01-13 devnull
693 357621cd 2005-01-13 devnull i = lookup(r, htmlchars, nelem(htmlchars));
694 357621cd 2005-01-13 devnull if(i >= 0)
695 357621cd 2005-01-13 devnull emitstr(htmlchars[i].name);
696 357621cd 2005-01-13 devnull else
697 357621cd 2005-01-13 devnull emit(r);
698 357621cd 2005-01-13 devnull }
699 357621cd 2005-01-13 devnull
700 357621cd 2005-01-13 devnull char*
701 357621cd 2005-01-13 devnull troffchar(char *s)
702 357621cd 2005-01-13 devnull {
703 357621cd 2005-01-13 devnull int i;
704 357621cd 2005-01-13 devnull
705 357621cd 2005-01-13 devnull for(i=0; troffchars[i].name!=nil; i++)
706 357621cd 2005-01-13 devnull if(strcmp(s, troffchars[i].name) == 0)
707 357621cd 2005-01-13 devnull return troffchars[i].value;
708 3087c4fe 2007-03-25 devnull return strdup(s);
709 357621cd 2005-01-13 devnull }
710 357621cd 2005-01-13 devnull
711 357621cd 2005-01-13 devnull void
712 357621cd 2005-01-13 devnull indent(void)
713 357621cd 2005-01-13 devnull {
714 357621cd 2005-01-13 devnull int nind;
715 357621cd 2005-01-13 devnull
716 357621cd 2005-01-13 devnull didP = 0;
717 357621cd 2005-01-13 devnull if(atnewline){
718 357621cd 2005-01-13 devnull if(hp != prevlineH){
719 357621cd 2005-01-13 devnull prevlineH = hp;
720 357621cd 2005-01-13 devnull /* these most peculiar numbers appear in the troff -man output */
721 357621cd 2005-01-13 devnull nind = ((prevlineH-1*res)+323)/324;
722 357621cd 2005-01-13 devnull attr &= ~((1<<Indent1)|(1<<Indent2)|(1<<Indent3));
723 357621cd 2005-01-13 devnull if(nind >= 1)
724 357621cd 2005-01-13 devnull attr |= (1<<Indent1);
725 357621cd 2005-01-13 devnull if(nind >= 2)
726 357621cd 2005-01-13 devnull attr |= (1<<Indent2);
727 357621cd 2005-01-13 devnull if(nind >= 3)
728 357621cd 2005-01-13 devnull attr |= (1<<Indent3);
729 357621cd 2005-01-13 devnull }
730 357621cd 2005-01-13 devnull atnewline = 0;
731 357621cd 2005-01-13 devnull }
732 357621cd 2005-01-13 devnull }
733 357621cd 2005-01-13 devnull
734 357621cd 2005-01-13 devnull void
735 357621cd 2005-01-13 devnull process(Biobuf *b, char *name)
736 357621cd 2005-01-13 devnull {
737 357621cd 2005-01-13 devnull int c, r, v, i;
738 357621cd 2005-01-13 devnull char *p;
739 357621cd 2005-01-13 devnull
740 357621cd 2005-01-13 devnull cno = 0;
741 357621cd 2005-01-13 devnull prevlineH = res;
742 357621cd 2005-01-13 devnull filename = name;
743 357621cd 2005-01-13 devnull for(;;){
744 357621cd 2005-01-13 devnull c = getc(b);
745 357621cd 2005-01-13 devnull switch(c){
746 357621cd 2005-01-13 devnull case Beof:
747 357621cd 2005-01-13 devnull /* go to ground state */
748 357621cd 2005-01-13 devnull attr = 0;
749 357621cd 2005-01-13 devnull emit('\n');
750 357621cd 2005-01-13 devnull return;
751 357621cd 2005-01-13 devnull case '\n':
752 357621cd 2005-01-13 devnull break;
753 357621cd 2005-01-13 devnull case '0': case '1': case '2': case '3': case '4':
754 357621cd 2005-01-13 devnull case '5': case '6': case '7': case '8': case '9':
755 357621cd 2005-01-13 devnull v = c-'0';
756 357621cd 2005-01-13 devnull c = getc(b);
757 357621cd 2005-01-13 devnull if(c<'0' || '9'<c)
758 357621cd 2005-01-13 devnull sysfatal("illegal character motion at %s:#%d", filename, cno);
759 357621cd 2005-01-13 devnull v = v*10 + (c-'0');
760 357621cd 2005-01-13 devnull hp += v;
761 357621cd 2005-01-13 devnull /* fall through to character case */
762 357621cd 2005-01-13 devnull case 'c':
763 357621cd 2005-01-13 devnull indent();
764 357621cd 2005-01-13 devnull r = getc(b);
765 357621cd 2005-01-13 devnull emithtmlchar(r);
766 357621cd 2005-01-13 devnull break;
767 357621cd 2005-01-13 devnull case 'D':
768 357621cd 2005-01-13 devnull /* draw line; ignore */
769 357621cd 2005-01-13 devnull do
770 357621cd 2005-01-13 devnull c = getc(b);
771 357621cd 2005-01-13 devnull while(c!='\n' && c!= Beof);
772 357621cd 2005-01-13 devnull break;
773 357621cd 2005-01-13 devnull case 'f':
774 357621cd 2005-01-13 devnull v = setnum(b, "font", 0, Nfont);
775 357621cd 2005-01-13 devnull switchfont(v);
776 357621cd 2005-01-13 devnull break;
777 357621cd 2005-01-13 devnull case 'h':
778 357621cd 2005-01-13 devnull v = setnum(b, "hpos", -20000, 20000);
779 357621cd 2005-01-13 devnull /* generate spaces if motion is large and within a line */
780 357621cd 2005-01-13 devnull if(!atnewline && v>2*72)
781 357621cd 2005-01-13 devnull for(i=0; i<v; i+=72)
782 357621cd 2005-01-13 devnull emitstr("&nbsp;");
783 357621cd 2005-01-13 devnull hp += v;
784 357621cd 2005-01-13 devnull break;
785 357621cd 2005-01-13 devnull case 'n':
786 357621cd 2005-01-13 devnull setnum(b, "n1", -10000, 10000);
787 cbeb0b26 2006-04-01 devnull /*Bprint(&bout, " N1=%d", v); */
788 357621cd 2005-01-13 devnull getc(b); /* space separates */
789 357621cd 2005-01-13 devnull setnum(b, "n2", -10000, 10000);
790 357621cd 2005-01-13 devnull atnewline = 1;
791 357621cd 2005-01-13 devnull if(!didP && hp < (Wid-1)*res) /* if line is less than 19" long, probably need a line break */
792 357621cd 2005-01-13 devnull emitstr("<br>");
793 357621cd 2005-01-13 devnull emit('\n');
794 357621cd 2005-01-13 devnull break;
795 357621cd 2005-01-13 devnull case 'p':
796 357621cd 2005-01-13 devnull page = setnum(b, "ps", -10000, 10000);
797 357621cd 2005-01-13 devnull break;
798 357621cd 2005-01-13 devnull case 's':
799 357621cd 2005-01-13 devnull ps = setnum(b, "ps", 1, 1000);
800 357621cd 2005-01-13 devnull break;
801 357621cd 2005-01-13 devnull case 'v':
802 357621cd 2005-01-13 devnull vp += setnum(b, "vpos", -10000, 10000);
803 357621cd 2005-01-13 devnull /* BUG: ignore motion */
804 357621cd 2005-01-13 devnull break;
805 357621cd 2005-01-13 devnull case 'x':
806 357621cd 2005-01-13 devnull xcmd(b);
807 357621cd 2005-01-13 devnull break;
808 357621cd 2005-01-13 devnull case 'w':
809 357621cd 2005-01-13 devnull emit(' ');
810 357621cd 2005-01-13 devnull break;
811 357621cd 2005-01-13 devnull case 'C':
812 357621cd 2005-01-13 devnull indent();
813 357621cd 2005-01-13 devnull p = getstr(b);
814 357621cd 2005-01-13 devnull emitstr(troffchar(p));
815 357621cd 2005-01-13 devnull break;
816 357621cd 2005-01-13 devnull case 'H':
817 357621cd 2005-01-13 devnull hp = setnum(b, "hpos", 0, 20000);
818 cbeb0b26 2006-04-01 devnull /*Bprint(&bout, " H=%d ", hp); */
819 357621cd 2005-01-13 devnull break;
820 357621cd 2005-01-13 devnull case 'V':
821 357621cd 2005-01-13 devnull vp = setnum(b, "vpos", 0, 10000);
822 357621cd 2005-01-13 devnull break;
823 357621cd 2005-01-13 devnull default:
824 357621cd 2005-01-13 devnull fprint(2, "dhtml: unknown directive %c(0x%.2ux) at %s:#%d\n", c, c, filename, cno);
825 357621cd 2005-01-13 devnull return;
826 357621cd 2005-01-13 devnull }
827 357621cd 2005-01-13 devnull }
828 357621cd 2005-01-13 devnull }
829 357621cd 2005-01-13 devnull
830 357621cd 2005-01-13 devnull HTMLfont*
831 357621cd 2005-01-13 devnull htmlfont(char *name)
832 357621cd 2005-01-13 devnull {
833 357621cd 2005-01-13 devnull int i;
834 357621cd 2005-01-13 devnull
835 357621cd 2005-01-13 devnull for(i=0; htmlfonts[i].name!=nil; i++)
836 357621cd 2005-01-13 devnull if(strcmp(name, htmlfonts[i].name) == 0)
837 357621cd 2005-01-13 devnull return &htmlfonts[i];
838 357621cd 2005-01-13 devnull return &htmlfonts[0];
839 357621cd 2005-01-13 devnull }
840 357621cd 2005-01-13 devnull
841 357621cd 2005-01-13 devnull void
842 357621cd 2005-01-13 devnull mountfont(int pos, char *name)
843 357621cd 2005-01-13 devnull {
844 357621cd 2005-01-13 devnull if(debug)
845 357621cd 2005-01-13 devnull fprint(2, "mount font %s on %d\n", name, pos);
846 357621cd 2005-01-13 devnull if(font[pos] != nil){
847 357621cd 2005-01-13 devnull free(font[pos]->name);
848 357621cd 2005-01-13 devnull free(font[pos]);
849 357621cd 2005-01-13 devnull }
850 357621cd 2005-01-13 devnull font[pos] = emalloc(sizeof(Font));
851 357621cd 2005-01-13 devnull font[pos]->name = estrdup(name);
852 357621cd 2005-01-13 devnull font[pos]->htmlfont = htmlfont(name);
853 357621cd 2005-01-13 devnull }
854 357621cd 2005-01-13 devnull
855 357621cd 2005-01-13 devnull void
856 357621cd 2005-01-13 devnull switchfont(int pos)
857 357621cd 2005-01-13 devnull {
858 357621cd 2005-01-13 devnull HTMLfont *hf;
859 357621cd 2005-01-13 devnull
860 357621cd 2005-01-13 devnull if(debug)
861 357621cd 2005-01-13 devnull fprint(2, "font change from %d (%s) to %d (%s)\n", ft, font[ft]->name, pos, font[pos]->name);
862 357621cd 2005-01-13 devnull if(pos == ft)
863 357621cd 2005-01-13 devnull return;
864 357621cd 2005-01-13 devnull hf = font[ft]->htmlfont;
865 357621cd 2005-01-13 devnull if(hf->bit != 0)
866 357621cd 2005-01-13 devnull attr &= ~(1<<hf->bit);
867 357621cd 2005-01-13 devnull ft = pos;
868 357621cd 2005-01-13 devnull hf = font[ft]->htmlfont;
869 357621cd 2005-01-13 devnull if(hf->bit != 0)
870 357621cd 2005-01-13 devnull attr |= (1<<hf->bit);
871 357621cd 2005-01-13 devnull }