1*7dd7cddfSDavid du Colombier #include <u.h> 2*7dd7cddfSDavid du Colombier #include <libc.h> 3*7dd7cddfSDavid du Colombier #include <ctype.h> 4*7dd7cddfSDavid du Colombier #include <bio.h> 5*7dd7cddfSDavid du Colombier 6*7dd7cddfSDavid du Colombier enum 7*7dd7cddfSDavid du Colombier { 8*7dd7cddfSDavid du Colombier SSIZE = 10, 9*7dd7cddfSDavid du Colombier 10*7dd7cddfSDavid du Colombier /* list types */ 11*7dd7cddfSDavid du Colombier Lordered = 0, 12*7dd7cddfSDavid du Colombier Lunordered, 13*7dd7cddfSDavid du Colombier Lmenu, 14*7dd7cddfSDavid du Colombier Ldir, 15*7dd7cddfSDavid du Colombier 16*7dd7cddfSDavid du Colombier }; 17*7dd7cddfSDavid du Colombier 18*7dd7cddfSDavid du Colombier Biobuf in, out; 19*7dd7cddfSDavid du Colombier int lastc = '\n'; 20*7dd7cddfSDavid du Colombier int inpre = 0; 21*7dd7cddfSDavid du Colombier 22*7dd7cddfSDavid du Colombier /* stack for fonts */ 23*7dd7cddfSDavid du Colombier char *fontstack[SSIZE]; 24*7dd7cddfSDavid du Colombier char *font = "R"; 25*7dd7cddfSDavid du Colombier int fsp; 26*7dd7cddfSDavid du Colombier 27*7dd7cddfSDavid du Colombier /* stack for lists */ 28*7dd7cddfSDavid du Colombier struct 29*7dd7cddfSDavid du Colombier { 30*7dd7cddfSDavid du Colombier int type; 31*7dd7cddfSDavid du Colombier int ord; 32*7dd7cddfSDavid du Colombier } liststack[SSIZE]; 33*7dd7cddfSDavid du Colombier int lsp; 34*7dd7cddfSDavid du Colombier 35*7dd7cddfSDavid du Colombier int quoting; 36*7dd7cddfSDavid du Colombier 37*7dd7cddfSDavid du Colombier typedef struct Goobie Goobie; 38*7dd7cddfSDavid du Colombier struct Goobie 39*7dd7cddfSDavid du Colombier { 40*7dd7cddfSDavid du Colombier char *name; 41*7dd7cddfSDavid du Colombier void (*f)(Goobie*, char*); 42*7dd7cddfSDavid du Colombier void (*ef)(Goobie*, char*); 43*7dd7cddfSDavid du Colombier }; 44*7dd7cddfSDavid du Colombier 45*7dd7cddfSDavid du Colombier void eatwhite(void); 46*7dd7cddfSDavid du Colombier void escape(void); 47*7dd7cddfSDavid du Colombier 48*7dd7cddfSDavid du Colombier typedef void Action(Goobie*, char*); 49*7dd7cddfSDavid du Colombier 50*7dd7cddfSDavid du Colombier Action g_ignore; 51*7dd7cddfSDavid du Colombier Action g_unexpected; 52*7dd7cddfSDavid du Colombier Action g_title; 53*7dd7cddfSDavid du Colombier Action g_p; 54*7dd7cddfSDavid du Colombier Action g_h; 55*7dd7cddfSDavid du Colombier Action g_li; 56*7dd7cddfSDavid du Colombier Action g_list, g_listend; 57*7dd7cddfSDavid du Colombier Action g_pre; 58*7dd7cddfSDavid du Colombier Action g_fpush, g_fpop; 59*7dd7cddfSDavid du Colombier Action g_indent, g_exdent; 60*7dd7cddfSDavid du Colombier Action g_dt; 61*7dd7cddfSDavid du Colombier Action g_display; 62*7dd7cddfSDavid du Colombier Action g_displayend; 63*7dd7cddfSDavid du Colombier Action g_table, g_tableend, g_caption, g_captionend; 64*7dd7cddfSDavid du Colombier Action g_br, g_hr; 65*7dd7cddfSDavid du Colombier 66*7dd7cddfSDavid du Colombier Goobie gtab[] = 67*7dd7cddfSDavid du Colombier { 68*7dd7cddfSDavid du Colombier "!--", g_ignore, g_unexpected, 69*7dd7cddfSDavid du Colombier "!doctype", g_ignore, g_unexpected, 70*7dd7cddfSDavid du Colombier "a", g_ignore, g_ignore, 71*7dd7cddfSDavid du Colombier "address", g_display, g_displayend, 72*7dd7cddfSDavid du Colombier "b", g_fpush, g_fpop, 73*7dd7cddfSDavid du Colombier "base", g_ignore, g_unexpected, 74*7dd7cddfSDavid du Colombier "blink", g_ignore, g_ignore, 75*7dd7cddfSDavid du Colombier "blockquote", g_ignore, g_ignore, 76*7dd7cddfSDavid du Colombier "body", g_ignore, g_ignore, 77*7dd7cddfSDavid du Colombier "br", g_br, g_unexpected, 78*7dd7cddfSDavid du Colombier "caption", g_caption, g_captionend, 79*7dd7cddfSDavid du Colombier "center", g_ignore, g_ignore, 80*7dd7cddfSDavid du Colombier "cite", g_ignore, g_ignore, 81*7dd7cddfSDavid du Colombier "code", g_ignore, g_ignore, 82*7dd7cddfSDavid du Colombier "dd", g_ignore, g_unexpected, 83*7dd7cddfSDavid du Colombier "dfn", g_ignore, g_ignore, 84*7dd7cddfSDavid du Colombier "dir", g_list, g_listend, 85*7dd7cddfSDavid du Colombier "dl", g_indent, g_exdent, 86*7dd7cddfSDavid du Colombier "dt", g_dt, g_unexpected, 87*7dd7cddfSDavid du Colombier "em", g_ignore, g_ignore, 88*7dd7cddfSDavid du Colombier "font", g_ignore, g_ignore, 89*7dd7cddfSDavid du Colombier "form", g_ignore, g_ignore, 90*7dd7cddfSDavid du Colombier "h1", g_h, g_p, 91*7dd7cddfSDavid du Colombier "h2", g_h, g_p, 92*7dd7cddfSDavid du Colombier "h3", g_h, g_p, 93*7dd7cddfSDavid du Colombier "h4", g_h, g_p, 94*7dd7cddfSDavid du Colombier "h5", g_h, g_p, 95*7dd7cddfSDavid du Colombier "h6", g_h, g_p, 96*7dd7cddfSDavid du Colombier "head", g_ignore, g_ignore, 97*7dd7cddfSDavid du Colombier "hr", g_hr, g_unexpected, 98*7dd7cddfSDavid du Colombier "html", g_ignore, g_ignore, 99*7dd7cddfSDavid du Colombier "i", g_fpush, g_fpop, 100*7dd7cddfSDavid du Colombier "input", g_ignore, g_unexpected, 101*7dd7cddfSDavid du Colombier "img", g_ignore, g_unexpected, 102*7dd7cddfSDavid du Colombier "isindex", g_ignore, g_unexpected, 103*7dd7cddfSDavid du Colombier "kbd", g_fpush, g_fpop, 104*7dd7cddfSDavid du Colombier "key", g_ignore, g_ignore, 105*7dd7cddfSDavid du Colombier "li", g_li, g_unexpected, 106*7dd7cddfSDavid du Colombier "link", g_ignore, g_unexpected, 107*7dd7cddfSDavid du Colombier "listing", g_ignore, g_ignore, 108*7dd7cddfSDavid du Colombier "menu", g_list, g_listend, 109*7dd7cddfSDavid du Colombier "meta", g_ignore, g_unexpected, 110*7dd7cddfSDavid du Colombier "nextid", g_ignore, g_unexpected, 111*7dd7cddfSDavid du Colombier "ol", g_list, g_listend, 112*7dd7cddfSDavid du Colombier "option", g_ignore, g_unexpected, 113*7dd7cddfSDavid du Colombier "p", g_p, g_ignore, 114*7dd7cddfSDavid du Colombier "plaintext", g_ignore, g_unexpected, 115*7dd7cddfSDavid du Colombier "pre", g_pre, g_displayend, 116*7dd7cddfSDavid du Colombier "samp", g_ignore, g_ignore, 117*7dd7cddfSDavid du Colombier "select", g_ignore, g_ignore, 118*7dd7cddfSDavid du Colombier "strong", g_ignore, g_ignore, 119*7dd7cddfSDavid du Colombier "table", g_table, g_tableend, 120*7dd7cddfSDavid du Colombier "textarea", g_ignore, g_ignore, 121*7dd7cddfSDavid du Colombier "title", g_title, g_ignore, 122*7dd7cddfSDavid du Colombier "tt", g_fpush, g_fpop, 123*7dd7cddfSDavid du Colombier "u", g_ignore, g_ignore, 124*7dd7cddfSDavid du Colombier "ul", g_list, g_listend, 125*7dd7cddfSDavid du Colombier "var", g_ignore, g_ignore, 126*7dd7cddfSDavid du Colombier "xmp", g_ignore, g_ignore, 127*7dd7cddfSDavid du Colombier 0, 0, 0, 128*7dd7cddfSDavid du Colombier }; 129*7dd7cddfSDavid du Colombier 130*7dd7cddfSDavid du Colombier typedef struct Entity Entity; 131*7dd7cddfSDavid du Colombier struct Entity 132*7dd7cddfSDavid du Colombier { 133*7dd7cddfSDavid du Colombier char *name; 134*7dd7cddfSDavid du Colombier Rune value; 135*7dd7cddfSDavid du Colombier }; 136*7dd7cddfSDavid du Colombier 137*7dd7cddfSDavid du Colombier Entity pl_entity[]= 138*7dd7cddfSDavid du Colombier { 139*7dd7cddfSDavid du Colombier "#SPACE", L' ', "#RS", L'\n', "#RE", L'\r', "quot", L'"', 140*7dd7cddfSDavid du Colombier "AElig", L'Æ', "Aacute", L'Á', "Acirc", L'Â', "Agrave", L'À', "Aring", L'Å', 141*7dd7cddfSDavid du Colombier "Atilde", L'Ã', "Auml", L'Ä', "Ccedil", L'Ç', "ETH", L'Ð', "Eacute", L'É', 142*7dd7cddfSDavid du Colombier "Ecirc", L'Ê', "Egrave", L'È', "Euml", L'Ë', "Iacute", L'Í', "Icirc", L'Î', 143*7dd7cddfSDavid du Colombier "Igrave", L'Ì', "Iuml", L'Ï', "Ntilde", L'Ñ', "Oacute", L'Ó', "Ocirc", L'Ô', 144*7dd7cddfSDavid du Colombier "Ograve", L'Ò', "Oslash", L'Ø', "Otilde", L'Õ', "Ouml", L'Ö', "THORN", L'Þ', 145*7dd7cddfSDavid du Colombier "Uacute", L'Ú', "Ucirc", L'Û', "Ugrave", L'Ù', "Uuml", L'Ü', "Yacute", L'Ý', 146*7dd7cddfSDavid du Colombier "aacute", L'á', "acirc", L'â', "aelig", L'æ', "agrave", L'à', "amp", L'&', 147*7dd7cddfSDavid du Colombier "aring", L'å', "atilde", L'ã', "auml", L'ä', "ccedil", L'ç', "eacute", L'é', 148*7dd7cddfSDavid du Colombier "ecirc", L'ê', "egrave", L'è', "eth", L'ð', "euml", L'ë', "gt", L'>', 149*7dd7cddfSDavid du Colombier "iacute", L'í', "icirc", L'î', "igrave", L'ì', "iuml", L'ï', "lt", L'<', 150*7dd7cddfSDavid du Colombier "ntilde", L'ñ', "oacute", L'ó', "ocirc", L'ô', "ograve", L'ò', "oslash", L'ø', 151*7dd7cddfSDavid du Colombier "otilde", L'õ', "ouml", L'ö', "szlig", L'ß', "thorn", L'þ', "uacute", L'ú', 152*7dd7cddfSDavid du Colombier "ucirc", L'û', "ugrave", L'ù', "uuml", L'ü', "yacute", L'ý', "yuml", L'ÿ', 153*7dd7cddfSDavid du Colombier 0 154*7dd7cddfSDavid du Colombier }; 155*7dd7cddfSDavid du Colombier 156*7dd7cddfSDavid du Colombier int 157*7dd7cddfSDavid du Colombier cistrcmp(char *a, char *b) 158*7dd7cddfSDavid du Colombier { 159*7dd7cddfSDavid du Colombier int c, d; 160*7dd7cddfSDavid du Colombier 161*7dd7cddfSDavid du Colombier for(;; a++, b++){ 162*7dd7cddfSDavid du Colombier d = tolower(*a); 163*7dd7cddfSDavid du Colombier c = d - tolower(*b); 164*7dd7cddfSDavid du Colombier if(c) 165*7dd7cddfSDavid du Colombier break; 166*7dd7cddfSDavid du Colombier if(d == 0) 167*7dd7cddfSDavid du Colombier break; 168*7dd7cddfSDavid du Colombier } 169*7dd7cddfSDavid du Colombier return c; 170*7dd7cddfSDavid du Colombier } 171*7dd7cddfSDavid du Colombier 172*7dd7cddfSDavid du Colombier int 173*7dd7cddfSDavid du Colombier readupto(char *buf, int n, char d, char notme) 174*7dd7cddfSDavid du Colombier { 175*7dd7cddfSDavid du Colombier char *p; 176*7dd7cddfSDavid du Colombier int c; 177*7dd7cddfSDavid du Colombier 178*7dd7cddfSDavid du Colombier buf[0] = 0; 179*7dd7cddfSDavid du Colombier for(p = buf;; p++){ 180*7dd7cddfSDavid du Colombier c = Bgetc(&in); 181*7dd7cddfSDavid du Colombier if(c < 0){ 182*7dd7cddfSDavid du Colombier *p = 0; 183*7dd7cddfSDavid du Colombier return -1; 184*7dd7cddfSDavid du Colombier } 185*7dd7cddfSDavid du Colombier if(c == notme){ 186*7dd7cddfSDavid du Colombier Bungetc(&in); 187*7dd7cddfSDavid du Colombier return -1; 188*7dd7cddfSDavid du Colombier } 189*7dd7cddfSDavid du Colombier if(c == d){ 190*7dd7cddfSDavid du Colombier *p = 0; 191*7dd7cddfSDavid du Colombier return 0; 192*7dd7cddfSDavid du Colombier } 193*7dd7cddfSDavid du Colombier *p = c; 194*7dd7cddfSDavid du Colombier if(p == buf + n){ 195*7dd7cddfSDavid du Colombier *p = 0; 196*7dd7cddfSDavid du Colombier Bprint(&out, "<%s", buf); 197*7dd7cddfSDavid du Colombier return -1; 198*7dd7cddfSDavid du Colombier } 199*7dd7cddfSDavid du Colombier } 200*7dd7cddfSDavid du Colombier } 201*7dd7cddfSDavid du Colombier 202*7dd7cddfSDavid du Colombier void 203*7dd7cddfSDavid du Colombier dogoobie(void) 204*7dd7cddfSDavid du Colombier { 205*7dd7cddfSDavid du Colombier char *arg, *type; 206*7dd7cddfSDavid du Colombier Goobie *g; 207*7dd7cddfSDavid du Colombier char buf[1024]; 208*7dd7cddfSDavid du Colombier int closing; 209*7dd7cddfSDavid du Colombier 210*7dd7cddfSDavid du Colombier if(readupto(buf, sizeof(buf), '>', '<') < 0){ 211*7dd7cddfSDavid du Colombier Bprint(&out, "<%s", buf); 212*7dd7cddfSDavid du Colombier return; 213*7dd7cddfSDavid du Colombier } 214*7dd7cddfSDavid du Colombier type = buf; 215*7dd7cddfSDavid du Colombier if(*type == '/'){ 216*7dd7cddfSDavid du Colombier type++; 217*7dd7cddfSDavid du Colombier closing = 1; 218*7dd7cddfSDavid du Colombier } else 219*7dd7cddfSDavid du Colombier closing = 0; 220*7dd7cddfSDavid du Colombier arg = strchr(type, ' '); 221*7dd7cddfSDavid du Colombier if(arg == 0) 222*7dd7cddfSDavid du Colombier arg = strchr(type, '\r'); 223*7dd7cddfSDavid du Colombier if(arg == 0) 224*7dd7cddfSDavid du Colombier arg = strchr(type, '\n'); 225*7dd7cddfSDavid du Colombier if(arg) 226*7dd7cddfSDavid du Colombier *arg++ = 0; 227*7dd7cddfSDavid du Colombier for(g = gtab; g->name; g++) 228*7dd7cddfSDavid du Colombier if(cistrcmp(type, g->name) == 0){ 229*7dd7cddfSDavid du Colombier if(closing){ 230*7dd7cddfSDavid du Colombier if(g->ef){ 231*7dd7cddfSDavid du Colombier (*g->ef)(g, arg); 232*7dd7cddfSDavid du Colombier return; 233*7dd7cddfSDavid du Colombier } 234*7dd7cddfSDavid du Colombier } else { 235*7dd7cddfSDavid du Colombier if(g->f){ 236*7dd7cddfSDavid du Colombier (*g->f)(g, arg); 237*7dd7cddfSDavid du Colombier return; 238*7dd7cddfSDavid du Colombier } 239*7dd7cddfSDavid du Colombier } 240*7dd7cddfSDavid du Colombier } 241*7dd7cddfSDavid du Colombier if(closing) 242*7dd7cddfSDavid du Colombier type--; 243*7dd7cddfSDavid du Colombier if(arg) 244*7dd7cddfSDavid du Colombier Bprint(&out, "<%s %s>\n", type, arg); 245*7dd7cddfSDavid du Colombier else 246*7dd7cddfSDavid du Colombier Bprint(&out, "<%s>\n", type); 247*7dd7cddfSDavid du Colombier } 248*7dd7cddfSDavid du Colombier 249*7dd7cddfSDavid du Colombier void 250*7dd7cddfSDavid du Colombier main(void) 251*7dd7cddfSDavid du Colombier { 252*7dd7cddfSDavid du Colombier int c; 253*7dd7cddfSDavid du Colombier 254*7dd7cddfSDavid du Colombier Binit(&in, 0, OREAD); 255*7dd7cddfSDavid du Colombier Binit(&out, 1, OWRITE); 256*7dd7cddfSDavid du Colombier 257*7dd7cddfSDavid du Colombier for(;;){ 258*7dd7cddfSDavid du Colombier c = Bgetc(&in); 259*7dd7cddfSDavid du Colombier if(c < 0) 260*7dd7cddfSDavid du Colombier return; 261*7dd7cddfSDavid du Colombier switch(c){ 262*7dd7cddfSDavid du Colombier case '<': 263*7dd7cddfSDavid du Colombier dogoobie(); 264*7dd7cddfSDavid du Colombier break; 265*7dd7cddfSDavid du Colombier case '&': 266*7dd7cddfSDavid du Colombier escape(); 267*7dd7cddfSDavid du Colombier break; 268*7dd7cddfSDavid du Colombier case '\r': 269*7dd7cddfSDavid du Colombier break; 270*7dd7cddfSDavid du Colombier case '\n': 271*7dd7cddfSDavid du Colombier if(quoting){ 272*7dd7cddfSDavid du Colombier Bputc(&out, '"'); 273*7dd7cddfSDavid du Colombier quoting = 0; 274*7dd7cddfSDavid du Colombier } 275*7dd7cddfSDavid du Colombier if(lastc != '\n') 276*7dd7cddfSDavid du Colombier Bputc(&out, '\n'); 277*7dd7cddfSDavid du Colombier /* can't emit leading spaces in filled troff docs */ 278*7dd7cddfSDavid du Colombier if (!inpre) 279*7dd7cddfSDavid du Colombier eatwhite(); 280*7dd7cddfSDavid du Colombier lastc = c; 281*7dd7cddfSDavid du Colombier break; 282*7dd7cddfSDavid du Colombier default: 283*7dd7cddfSDavid du Colombier Bputc(&out, c); 284*7dd7cddfSDavid du Colombier lastc = c; 285*7dd7cddfSDavid du Colombier break; 286*7dd7cddfSDavid du Colombier } 287*7dd7cddfSDavid du Colombier } 288*7dd7cddfSDavid du Colombier } 289*7dd7cddfSDavid du Colombier 290*7dd7cddfSDavid du Colombier void 291*7dd7cddfSDavid du Colombier escape(void) 292*7dd7cddfSDavid du Colombier { 293*7dd7cddfSDavid du Colombier Entity *e; 294*7dd7cddfSDavid du Colombier char buf[8]; 295*7dd7cddfSDavid du Colombier 296*7dd7cddfSDavid du Colombier if(readupto(buf, sizeof(buf), ';', '\n') < 0){ 297*7dd7cddfSDavid du Colombier Bprint(&out, "&%s", buf); 298*7dd7cddfSDavid du Colombier return; 299*7dd7cddfSDavid du Colombier } 300*7dd7cddfSDavid du Colombier for(e = pl_entity; e->name; e++) 301*7dd7cddfSDavid du Colombier if(strcmp(buf, e->name) == 0){ 302*7dd7cddfSDavid du Colombier Bprint(&out, "%C", e->value); 303*7dd7cddfSDavid du Colombier return; 304*7dd7cddfSDavid du Colombier } 305*7dd7cddfSDavid du Colombier Bprint(&out, "&%s;", buf); 306*7dd7cddfSDavid du Colombier } 307*7dd7cddfSDavid du Colombier 308*7dd7cddfSDavid du Colombier /* 309*7dd7cddfSDavid du Colombier * whitespace is not significant to HTML, but newlines 310*7dd7cddfSDavid du Colombier * and leading spaces are significant to troff. 311*7dd7cddfSDavid du Colombier */ 312*7dd7cddfSDavid du Colombier void 313*7dd7cddfSDavid du Colombier eatwhite(void) 314*7dd7cddfSDavid du Colombier { 315*7dd7cddfSDavid du Colombier int c; 316*7dd7cddfSDavid du Colombier 317*7dd7cddfSDavid du Colombier for(;;){ 318*7dd7cddfSDavid du Colombier c = Bgetc(&in); 319*7dd7cddfSDavid du Colombier if(c < 0) 320*7dd7cddfSDavid du Colombier break; 321*7dd7cddfSDavid du Colombier if(!isspace(c)){ 322*7dd7cddfSDavid du Colombier Bungetc(&in); 323*7dd7cddfSDavid du Colombier break; 324*7dd7cddfSDavid du Colombier } 325*7dd7cddfSDavid du Colombier } 326*7dd7cddfSDavid du Colombier } 327*7dd7cddfSDavid du Colombier 328*7dd7cddfSDavid du Colombier /* 329*7dd7cddfSDavid du Colombier * print at start of line 330*7dd7cddfSDavid du Colombier */ 331*7dd7cddfSDavid du Colombier void 332*7dd7cddfSDavid du Colombier printsol(char *fmt, ...) 333*7dd7cddfSDavid du Colombier { 334*7dd7cddfSDavid du Colombier char buf[8*1024], *s; 335*7dd7cddfSDavid du Colombier va_list arg; 336*7dd7cddfSDavid du Colombier 337*7dd7cddfSDavid du Colombier if(quoting){ 338*7dd7cddfSDavid du Colombier Bputc(&out, '"'); 339*7dd7cddfSDavid du Colombier quoting = 0; 340*7dd7cddfSDavid du Colombier } 341*7dd7cddfSDavid du Colombier if(lastc != '\n') 342*7dd7cddfSDavid du Colombier Bputc(&out, '\n'); 343*7dd7cddfSDavid du Colombier va_start(arg, fmt); 344*7dd7cddfSDavid du Colombier s = doprint(buf, buf + (sizeof(buf)-1) / sizeof(*buf), fmt, arg); 345*7dd7cddfSDavid du Colombier va_end(arg); 346*7dd7cddfSDavid du Colombier Bwrite(&out, buf, s-buf); 347*7dd7cddfSDavid du Colombier lastc = *(s-1); 348*7dd7cddfSDavid du Colombier } 349*7dd7cddfSDavid du Colombier 350*7dd7cddfSDavid du Colombier void 351*7dd7cddfSDavid du Colombier g_ignore(Goobie *g, char *arg) 352*7dd7cddfSDavid du Colombier { 353*7dd7cddfSDavid du Colombier USED(g, arg); 354*7dd7cddfSDavid du Colombier } 355*7dd7cddfSDavid du Colombier 356*7dd7cddfSDavid du Colombier void 357*7dd7cddfSDavid du Colombier g_unexpected(Goobie *g, char *arg) 358*7dd7cddfSDavid du Colombier { 359*7dd7cddfSDavid du Colombier USED(arg); 360*7dd7cddfSDavid du Colombier fprint(2, "unexpected %s ending\n", g->name); 361*7dd7cddfSDavid du Colombier } 362*7dd7cddfSDavid du Colombier 363*7dd7cddfSDavid du Colombier void 364*7dd7cddfSDavid du Colombier g_title(Goobie *g, char *arg) 365*7dd7cddfSDavid du Colombier { 366*7dd7cddfSDavid du Colombier USED(arg); 367*7dd7cddfSDavid du Colombier printsol(".TL\n", g->name); 368*7dd7cddfSDavid du Colombier } 369*7dd7cddfSDavid du Colombier 370*7dd7cddfSDavid du Colombier void 371*7dd7cddfSDavid du Colombier g_p(Goobie *g, char *arg) 372*7dd7cddfSDavid du Colombier { 373*7dd7cddfSDavid du Colombier USED(arg); 374*7dd7cddfSDavid du Colombier printsol(".LP\n", g->name); 375*7dd7cddfSDavid du Colombier } 376*7dd7cddfSDavid du Colombier 377*7dd7cddfSDavid du Colombier void 378*7dd7cddfSDavid du Colombier g_h(Goobie *g, char *arg) 379*7dd7cddfSDavid du Colombier { 380*7dd7cddfSDavid du Colombier USED(arg); 381*7dd7cddfSDavid du Colombier printsol(".SH %c\n", g->name[1]); 382*7dd7cddfSDavid du Colombier } 383*7dd7cddfSDavid du Colombier 384*7dd7cddfSDavid du Colombier void 385*7dd7cddfSDavid du Colombier g_list(Goobie *g, char *arg) 386*7dd7cddfSDavid du Colombier { 387*7dd7cddfSDavid du Colombier USED(arg); 388*7dd7cddfSDavid du Colombier 389*7dd7cddfSDavid du Colombier if(lsp != SSIZE){ 390*7dd7cddfSDavid du Colombier switch(g->name[0]){ 391*7dd7cddfSDavid du Colombier case 'o': 392*7dd7cddfSDavid du Colombier liststack[lsp].type = Lordered; 393*7dd7cddfSDavid du Colombier liststack[lsp].ord = 0; 394*7dd7cddfSDavid du Colombier break; 395*7dd7cddfSDavid du Colombier default: 396*7dd7cddfSDavid du Colombier liststack[lsp].type = Lunordered; 397*7dd7cddfSDavid du Colombier break; 398*7dd7cddfSDavid du Colombier } 399*7dd7cddfSDavid du Colombier } 400*7dd7cddfSDavid du Colombier lsp++; 401*7dd7cddfSDavid du Colombier } 402*7dd7cddfSDavid du Colombier 403*7dd7cddfSDavid du Colombier void 404*7dd7cddfSDavid du Colombier g_br(Goobie *g, char *arg) 405*7dd7cddfSDavid du Colombier { 406*7dd7cddfSDavid du Colombier USED(g, arg); 407*7dd7cddfSDavid du Colombier printsol(".br\n"); 408*7dd7cddfSDavid du Colombier } 409*7dd7cddfSDavid du Colombier 410*7dd7cddfSDavid du Colombier void 411*7dd7cddfSDavid du Colombier g_li(Goobie *g, char *arg) 412*7dd7cddfSDavid du Colombier { 413*7dd7cddfSDavid du Colombier USED(g, arg); 414*7dd7cddfSDavid du Colombier if(lsp <= 0 || lsp > SSIZE){ 415*7dd7cddfSDavid du Colombier printsol(".IP \\(bu\n"); 416*7dd7cddfSDavid du Colombier return; 417*7dd7cddfSDavid du Colombier } 418*7dd7cddfSDavid du Colombier switch(liststack[lsp-1].type){ 419*7dd7cddfSDavid du Colombier case Lunordered: 420*7dd7cddfSDavid du Colombier printsol(".IP \\(bu\n"); 421*7dd7cddfSDavid du Colombier break; 422*7dd7cddfSDavid du Colombier case Lordered: 423*7dd7cddfSDavid du Colombier printsol(".IP %d\n", ++liststack[lsp-1].ord); 424*7dd7cddfSDavid du Colombier break; 425*7dd7cddfSDavid du Colombier } 426*7dd7cddfSDavid du Colombier } 427*7dd7cddfSDavid du Colombier 428*7dd7cddfSDavid du Colombier void 429*7dd7cddfSDavid du Colombier g_listend(Goobie *g, char *arg) 430*7dd7cddfSDavid du Colombier { 431*7dd7cddfSDavid du Colombier USED(g, arg); 432*7dd7cddfSDavid du Colombier if(--lsp < 0) 433*7dd7cddfSDavid du Colombier lsp = 0; 434*7dd7cddfSDavid du Colombier printsol(".LP\n"); 435*7dd7cddfSDavid du Colombier } 436*7dd7cddfSDavid du Colombier 437*7dd7cddfSDavid du Colombier void 438*7dd7cddfSDavid du Colombier g_display(Goobie *g, char *arg) 439*7dd7cddfSDavid du Colombier { 440*7dd7cddfSDavid du Colombier USED(g, arg); 441*7dd7cddfSDavid du Colombier printsol(".DS\n"); 442*7dd7cddfSDavid du Colombier } 443*7dd7cddfSDavid du Colombier 444*7dd7cddfSDavid du Colombier void 445*7dd7cddfSDavid du Colombier g_pre(Goobie *g, char *arg) 446*7dd7cddfSDavid du Colombier { 447*7dd7cddfSDavid du Colombier USED(g, arg); 448*7dd7cddfSDavid du Colombier printsol(".DS L\n"); 449*7dd7cddfSDavid du Colombier inpre = 1; 450*7dd7cddfSDavid du Colombier } 451*7dd7cddfSDavid du Colombier 452*7dd7cddfSDavid du Colombier void 453*7dd7cddfSDavid du Colombier g_displayend(Goobie *g, char *arg) 454*7dd7cddfSDavid du Colombier { 455*7dd7cddfSDavid du Colombier USED(g, arg); 456*7dd7cddfSDavid du Colombier printsol(".DE\n"); 457*7dd7cddfSDavid du Colombier inpre = 0; 458*7dd7cddfSDavid du Colombier } 459*7dd7cddfSDavid du Colombier 460*7dd7cddfSDavid du Colombier void 461*7dd7cddfSDavid du Colombier g_fpush(Goobie *g, char *arg) 462*7dd7cddfSDavid du Colombier { 463*7dd7cddfSDavid du Colombier USED(arg); 464*7dd7cddfSDavid du Colombier if(fsp < SSIZE) 465*7dd7cddfSDavid du Colombier fontstack[fsp] = font; 466*7dd7cddfSDavid du Colombier fsp++; 467*7dd7cddfSDavid du Colombier switch(g->name[0]){ 468*7dd7cddfSDavid du Colombier case 'b': 469*7dd7cddfSDavid du Colombier font = "B"; 470*7dd7cddfSDavid du Colombier break; 471*7dd7cddfSDavid du Colombier case 'i': 472*7dd7cddfSDavid du Colombier font = "I"; 473*7dd7cddfSDavid du Colombier break; 474*7dd7cddfSDavid du Colombier case 'k': /* kbd */ 475*7dd7cddfSDavid du Colombier case 't': /* tt */ 476*7dd7cddfSDavid du Colombier font = "(CW"; 477*7dd7cddfSDavid du Colombier break; 478*7dd7cddfSDavid du Colombier } 479*7dd7cddfSDavid du Colombier Bprint(&out, "\\f%s", font); 480*7dd7cddfSDavid du Colombier } 481*7dd7cddfSDavid du Colombier 482*7dd7cddfSDavid du Colombier void 483*7dd7cddfSDavid du Colombier g_fpop(Goobie *g, char *arg) 484*7dd7cddfSDavid du Colombier { 485*7dd7cddfSDavid du Colombier USED(g, arg); 486*7dd7cddfSDavid du Colombier fsp--; 487*7dd7cddfSDavid du Colombier if(fsp < SSIZE) 488*7dd7cddfSDavid du Colombier font = fontstack[fsp]; 489*7dd7cddfSDavid du Colombier else 490*7dd7cddfSDavid du Colombier font = "R"; 491*7dd7cddfSDavid du Colombier 492*7dd7cddfSDavid du Colombier Bprint(&out, "\\f%s", font); 493*7dd7cddfSDavid du Colombier } 494*7dd7cddfSDavid du Colombier 495*7dd7cddfSDavid du Colombier void 496*7dd7cddfSDavid du Colombier g_indent(Goobie *g, char *arg) 497*7dd7cddfSDavid du Colombier { 498*7dd7cddfSDavid du Colombier USED(g, arg); 499*7dd7cddfSDavid du Colombier printsol(".RS\n"); 500*7dd7cddfSDavid du Colombier } 501*7dd7cddfSDavid du Colombier 502*7dd7cddfSDavid du Colombier void 503*7dd7cddfSDavid du Colombier g_exdent(Goobie *g, char *arg) 504*7dd7cddfSDavid du Colombier { 505*7dd7cddfSDavid du Colombier USED(g, arg); 506*7dd7cddfSDavid du Colombier printsol(".RE\n"); 507*7dd7cddfSDavid du Colombier } 508*7dd7cddfSDavid du Colombier 509*7dd7cddfSDavid du Colombier void 510*7dd7cddfSDavid du Colombier g_dt(Goobie *g, char *arg) 511*7dd7cddfSDavid du Colombier { 512*7dd7cddfSDavid du Colombier USED(g, arg); 513*7dd7cddfSDavid du Colombier printsol(".IP \""); 514*7dd7cddfSDavid du Colombier quoting = 1; 515*7dd7cddfSDavid du Colombier } 516*7dd7cddfSDavid du Colombier 517*7dd7cddfSDavid du Colombier void 518*7dd7cddfSDavid du Colombier g_hr(Goobie *g, char *arg) 519*7dd7cddfSDavid du Colombier { 520*7dd7cddfSDavid du Colombier USED(g, arg); 521*7dd7cddfSDavid du Colombier printsol(".br\n"); 522*7dd7cddfSDavid du Colombier printsol("\\l'5i'\n"); 523*7dd7cddfSDavid du Colombier } 524*7dd7cddfSDavid du Colombier 525*7dd7cddfSDavid du Colombier 526*7dd7cddfSDavid du Colombier /* 527*7dd7cddfSDavid du Colombier <table border> 528*7dd7cddfSDavid du Colombier <caption><font size="+1"><b>Cumulative Class Data</b></font></caption> 529*7dd7cddfSDavid du Colombier <tr><th rowspan=2>DOSE<br>mg/kg</th><th colspan=2>PARALYSIS</th><th colspan=2>DEATH</th> 530*7dd7cddfSDavid du Colombier </tr> 531*7dd7cddfSDavid du Colombier <tr><th width=80>Number</th><th width=80>Percent</th><th width=80>Number</th><th width=80>Percent</th> 532*7dd7cddfSDavid du Colombier </tr> 533*7dd7cddfSDavid du Colombier <tr align=center> 534*7dd7cddfSDavid du Colombier <td>0.1</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 535*7dd7cddfSDavid du Colombier </tr> 536*7dd7cddfSDavid du Colombier <tr align=center> 537*7dd7cddfSDavid du Colombier <td>0.2</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 538*7dd7cddfSDavid du Colombier </tr> 539*7dd7cddfSDavid du Colombier <tr align=center> 540*7dd7cddfSDavid du Colombier <td>0.3</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 541*7dd7cddfSDavid du Colombier </tr> 542*7dd7cddfSDavid du Colombier <tr align=center> 543*7dd7cddfSDavid du Colombier <td>0.4</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 544*7dd7cddfSDavid du Colombier </tr> 545*7dd7cddfSDavid du Colombier <tr align=center> 546*7dd7cddfSDavid du Colombier <td>0.5</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 547*7dd7cddfSDavid du Colombier </tr> 548*7dd7cddfSDavid du Colombier <tr align=center> 549*7dd7cddfSDavid du Colombier <td>0.6</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 550*7dd7cddfSDavid du Colombier </tr> 551*7dd7cddfSDavid du Colombier <tr align=center> 552*7dd7cddfSDavid du Colombier <td>0.7</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 553*7dd7cddfSDavid du Colombier </tr> 554*7dd7cddfSDavid du Colombier <tr align=center> 555*7dd7cddfSDavid du Colombier <td>0.8</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 556*7dd7cddfSDavid du Colombier </tr> 557*7dd7cddfSDavid du Colombier <tr align=center> 558*7dd7cddfSDavid du Colombier <td>0.8 oral</td><td><br></td> <td><br></td> <td><br></td> <td><br></td> 559*7dd7cddfSDavid du Colombier </tr> 560*7dd7cddfSDavid du Colombier </table> 561*7dd7cddfSDavid du Colombier */ 562*7dd7cddfSDavid du Colombier 563*7dd7cddfSDavid du Colombier void 564*7dd7cddfSDavid du Colombier g_table(Goobie *g, char *arg) 565*7dd7cddfSDavid du Colombier { 566*7dd7cddfSDavid du Colombier USED(g, arg); 567*7dd7cddfSDavid du Colombier printsol(".TS\ncenter ;\n"); 568*7dd7cddfSDavid du Colombier } 569*7dd7cddfSDavid du Colombier 570*7dd7cddfSDavid du Colombier void 571*7dd7cddfSDavid du Colombier g_tableend(Goobie *g, char *arg) 572*7dd7cddfSDavid du Colombier { 573*7dd7cddfSDavid du Colombier USED(g, arg); 574*7dd7cddfSDavid du Colombier printsol(".TE\n"); 575*7dd7cddfSDavid du Colombier } 576*7dd7cddfSDavid du Colombier 577*7dd7cddfSDavid du Colombier void 578*7dd7cddfSDavid du Colombier g_caption(Goobie *g, char *arg) 579*7dd7cddfSDavid du Colombier { 580*7dd7cddfSDavid du Colombier USED(g, arg); 581*7dd7cddfSDavid du Colombier } 582*7dd7cddfSDavid du Colombier 583*7dd7cddfSDavid du Colombier void 584*7dd7cddfSDavid du Colombier g_captionend(Goobie *g, char *arg) 585*7dd7cddfSDavid du Colombier { 586*7dd7cddfSDavid du Colombier USED(g, arg); 587*7dd7cddfSDavid du Colombier } 588