1 c42a1d3d 2006-02-21 devnull #include "a.h"
5 c42a1d3d 2006-02-21 devnull MAXREQ = 100,
6 c42a1d3d 2006-02-21 devnull MAXRAW = 40,
7 c42a1d3d 2006-02-21 devnull MAXESC = 60,
8 c42a1d3d 2006-02-21 devnull MAXLINE = 1024,
9 c42a1d3d 2006-02-21 devnull MAXIF = 20,
10 cbeb0b26 2006-04-01 devnull MAXARG = 10
13 c42a1d3d 2006-02-21 devnull typedef struct Esc Esc;
14 c42a1d3d 2006-02-21 devnull typedef struct Req Req;
15 c42a1d3d 2006-02-21 devnull typedef struct Raw Raw;
17 c42a1d3d 2006-02-21 devnull /* escape sequence handler, like for \c */
18 c42a1d3d 2006-02-21 devnull struct Esc
21 c42a1d3d 2006-02-21 devnull int (*f)(void);
22 c42a1d3d 2006-02-21 devnull int mode;
25 c42a1d3d 2006-02-21 devnull /* raw request handler, like for .ie */
26 c42a1d3d 2006-02-21 devnull struct Raw
28 c42a1d3d 2006-02-21 devnull Rune *name;
29 c42a1d3d 2006-02-21 devnull void (*f)(Rune*);
32 c42a1d3d 2006-02-21 devnull /* regular request handler, like for .ft */
33 c42a1d3d 2006-02-21 devnull struct Req
35 c42a1d3d 2006-02-21 devnull int argc;
36 c42a1d3d 2006-02-21 devnull Rune *name;
37 c42a1d3d 2006-02-21 devnull void (*f)(int, Rune**);
40 c42a1d3d 2006-02-21 devnull int dot = '.';
41 c42a1d3d 2006-02-21 devnull int tick = '\'';
42 c42a1d3d 2006-02-21 devnull int backslash = '\\';
44 c42a1d3d 2006-02-21 devnull int inputmode;
45 c42a1d3d 2006-02-21 devnull Req req[MAXREQ];
46 c42a1d3d 2006-02-21 devnull int nreq;
47 c42a1d3d 2006-02-21 devnull Raw raw[MAXRAW];
48 c42a1d3d 2006-02-21 devnull int nraw;
49 c42a1d3d 2006-02-21 devnull Esc esc[MAXESC];
50 c42a1d3d 2006-02-21 devnull int nesc;
51 c42a1d3d 2006-02-21 devnull int iftrue[MAXIF];
52 c42a1d3d 2006-02-21 devnull int niftrue;
54 c42a1d3d 2006-02-21 devnull int isoutput;
55 c42a1d3d 2006-02-21 devnull int linepos;
59 c42a1d3d 2006-02-21 devnull addraw(Rune *name, void (*f)(Rune*))
63 c42a1d3d 2006-02-21 devnull if(nraw >= nelem(raw)){
64 c42a1d3d 2006-02-21 devnull fprint(2, "too many raw requets\n");
67 c42a1d3d 2006-02-21 devnull r = &raw[nraw++];
68 c42a1d3d 2006-02-21 devnull r->name = erunestrdup(name);
69 c42a1d3d 2006-02-21 devnull r->f = f;
73 c42a1d3d 2006-02-21 devnull delraw(Rune *name)
77 c42a1d3d 2006-02-21 devnull for(i=0; i<nraw; i++){
78 c42a1d3d 2006-02-21 devnull if(runestrcmp(raw[i].name, name) == 0){
79 c42a1d3d 2006-02-21 devnull if(i != --nraw){
80 c42a1d3d 2006-02-21 devnull free(raw[i].name);
81 c42a1d3d 2006-02-21 devnull raw[i] = raw[nraw];
89 c42a1d3d 2006-02-21 devnull renraw(Rune *from, Rune *to)
93 c42a1d3d 2006-02-21 devnull delraw(to);
94 c42a1d3d 2006-02-21 devnull for(i=0; i<nraw; i++)
95 c42a1d3d 2006-02-21 devnull if(runestrcmp(raw[i].name, from) == 0){
96 c42a1d3d 2006-02-21 devnull free(raw[i].name);
97 c42a1d3d 2006-02-21 devnull raw[i].name = erunestrdup(to);
104 c42a1d3d 2006-02-21 devnull addreq(Rune *s, void (*f)(int, Rune**), int argc)
108 c42a1d3d 2006-02-21 devnull if(nreq >= nelem(req)){
109 c42a1d3d 2006-02-21 devnull fprint(2, "too many requests\n");
112 c42a1d3d 2006-02-21 devnull r = &req[nreq++];
113 c42a1d3d 2006-02-21 devnull r->name = erunestrdup(s);
114 c42a1d3d 2006-02-21 devnull r->f = f;
115 c42a1d3d 2006-02-21 devnull r->argc = argc;
119 c42a1d3d 2006-02-21 devnull delreq(Rune *name)
123 c42a1d3d 2006-02-21 devnull for(i=0; i<nreq; i++){
124 c42a1d3d 2006-02-21 devnull if(runestrcmp(req[i].name, name) == 0){
125 c42a1d3d 2006-02-21 devnull if(i != --nreq){
126 c42a1d3d 2006-02-21 devnull free(req[i].name);
127 c42a1d3d 2006-02-21 devnull req[i] = req[nreq];
135 c42a1d3d 2006-02-21 devnull renreq(Rune *from, Rune *to)
139 c42a1d3d 2006-02-21 devnull delreq(to);
140 c42a1d3d 2006-02-21 devnull for(i=0; i<nreq; i++)
141 c42a1d3d 2006-02-21 devnull if(runestrcmp(req[i].name, from) == 0){
142 c42a1d3d 2006-02-21 devnull free(req[i].name);
143 c42a1d3d 2006-02-21 devnull req[i].name = erunestrdup(to);
149 c42a1d3d 2006-02-21 devnull addesc(Rune r, int (*f)(void), int mode)
153 c42a1d3d 2006-02-21 devnull if(nesc >= nelem(esc)){
154 c42a1d3d 2006-02-21 devnull fprint(2, "too many escapes\n");
157 c42a1d3d 2006-02-21 devnull e = &esc[nesc++];
158 c42a1d3d 2006-02-21 devnull e->r = r;
159 c42a1d3d 2006-02-21 devnull e->f = f;
160 c42a1d3d 2006-02-21 devnull e->mode = mode;
164 c42a1d3d 2006-02-21 devnull * Get the next logical character in the input stream.
167 c42a1d3d 2006-02-21 devnull getnext(void)
169 c42a1d3d 2006-02-21 devnull int i, r;
172 c42a1d3d 2006-02-21 devnull r = getrune();
173 c42a1d3d 2006-02-21 devnull if(r < 0)
174 c42a1d3d 2006-02-21 devnull return -1;
175 c42a1d3d 2006-02-21 devnull if(r == Uformatted){
177 c42a1d3d 2006-02-21 devnull assert(!isoutput);
178 c42a1d3d 2006-02-21 devnull while((r = getrune()) >= 0 && r != Uunformatted){
179 c42a1d3d 2006-02-21 devnull if(r == Uformatted)
180 c42a1d3d 2006-02-21 devnull continue;
181 c42a1d3d 2006-02-21 devnull outrune(r);
183 c42a1d3d 2006-02-21 devnull goto next;
185 c42a1d3d 2006-02-21 devnull if(r == Uunformatted)
186 c42a1d3d 2006-02-21 devnull goto next;
187 c42a1d3d 2006-02-21 devnull if(r == backslash){
188 c42a1d3d 2006-02-21 devnull r = getrune();
189 c42a1d3d 2006-02-21 devnull if(r < 0)
190 c42a1d3d 2006-02-21 devnull return -1;
191 c42a1d3d 2006-02-21 devnull for(i=0; i<nesc; i++){
192 c42a1d3d 2006-02-21 devnull if(r == esc[i].r && (inputmode&esc[i].mode)==inputmode){
193 c42a1d3d 2006-02-21 devnull if(esc[i].f == e_warn)
194 c42a1d3d 2006-02-21 devnull warn("ignoring %C%C", backslash, r);
195 c42a1d3d 2006-02-21 devnull r = esc[i].f();
196 c42a1d3d 2006-02-21 devnull if(r <= 0)
197 c42a1d3d 2006-02-21 devnull goto next;
198 c42a1d3d 2006-02-21 devnull return r;
201 c42a1d3d 2006-02-21 devnull if(inputmode&(ArgMode|CopyMode)){
202 c42a1d3d 2006-02-21 devnull ungetrune(r);
203 c42a1d3d 2006-02-21 devnull r = backslash;
206 c42a1d3d 2006-02-21 devnull return r;
210 c42a1d3d 2006-02-21 devnull ungetnext(Rune r)
213 c42a1d3d 2006-02-21 devnull * really we want to undo the getrunes that led us here,
214 c42a1d3d 2006-02-21 devnull * since the call after ungetnext might be getrune!
216 c42a1d3d 2006-02-21 devnull ungetrune(r);
220 c42a1d3d 2006-02-21 devnull _readx(Rune *p, int n, int nmode, int line)
222 c42a1d3d 2006-02-21 devnull int c, omode;
223 c42a1d3d 2006-02-21 devnull Rune *e;
225 c42a1d3d 2006-02-21 devnull while((c = getrune()) == ' ' || c == '\t')
227 c42a1d3d 2006-02-21 devnull ungetrune(c);
228 c42a1d3d 2006-02-21 devnull omode = inputmode;
229 c42a1d3d 2006-02-21 devnull inputmode = nmode;
230 c42a1d3d 2006-02-21 devnull e = p+n-1;
231 c42a1d3d 2006-02-21 devnull for(c=getnext(); p<e; c=getnext()){
232 c42a1d3d 2006-02-21 devnull if(c < 0)
234 c42a1d3d 2006-02-21 devnull if(!line && (c == ' ' || c == '\t'))
236 c42a1d3d 2006-02-21 devnull if(c == '\n'){
237 c42a1d3d 2006-02-21 devnull if(!line)
238 c42a1d3d 2006-02-21 devnull ungetnext(c);
241 c42a1d3d 2006-02-21 devnull *p++ = c;
243 c42a1d3d 2006-02-21 devnull inputmode = omode;
245 c42a1d3d 2006-02-21 devnull if(c < 0)
246 c42a1d3d 2006-02-21 devnull return -1;
247 c42a1d3d 2006-02-21 devnull return 0;
251 c42a1d3d 2006-02-21 devnull * Get the next argument from the current line.
254 c42a1d3d 2006-02-21 devnull copyarg(void)
256 c42a1d3d 2006-02-21 devnull static Rune buf[MaxLine];
258 c42a1d3d 2006-02-21 devnull Rune *r;
260 c42a1d3d 2006-02-21 devnull if(_readx(buf, sizeof buf, ArgMode, 0) < 0)
261 c42a1d3d 2006-02-21 devnull return nil;
262 c42a1d3d 2006-02-21 devnull r = runestrstr(buf, L("\\\""));
265 c42a1d3d 2006-02-21 devnull while((c = getrune()) >= 0 && c != '\n')
267 c42a1d3d 2006-02-21 devnull ungetrune('\n');
269 c42a1d3d 2006-02-21 devnull r = erunestrdup(buf);
270 c42a1d3d 2006-02-21 devnull return r;
274 c42a1d3d 2006-02-21 devnull * Read the current line in given mode. Newline not kept.
275 c42a1d3d 2006-02-21 devnull * Uses different buffer from copyarg!
278 c42a1d3d 2006-02-21 devnull readline(int m)
280 c42a1d3d 2006-02-21 devnull static Rune buf[MaxLine];
281 c42a1d3d 2006-02-21 devnull Rune *r;
283 c42a1d3d 2006-02-21 devnull if(_readx(buf, sizeof buf, m, 1) < 0)
284 c42a1d3d 2006-02-21 devnull return nil;
285 c42a1d3d 2006-02-21 devnull r = erunestrdup(buf);
286 c42a1d3d 2006-02-21 devnull return r;
290 c42a1d3d 2006-02-21 devnull * Given the argument line (already read in copy+arg mode),
291 c42a1d3d 2006-02-21 devnull * parse into arguments. Note that \" has been left in place
292 c42a1d3d 2006-02-21 devnull * during copy+arg mode parsing, so comments still need to be stripped.
295 c42a1d3d 2006-02-21 devnull parseargs(Rune *p, Rune **argv)
297 c42a1d3d 2006-02-21 devnull int argc;
298 c42a1d3d 2006-02-21 devnull Rune *w;
300 c42a1d3d 2006-02-21 devnull for(argc=0; argc<MAXARG; argc++){
301 c42a1d3d 2006-02-21 devnull while(*p == ' ' || *p == '\t')
303 c42a1d3d 2006-02-21 devnull if(*p == 0)
305 c42a1d3d 2006-02-21 devnull argv[argc] = p;
306 c42a1d3d 2006-02-21 devnull if(*p == '"'){
307 c42a1d3d 2006-02-21 devnull /* quoted argument */
308 c42a1d3d 2006-02-21 devnull if(*(p+1) == '"'){
309 c42a1d3d 2006-02-21 devnull /* empty argument */
313 c42a1d3d 2006-02-21 devnull /* parse quoted string */
314 c42a1d3d 2006-02-21 devnull w = p++;
315 c42a1d3d 2006-02-21 devnull for(; *p; p++){
316 c42a1d3d 2006-02-21 devnull if(*p == '"' && *(p+1) == '"')
317 c42a1d3d 2006-02-21 devnull *w++ = '"';
318 c42a1d3d 2006-02-21 devnull else if(*p == '"'){
322 c42a1d3d 2006-02-21 devnull *w++ = *p;
327 c42a1d3d 2006-02-21 devnull /* unquoted argument - need to watch out for \" comment */
328 c42a1d3d 2006-02-21 devnull for(; *p; p++){
329 c42a1d3d 2006-02-21 devnull if(*p == ' ' || *p == '\t'){
330 c42a1d3d 2006-02-21 devnull *p++ = 0;
333 c42a1d3d 2006-02-21 devnull if(*p == '\\' && *(p+1) == '"'){
335 c42a1d3d 2006-02-21 devnull if(p != argv[argc])
337 c42a1d3d 2006-02-21 devnull return argc;
342 c42a1d3d 2006-02-21 devnull return argc;
346 c42a1d3d 2006-02-21 devnull * Process a dot line. The dot has been read.
349 c42a1d3d 2006-02-21 devnull dotline(int dot)
351 c42a1d3d 2006-02-21 devnull int argc, i;
352 c42a1d3d 2006-02-21 devnull Rune *a, *argv[1+MAXARG];
355 c42a1d3d 2006-02-21 devnull * Read request/macro name
357 c42a1d3d 2006-02-21 devnull a = copyarg();
358 c42a1d3d 2006-02-21 devnull if(a == nil || a[0] == 0){
359 c42a1d3d 2006-02-21 devnull free(a);
360 c42a1d3d 2006-02-21 devnull getrune(); /* \n */
363 c42a1d3d 2006-02-21 devnull argv[0] = a;
365 c42a1d3d 2006-02-21 devnull * Check for .if, .ie, and others with special parsing.
367 c42a1d3d 2006-02-21 devnull for(i=0; i<nraw; i++){
368 c42a1d3d 2006-02-21 devnull if(runestrcmp(raw[i].name, a) == 0){
369 c42a1d3d 2006-02-21 devnull raw[i].f(raw[i].name);
370 c42a1d3d 2006-02-21 devnull free(a);
376 c42a1d3d 2006-02-21 devnull * Read rest of line in copy mode, invoke regular request.
378 c42a1d3d 2006-02-21 devnull a = readline(ArgMode);
379 c42a1d3d 2006-02-21 devnull if(a == nil){
380 c42a1d3d 2006-02-21 devnull free(argv[0]);
383 c42a1d3d 2006-02-21 devnull argc = 1+parseargs(a, argv+1);
384 c42a1d3d 2006-02-21 devnull for(i=0; i<nreq; i++){
385 c42a1d3d 2006-02-21 devnull if(runestrcmp(req[i].name, argv[0]) == 0){
386 c42a1d3d 2006-02-21 devnull if(req[i].argc != -1){
387 c42a1d3d 2006-02-21 devnull if(argc < 1+req[i].argc){
388 c42a1d3d 2006-02-21 devnull warn("not enough arguments for %C%S", dot, req[i].name);
389 c42a1d3d 2006-02-21 devnull free(argv[0]);
390 c42a1d3d 2006-02-21 devnull free(a);
393 c42a1d3d 2006-02-21 devnull if(argc > 1+req[i].argc)
394 c42a1d3d 2006-02-21 devnull warn("too many arguments for %C%S", dot, req[i].name);
396 c42a1d3d 2006-02-21 devnull req[i].f(argc, argv);
397 c42a1d3d 2006-02-21 devnull free(argv[0]);
398 c42a1d3d 2006-02-21 devnull free(a);
404 c42a1d3d 2006-02-21 devnull * Invoke user-defined macros.
406 c42a1d3d 2006-02-21 devnull runmacro(dot, argc, argv);
407 c42a1d3d 2006-02-21 devnull free(argv[0]);
408 c42a1d3d 2006-02-21 devnull free(a);
412 c42a1d3d 2006-02-21 devnull * newlines are magical in various ways.
414 c42a1d3d 2006-02-21 devnull int bol;
416 c42a1d3d 2006-02-21 devnull newline(void)
421 c42a1d3d 2006-02-21 devnull sp(eval(L("1v")));
422 c42a1d3d 2006-02-21 devnull bol = 1;
423 c42a1d3d 2006-02-21 devnull if((n=getnr(L(".ce"))) > 0){
424 c42a1d3d 2006-02-21 devnull nr(L(".ce"), n-1);
427 c42a1d3d 2006-02-21 devnull if(getnr(L(".fi")) == 0)
429 c42a1d3d 2006-02-21 devnull outrune('\n');
433 c42a1d3d 2006-02-21 devnull startoutput(void)
435 c42a1d3d 2006-02-21 devnull char *align;
436 c42a1d3d 2006-02-21 devnull double ps, vs, lm, rm, ti;
437 c42a1d3d 2006-02-21 devnull Rune buf[200];
439 c42a1d3d 2006-02-21 devnull if(isoutput)
441 c42a1d3d 2006-02-21 devnull isoutput = 1;
443 c42a1d3d 2006-02-21 devnull if(getnr(L(".paragraph")) == 0)
446 c42a1d3d 2006-02-21 devnull nr(L(".ns"), 0);
447 c42a1d3d 2006-02-21 devnull isoutput = 1;
448 c42a1d3d 2006-02-21 devnull ps = getnr(L(".s"));
449 c42a1d3d 2006-02-21 devnull if(ps <= 1)
450 c42a1d3d 2006-02-21 devnull ps = 10;
451 c42a1d3d 2006-02-21 devnull ps /= 72.0;
452 c42a1d3d 2006-02-21 devnull USED(ps);
454 c42a1d3d 2006-02-21 devnull vs = getnr(L(".v"))*getnr(L(".ls")) * 1.0/UPI;
455 c42a1d3d 2006-02-21 devnull vs /= (10.0/72.0); /* ps */
456 c42a1d3d 2006-02-21 devnull if(vs == 0)
457 c42a1d3d 2006-02-21 devnull vs = 1.2;
459 c42a1d3d 2006-02-21 devnull lm = (getnr(L(".o"))+getnr(L(".i"))) * 1.0/UPI;
460 c42a1d3d 2006-02-21 devnull ti = getnr(L(".ti")) * 1.0/UPI;
461 c42a1d3d 2006-02-21 devnull nr(L(".ti"), 0);
463 c42a1d3d 2006-02-21 devnull rm = 8.0 - getnr(L(".l"))*1.0/UPI - getnr(L(".o"))*1.0/UPI;
464 c42a1d3d 2006-02-21 devnull if(rm < 0)
466 c42a1d3d 2006-02-21 devnull switch(getnr(L(".j"))){
467 c42a1d3d 2006-02-21 devnull default:
469 c42a1d3d 2006-02-21 devnull align = "left";
472 c42a1d3d 2006-02-21 devnull align = "justify";
475 c42a1d3d 2006-02-21 devnull align = "center";
478 c42a1d3d 2006-02-21 devnull align = "right";
481 c42a1d3d 2006-02-21 devnull if(getnr(L(".ce")))
482 c42a1d3d 2006-02-21 devnull align = "center";
483 c42a1d3d 2006-02-21 devnull if(!getnr(L(".margin")))
484 c42a1d3d 2006-02-21 devnull runesnprint(buf, nelem(buf), "<p style=\"line-height: %.1fem; text-indent: %.2fin; margin-top: 0; margin-bottom: 0; text-align: %s;\">\n",
485 c42a1d3d 2006-02-21 devnull vs, ti, align);
487 c42a1d3d 2006-02-21 devnull runesnprint(buf, nelem(buf), "<p style=\"line-height: %.1fem; margin-left: %.2fin; text-indent: %.2fin; margin-right: %.2fin; margin-top: 0; margin-bottom: 0; text-align: %s;\">\n",
488 c42a1d3d 2006-02-21 devnull vs, lm, ti, rm, align);
489 c42a1d3d 2006-02-21 devnull outhtml(buf);
492 c42a1d3d 2006-02-21 devnull br(void)
494 c42a1d3d 2006-02-21 devnull if(!isoutput)
496 c42a1d3d 2006-02-21 devnull isoutput = 0;
498 c42a1d3d 2006-02-21 devnull nr(L(".dv"), 0);
500 c42a1d3d 2006-02-21 devnull hideihtml();
501 c42a1d3d 2006-02-21 devnull if(getnr(L(".paragraph")))
502 c42a1d3d 2006-02-21 devnull outhtml(L("</p>"));
506 c42a1d3d 2006-02-21 devnull r_margin(int argc, Rune **argv)
508 c42a1d3d 2006-02-21 devnull USED(argc);
510 c42a1d3d 2006-02-21 devnull nr(L(".margin"), eval(argv[1]));
513 c42a1d3d 2006-02-21 devnull int inrequest;
515 c42a1d3d 2006-02-21 devnull runinput(void)
519 c42a1d3d 2006-02-21 devnull bol = 1;
520 c42a1d3d 2006-02-21 devnull for(;;){
521 c42a1d3d 2006-02-21 devnull c = getnext();
522 c42a1d3d 2006-02-21 devnull if(c < 0)
524 c42a1d3d 2006-02-21 devnull if((c == dot || c == tick) && bol){
525 c42a1d3d 2006-02-21 devnull inrequest = 1;
526 c42a1d3d 2006-02-21 devnull dotline(c);
527 c42a1d3d 2006-02-21 devnull bol = 1;
528 c42a1d3d 2006-02-21 devnull inrequest = 0;
529 c42a1d3d 2006-02-21 devnull }else if(c == '\n'){
530 c42a1d3d 2006-02-21 devnull newline();
531 c42a1d3d 2006-02-21 devnull itrap();
532 c42a1d3d 2006-02-21 devnull linepos = 0;
534 c42a1d3d 2006-02-21 devnull outtrap();
535 c42a1d3d 2006-02-21 devnull startoutput();
536 c42a1d3d 2006-02-21 devnull showihtml();
537 c42a1d3d 2006-02-21 devnull if(c == '\t'){
538 c42a1d3d 2006-02-21 devnull /* XXX do better */
539 c42a1d3d 2006-02-21 devnull outrune(' ');
540 c42a1d3d 2006-02-21 devnull while(++linepos%4)
541 c42a1d3d 2006-02-21 devnull outrune(' ');
543 c42a1d3d 2006-02-21 devnull outrune(c);
544 c42a1d3d 2006-02-21 devnull linepos++;
546 c42a1d3d 2006-02-21 devnull bol = 0;
552 c42a1d3d 2006-02-21 devnull run(void)
554 c42a1d3d 2006-02-21 devnull t1init();
555 c42a1d3d 2006-02-21 devnull t2init();
556 c42a1d3d 2006-02-21 devnull t3init();
557 c42a1d3d 2006-02-21 devnull t4init();
558 c42a1d3d 2006-02-21 devnull t5init();
559 c42a1d3d 2006-02-21 devnull t6init();
560 c42a1d3d 2006-02-21 devnull t7init();
561 c42a1d3d 2006-02-21 devnull t8init();
562 c42a1d3d 2006-02-21 devnull /* t9init(); t9.c */
563 c42a1d3d 2006-02-21 devnull t10init();
564 c42a1d3d 2006-02-21 devnull t11init();
565 c42a1d3d 2006-02-21 devnull /* t12init(); t12.c */
566 c42a1d3d 2006-02-21 devnull t13init();
567 c42a1d3d 2006-02-21 devnull t14init();
568 c42a1d3d 2006-02-21 devnull t15init();
569 c42a1d3d 2006-02-21 devnull t16init();
570 c42a1d3d 2006-02-21 devnull t17init();
571 c42a1d3d 2006-02-21 devnull t18init();
572 c42a1d3d 2006-02-21 devnull t19init();
573 c42a1d3d 2006-02-21 devnull t20init();
574 c42a1d3d 2006-02-21 devnull htmlinit();
575 c42a1d3d 2006-02-21 devnull hideihtml();
577 c42a1d3d 2006-02-21 devnull addreq(L("margin"), r_margin, 1);
578 c42a1d3d 2006-02-21 devnull nr(L(".margin"), 1);
579 c42a1d3d 2006-02-21 devnull nr(L(".paragraph"), 1);
581 c42a1d3d 2006-02-21 devnull runinput();
582 c42a1d3d 2006-02-21 devnull while(popinput())
584 c42a1d3d 2006-02-21 devnull dot = '.';
585 c42a1d3d 2006-02-21 devnull if(verbose)
586 c42a1d3d 2006-02-21 devnull fprint(2, "eof\n");
587 c42a1d3d 2006-02-21 devnull runmacro1(L("eof"));
588 c42a1d3d 2006-02-21 devnull closehtml();
592 c42a1d3d 2006-02-21 devnull out(Rune *s)
594 c42a1d3d 2006-02-21 devnull if(s == nil)
596 c42a1d3d 2006-02-21 devnull for(; *s; s++)
597 c42a1d3d 2006-02-21 devnull outrune(*s);
600 c42a1d3d 2006-02-21 devnull void (*outcb)(Rune);
603 c42a1d3d 2006-02-21 devnull inroman(Rune r)
607 c42a1d3d 2006-02-21 devnull f = getnr(L(".f"));
608 c42a1d3d 2006-02-21 devnull nr(L(".f"), 1);
609 c42a1d3d 2006-02-21 devnull runmacro1(L("font"));
610 c42a1d3d 2006-02-21 devnull outrune(r);
611 c42a1d3d 2006-02-21 devnull nr(L(".f"), f);
612 c42a1d3d 2006-02-21 devnull runmacro1(L("font"));
616 c42a1d3d 2006-02-21 devnull Brune(Rune r)
618 c42a1d3d 2006-02-21 devnull if(r == '&')
619 c42a1d3d 2006-02-21 devnull Bprint(&bout, "&");
620 c42a1d3d 2006-02-21 devnull else if(r == '<')
621 c42a1d3d 2006-02-21 devnull Bprint(&bout, "<");
622 c42a1d3d 2006-02-21 devnull else if(r == '>')
623 c42a1d3d 2006-02-21 devnull Bprint(&bout, ">");
624 c42a1d3d 2006-02-21 devnull else if(r < Runeself || utf8)
625 c42a1d3d 2006-02-21 devnull Bprint(&bout, "%C", r);
627 c42a1d3d 2006-02-21 devnull Bprint(&bout, "%S", rune2html(r));
631 c42a1d3d 2006-02-21 devnull outhtml(Rune *s)
635 c42a1d3d 2006-02-21 devnull for(; *s; s++){
636 c42a1d3d 2006-02-21 devnull switch(r = *s){
637 c42a1d3d 2006-02-21 devnull case '<':
638 c42a1d3d 2006-02-21 devnull r = Ult;
640 c42a1d3d 2006-02-21 devnull case '>':
641 c42a1d3d 2006-02-21 devnull r = Ugt;
643 c42a1d3d 2006-02-21 devnull case '&':
644 c42a1d3d 2006-02-21 devnull r = Uamp;
646 c42a1d3d 2006-02-21 devnull case ' ':
647 c42a1d3d 2006-02-21 devnull r = Uspace;
650 c42a1d3d 2006-02-21 devnull outrune(r);
655 c42a1d3d 2006-02-21 devnull outrune(Rune r)
657 c42a1d3d 2006-02-21 devnull switch(r){
658 c42a1d3d 2006-02-21 devnull case ' ':
659 c42a1d3d 2006-02-21 devnull if(getnr(L(".fi")) == 0)
660 c42a1d3d 2006-02-21 devnull r = Unbsp;
662 c42a1d3d 2006-02-21 devnull case Uformatted:
663 c42a1d3d 2006-02-21 devnull case Uunformatted:
664 c42a1d3d 2006-02-21 devnull abort();
666 c42a1d3d 2006-02-21 devnull if(outcb){
667 c42a1d3d 2006-02-21 devnull if(r == ' ')
668 c42a1d3d 2006-02-21 devnull r = Uspace;
669 c42a1d3d 2006-02-21 devnull outcb(r);
672 c42a1d3d 2006-02-21 devnull /* writing to bout */
673 c42a1d3d 2006-02-21 devnull switch(r){
674 c42a1d3d 2006-02-21 devnull case Uempty:
676 c42a1d3d 2006-02-21 devnull case Upl:
677 c42a1d3d 2006-02-21 devnull inroman('+');
679 c42a1d3d 2006-02-21 devnull case Ueq:
680 c42a1d3d 2006-02-21 devnull inroman('=');
682 c42a1d3d 2006-02-21 devnull case Umi:
683 c42a1d3d 2006-02-21 devnull inroman(0x2212);
685 c42a1d3d 2006-02-21 devnull case Utick:
686 c42a1d3d 2006-02-21 devnull r = '\'';
688 c42a1d3d 2006-02-21 devnull case Ubtick:
689 c42a1d3d 2006-02-21 devnull r = '`';
691 c42a1d3d 2006-02-21 devnull case Uminus:
692 c42a1d3d 2006-02-21 devnull r = '-';
694 c42a1d3d 2006-02-21 devnull case '\'':
695 c42a1d3d 2006-02-21 devnull Bprint(&bout, "’");
697 c42a1d3d 2006-02-21 devnull case '`':
698 c42a1d3d 2006-02-21 devnull Bprint(&bout, "‘");
700 c42a1d3d 2006-02-21 devnull case Uamp:
701 c42a1d3d 2006-02-21 devnull Bputrune(&bout, '&');
703 c42a1d3d 2006-02-21 devnull case Ult:
704 c42a1d3d 2006-02-21 devnull Bputrune(&bout, '<');
706 c42a1d3d 2006-02-21 devnull case Ugt:
707 c42a1d3d 2006-02-21 devnull Bputrune(&bout, '>');
709 c42a1d3d 2006-02-21 devnull case Uspace:
710 c42a1d3d 2006-02-21 devnull Bputrune(&bout, ' ');
712 c42a1d3d 2006-02-21 devnull case 0x2032:
714 c42a1d3d 2006-02-21 devnull * In Firefox, at least, the prime is not
715 c42a1d3d 2006-02-21 devnull * a superscript by default.
717 c42a1d3d 2006-02-21 devnull Bprint(&bout, "<sup>");
718 c42a1d3d 2006-02-21 devnull Brune(r);
719 c42a1d3d 2006-02-21 devnull Bprint(&bout, "</sup>");
722 c42a1d3d 2006-02-21 devnull Brune(r);
726 c42a1d3d 2006-02-21 devnull r_nop(int argc, Rune **argv)
728 c42a1d3d 2006-02-21 devnull USED(argc);
729 c42a1d3d 2006-02-21 devnull USED(argv);
733 c42a1d3d 2006-02-21 devnull r_warn(int argc, Rune **argv)
735 c42a1d3d 2006-02-21 devnull USED(argc);
736 c42a1d3d 2006-02-21 devnull warn("ignoring %C%S", dot, argv[0]);
740 c42a1d3d 2006-02-21 devnull e_warn(void)
742 c42a1d3d 2006-02-21 devnull /* dispatch loop prints a warning for us */
743 c42a1d3d 2006-02-21 devnull return 0;
747 c42a1d3d 2006-02-21 devnull e_nop(void)
749 c42a1d3d 2006-02-21 devnull return 0;