1*95c635efSGarrett D'Amore /* $Id: man_html.c,v 1.86 2012/01/03 15:16:24 kristaps Exp $ */ 2*95c635efSGarrett D'Amore /* 3*95c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*95c635efSGarrett D'Amore * 5*95c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 6*95c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 7*95c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 8*95c635efSGarrett D'Amore * 9*95c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*95c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*95c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*95c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*95c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*95c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*95c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*95c635efSGarrett D'Amore */ 17*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 18*95c635efSGarrett D'Amore #include "config.h" 19*95c635efSGarrett D'Amore #endif 20*95c635efSGarrett D'Amore 21*95c635efSGarrett D'Amore #include <sys/types.h> 22*95c635efSGarrett D'Amore 23*95c635efSGarrett D'Amore #include <assert.h> 24*95c635efSGarrett D'Amore #include <ctype.h> 25*95c635efSGarrett D'Amore #include <stdio.h> 26*95c635efSGarrett D'Amore #include <stdlib.h> 27*95c635efSGarrett D'Amore #include <string.h> 28*95c635efSGarrett D'Amore 29*95c635efSGarrett D'Amore #include "mandoc.h" 30*95c635efSGarrett D'Amore #include "out.h" 31*95c635efSGarrett D'Amore #include "html.h" 32*95c635efSGarrett D'Amore #include "man.h" 33*95c635efSGarrett D'Amore #include "main.h" 34*95c635efSGarrett D'Amore 35*95c635efSGarrett D'Amore /* TODO: preserve ident widths. */ 36*95c635efSGarrett D'Amore /* FIXME: have PD set the default vspace width. */ 37*95c635efSGarrett D'Amore 38*95c635efSGarrett D'Amore #define INDENT 5 39*95c635efSGarrett D'Amore 40*95c635efSGarrett D'Amore #define MAN_ARGS const struct man_meta *m, \ 41*95c635efSGarrett D'Amore const struct man_node *n, \ 42*95c635efSGarrett D'Amore struct mhtml *mh, \ 43*95c635efSGarrett D'Amore struct html *h 44*95c635efSGarrett D'Amore 45*95c635efSGarrett D'Amore struct mhtml { 46*95c635efSGarrett D'Amore int fl; 47*95c635efSGarrett D'Amore #define MANH_LITERAL (1 << 0) /* literal context */ 48*95c635efSGarrett D'Amore }; 49*95c635efSGarrett D'Amore 50*95c635efSGarrett D'Amore struct htmlman { 51*95c635efSGarrett D'Amore int (*pre)(MAN_ARGS); 52*95c635efSGarrett D'Amore int (*post)(MAN_ARGS); 53*95c635efSGarrett D'Amore }; 54*95c635efSGarrett D'Amore 55*95c635efSGarrett D'Amore static void print_bvspace(struct html *, 56*95c635efSGarrett D'Amore const struct man_node *); 57*95c635efSGarrett D'Amore static void print_man(MAN_ARGS); 58*95c635efSGarrett D'Amore static void print_man_head(MAN_ARGS); 59*95c635efSGarrett D'Amore static void print_man_nodelist(MAN_ARGS); 60*95c635efSGarrett D'Amore static void print_man_node(MAN_ARGS); 61*95c635efSGarrett D'Amore static int a2width(const struct man_node *, 62*95c635efSGarrett D'Amore struct roffsu *); 63*95c635efSGarrett D'Amore static int man_B_pre(MAN_ARGS); 64*95c635efSGarrett D'Amore static int man_HP_pre(MAN_ARGS); 65*95c635efSGarrett D'Amore static int man_IP_pre(MAN_ARGS); 66*95c635efSGarrett D'Amore static int man_I_pre(MAN_ARGS); 67*95c635efSGarrett D'Amore static int man_OP_pre(MAN_ARGS); 68*95c635efSGarrett D'Amore static int man_PP_pre(MAN_ARGS); 69*95c635efSGarrett D'Amore static int man_RS_pre(MAN_ARGS); 70*95c635efSGarrett D'Amore static int man_SH_pre(MAN_ARGS); 71*95c635efSGarrett D'Amore static int man_SM_pre(MAN_ARGS); 72*95c635efSGarrett D'Amore static int man_SS_pre(MAN_ARGS); 73*95c635efSGarrett D'Amore static int man_alt_pre(MAN_ARGS); 74*95c635efSGarrett D'Amore static int man_br_pre(MAN_ARGS); 75*95c635efSGarrett D'Amore static int man_ign_pre(MAN_ARGS); 76*95c635efSGarrett D'Amore static int man_in_pre(MAN_ARGS); 77*95c635efSGarrett D'Amore static int man_literal_pre(MAN_ARGS); 78*95c635efSGarrett D'Amore static void man_root_post(MAN_ARGS); 79*95c635efSGarrett D'Amore static void man_root_pre(MAN_ARGS); 80*95c635efSGarrett D'Amore 81*95c635efSGarrett D'Amore static const struct htmlman mans[MAN_MAX] = { 82*95c635efSGarrett D'Amore { man_br_pre, NULL }, /* br */ 83*95c635efSGarrett D'Amore { NULL, NULL }, /* TH */ 84*95c635efSGarrett D'Amore { man_SH_pre, NULL }, /* SH */ 85*95c635efSGarrett D'Amore { man_SS_pre, NULL }, /* SS */ 86*95c635efSGarrett D'Amore { man_IP_pre, NULL }, /* TP */ 87*95c635efSGarrett D'Amore { man_PP_pre, NULL }, /* LP */ 88*95c635efSGarrett D'Amore { man_PP_pre, NULL }, /* PP */ 89*95c635efSGarrett D'Amore { man_PP_pre, NULL }, /* P */ 90*95c635efSGarrett D'Amore { man_IP_pre, NULL }, /* IP */ 91*95c635efSGarrett D'Amore { man_HP_pre, NULL }, /* HP */ 92*95c635efSGarrett D'Amore { man_SM_pre, NULL }, /* SM */ 93*95c635efSGarrett D'Amore { man_SM_pre, NULL }, /* SB */ 94*95c635efSGarrett D'Amore { man_alt_pre, NULL }, /* BI */ 95*95c635efSGarrett D'Amore { man_alt_pre, NULL }, /* IB */ 96*95c635efSGarrett D'Amore { man_alt_pre, NULL }, /* BR */ 97*95c635efSGarrett D'Amore { man_alt_pre, NULL }, /* RB */ 98*95c635efSGarrett D'Amore { NULL, NULL }, /* R */ 99*95c635efSGarrett D'Amore { man_B_pre, NULL }, /* B */ 100*95c635efSGarrett D'Amore { man_I_pre, NULL }, /* I */ 101*95c635efSGarrett D'Amore { man_alt_pre, NULL }, /* IR */ 102*95c635efSGarrett D'Amore { man_alt_pre, NULL }, /* RI */ 103*95c635efSGarrett D'Amore { man_ign_pre, NULL }, /* na */ 104*95c635efSGarrett D'Amore { man_br_pre, NULL }, /* sp */ 105*95c635efSGarrett D'Amore { man_literal_pre, NULL }, /* nf */ 106*95c635efSGarrett D'Amore { man_literal_pre, NULL }, /* fi */ 107*95c635efSGarrett D'Amore { NULL, NULL }, /* RE */ 108*95c635efSGarrett D'Amore { man_RS_pre, NULL }, /* RS */ 109*95c635efSGarrett D'Amore { man_ign_pre, NULL }, /* DT */ 110*95c635efSGarrett D'Amore { man_ign_pre, NULL }, /* UC */ 111*95c635efSGarrett D'Amore { man_ign_pre, NULL }, /* PD */ 112*95c635efSGarrett D'Amore { man_ign_pre, NULL }, /* AT */ 113*95c635efSGarrett D'Amore { man_in_pre, NULL }, /* in */ 114*95c635efSGarrett D'Amore { man_ign_pre, NULL }, /* ft */ 115*95c635efSGarrett D'Amore { man_OP_pre, NULL }, /* OP */ 116*95c635efSGarrett D'Amore }; 117*95c635efSGarrett D'Amore 118*95c635efSGarrett D'Amore /* 119*95c635efSGarrett D'Amore * Printing leading vertical space before a block. 120*95c635efSGarrett D'Amore * This is used for the paragraph macros. 121*95c635efSGarrett D'Amore * The rules are pretty simple, since there's very little nesting going 122*95c635efSGarrett D'Amore * on here. Basically, if we're the first within another block (SS/SH), 123*95c635efSGarrett D'Amore * then don't emit vertical space. If we are (RS), then do. If not the 124*95c635efSGarrett D'Amore * first, print it. 125*95c635efSGarrett D'Amore */ 126*95c635efSGarrett D'Amore static void 127*95c635efSGarrett D'Amore print_bvspace(struct html *h, const struct man_node *n) 128*95c635efSGarrett D'Amore { 129*95c635efSGarrett D'Amore 130*95c635efSGarrett D'Amore if (n->body && n->body->child) 131*95c635efSGarrett D'Amore if (MAN_TBL == n->body->child->type) 132*95c635efSGarrett D'Amore return; 133*95c635efSGarrett D'Amore 134*95c635efSGarrett D'Amore if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) 135*95c635efSGarrett D'Amore if (NULL == n->prev) 136*95c635efSGarrett D'Amore return; 137*95c635efSGarrett D'Amore 138*95c635efSGarrett D'Amore print_otag(h, TAG_P, 0, NULL); 139*95c635efSGarrett D'Amore } 140*95c635efSGarrett D'Amore 141*95c635efSGarrett D'Amore void 142*95c635efSGarrett D'Amore html_man(void *arg, const struct man *m) 143*95c635efSGarrett D'Amore { 144*95c635efSGarrett D'Amore struct mhtml mh; 145*95c635efSGarrett D'Amore 146*95c635efSGarrett D'Amore memset(&mh, 0, sizeof(struct mhtml)); 147*95c635efSGarrett D'Amore print_man(man_meta(m), man_node(m), &mh, (struct html *)arg); 148*95c635efSGarrett D'Amore putchar('\n'); 149*95c635efSGarrett D'Amore } 150*95c635efSGarrett D'Amore 151*95c635efSGarrett D'Amore static void 152*95c635efSGarrett D'Amore print_man(MAN_ARGS) 153*95c635efSGarrett D'Amore { 154*95c635efSGarrett D'Amore struct tag *t, *tt; 155*95c635efSGarrett D'Amore struct htmlpair tag; 156*95c635efSGarrett D'Amore 157*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "mandoc"); 158*95c635efSGarrett D'Amore 159*95c635efSGarrett D'Amore if ( ! (HTML_FRAGMENT & h->oflags)) { 160*95c635efSGarrett D'Amore print_gen_decls(h); 161*95c635efSGarrett D'Amore t = print_otag(h, TAG_HTML, 0, NULL); 162*95c635efSGarrett D'Amore tt = print_otag(h, TAG_HEAD, 0, NULL); 163*95c635efSGarrett D'Amore print_man_head(m, n, mh, h); 164*95c635efSGarrett D'Amore print_tagq(h, tt); 165*95c635efSGarrett D'Amore print_otag(h, TAG_BODY, 0, NULL); 166*95c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 167*95c635efSGarrett D'Amore } else 168*95c635efSGarrett D'Amore t = print_otag(h, TAG_DIV, 1, &tag); 169*95c635efSGarrett D'Amore 170*95c635efSGarrett D'Amore print_man_nodelist(m, n, mh, h); 171*95c635efSGarrett D'Amore print_tagq(h, t); 172*95c635efSGarrett D'Amore } 173*95c635efSGarrett D'Amore 174*95c635efSGarrett D'Amore 175*95c635efSGarrett D'Amore /* ARGSUSED */ 176*95c635efSGarrett D'Amore static void 177*95c635efSGarrett D'Amore print_man_head(MAN_ARGS) 178*95c635efSGarrett D'Amore { 179*95c635efSGarrett D'Amore 180*95c635efSGarrett D'Amore print_gen_head(h); 181*95c635efSGarrett D'Amore assert(m->title); 182*95c635efSGarrett D'Amore assert(m->msec); 183*95c635efSGarrett D'Amore bufcat_fmt(h, "%s(%s)", m->title, m->msec); 184*95c635efSGarrett D'Amore print_otag(h, TAG_TITLE, 0, NULL); 185*95c635efSGarrett D'Amore print_text(h, h->buf); 186*95c635efSGarrett D'Amore } 187*95c635efSGarrett D'Amore 188*95c635efSGarrett D'Amore 189*95c635efSGarrett D'Amore static void 190*95c635efSGarrett D'Amore print_man_nodelist(MAN_ARGS) 191*95c635efSGarrett D'Amore { 192*95c635efSGarrett D'Amore 193*95c635efSGarrett D'Amore print_man_node(m, n, mh, h); 194*95c635efSGarrett D'Amore if (n->next) 195*95c635efSGarrett D'Amore print_man_nodelist(m, n->next, mh, h); 196*95c635efSGarrett D'Amore } 197*95c635efSGarrett D'Amore 198*95c635efSGarrett D'Amore 199*95c635efSGarrett D'Amore static void 200*95c635efSGarrett D'Amore print_man_node(MAN_ARGS) 201*95c635efSGarrett D'Amore { 202*95c635efSGarrett D'Amore int child; 203*95c635efSGarrett D'Amore struct tag *t; 204*95c635efSGarrett D'Amore 205*95c635efSGarrett D'Amore child = 1; 206*95c635efSGarrett D'Amore t = h->tags.head; 207*95c635efSGarrett D'Amore 208*95c635efSGarrett D'Amore switch (n->type) { 209*95c635efSGarrett D'Amore case (MAN_ROOT): 210*95c635efSGarrett D'Amore man_root_pre(m, n, mh, h); 211*95c635efSGarrett D'Amore break; 212*95c635efSGarrett D'Amore case (MAN_TEXT): 213*95c635efSGarrett D'Amore /* 214*95c635efSGarrett D'Amore * If we have a blank line, output a vertical space. 215*95c635efSGarrett D'Amore * If we have a space as the first character, break 216*95c635efSGarrett D'Amore * before printing the line's data. 217*95c635efSGarrett D'Amore */ 218*95c635efSGarrett D'Amore if ('\0' == *n->string) { 219*95c635efSGarrett D'Amore print_otag(h, TAG_P, 0, NULL); 220*95c635efSGarrett D'Amore return; 221*95c635efSGarrett D'Amore } 222*95c635efSGarrett D'Amore 223*95c635efSGarrett D'Amore if (' ' == *n->string && MAN_LINE & n->flags) 224*95c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 225*95c635efSGarrett D'Amore else if (MANH_LITERAL & mh->fl && n->prev) 226*95c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 227*95c635efSGarrett D'Amore 228*95c635efSGarrett D'Amore print_text(h, n->string); 229*95c635efSGarrett D'Amore return; 230*95c635efSGarrett D'Amore case (MAN_EQN): 231*95c635efSGarrett D'Amore print_eqn(h, n->eqn); 232*95c635efSGarrett D'Amore break; 233*95c635efSGarrett D'Amore case (MAN_TBL): 234*95c635efSGarrett D'Amore /* 235*95c635efSGarrett D'Amore * This will take care of initialising all of the table 236*95c635efSGarrett D'Amore * state data for the first table, then tearing it down 237*95c635efSGarrett D'Amore * for the last one. 238*95c635efSGarrett D'Amore */ 239*95c635efSGarrett D'Amore print_tbl(h, n->span); 240*95c635efSGarrett D'Amore return; 241*95c635efSGarrett D'Amore default: 242*95c635efSGarrett D'Amore /* 243*95c635efSGarrett D'Amore * Close out scope of font prior to opening a macro 244*95c635efSGarrett D'Amore * scope. 245*95c635efSGarrett D'Amore */ 246*95c635efSGarrett D'Amore if (HTMLFONT_NONE != h->metac) { 247*95c635efSGarrett D'Amore h->metal = h->metac; 248*95c635efSGarrett D'Amore h->metac = HTMLFONT_NONE; 249*95c635efSGarrett D'Amore } 250*95c635efSGarrett D'Amore 251*95c635efSGarrett D'Amore /* 252*95c635efSGarrett D'Amore * Close out the current table, if it's open, and unset 253*95c635efSGarrett D'Amore * the "meta" table state. This will be reopened on the 254*95c635efSGarrett D'Amore * next table element. 255*95c635efSGarrett D'Amore */ 256*95c635efSGarrett D'Amore if (h->tblt) { 257*95c635efSGarrett D'Amore print_tblclose(h); 258*95c635efSGarrett D'Amore t = h->tags.head; 259*95c635efSGarrett D'Amore } 260*95c635efSGarrett D'Amore if (mans[n->tok].pre) 261*95c635efSGarrett D'Amore child = (*mans[n->tok].pre)(m, n, mh, h); 262*95c635efSGarrett D'Amore break; 263*95c635efSGarrett D'Amore } 264*95c635efSGarrett D'Amore 265*95c635efSGarrett D'Amore if (child && n->child) 266*95c635efSGarrett D'Amore print_man_nodelist(m, n->child, mh, h); 267*95c635efSGarrett D'Amore 268*95c635efSGarrett D'Amore /* This will automatically close out any font scope. */ 269*95c635efSGarrett D'Amore print_stagq(h, t); 270*95c635efSGarrett D'Amore 271*95c635efSGarrett D'Amore switch (n->type) { 272*95c635efSGarrett D'Amore case (MAN_ROOT): 273*95c635efSGarrett D'Amore man_root_post(m, n, mh, h); 274*95c635efSGarrett D'Amore break; 275*95c635efSGarrett D'Amore case (MAN_EQN): 276*95c635efSGarrett D'Amore break; 277*95c635efSGarrett D'Amore default: 278*95c635efSGarrett D'Amore if (mans[n->tok].post) 279*95c635efSGarrett D'Amore (*mans[n->tok].post)(m, n, mh, h); 280*95c635efSGarrett D'Amore break; 281*95c635efSGarrett D'Amore } 282*95c635efSGarrett D'Amore } 283*95c635efSGarrett D'Amore 284*95c635efSGarrett D'Amore 285*95c635efSGarrett D'Amore static int 286*95c635efSGarrett D'Amore a2width(const struct man_node *n, struct roffsu *su) 287*95c635efSGarrett D'Amore { 288*95c635efSGarrett D'Amore 289*95c635efSGarrett D'Amore if (MAN_TEXT != n->type) 290*95c635efSGarrett D'Amore return(0); 291*95c635efSGarrett D'Amore if (a2roffsu(n->string, su, SCALE_BU)) 292*95c635efSGarrett D'Amore return(1); 293*95c635efSGarrett D'Amore 294*95c635efSGarrett D'Amore return(0); 295*95c635efSGarrett D'Amore } 296*95c635efSGarrett D'Amore 297*95c635efSGarrett D'Amore 298*95c635efSGarrett D'Amore /* ARGSUSED */ 299*95c635efSGarrett D'Amore static void 300*95c635efSGarrett D'Amore man_root_pre(MAN_ARGS) 301*95c635efSGarrett D'Amore { 302*95c635efSGarrett D'Amore struct htmlpair tag[3]; 303*95c635efSGarrett D'Amore struct tag *t, *tt; 304*95c635efSGarrett D'Amore char b[BUFSIZ], title[BUFSIZ]; 305*95c635efSGarrett D'Amore 306*95c635efSGarrett D'Amore b[0] = 0; 307*95c635efSGarrett D'Amore if (m->vol) 308*95c635efSGarrett D'Amore (void)strlcat(b, m->vol, BUFSIZ); 309*95c635efSGarrett D'Amore 310*95c635efSGarrett D'Amore assert(m->title); 311*95c635efSGarrett D'Amore assert(m->msec); 312*95c635efSGarrett D'Amore snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec); 313*95c635efSGarrett D'Amore 314*95c635efSGarrett D'Amore PAIR_SUMMARY_INIT(&tag[0], "Document Header"); 315*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[1], "head"); 316*95c635efSGarrett D'Amore PAIR_INIT(&tag[2], ATTR_WIDTH, "100%"); 317*95c635efSGarrett D'Amore t = print_otag(h, TAG_TABLE, 3, tag); 318*95c635efSGarrett D'Amore PAIR_INIT(&tag[0], ATTR_WIDTH, "30%"); 319*95c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 320*95c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 321*95c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 322*95c635efSGarrett D'Amore 323*95c635efSGarrett D'Amore print_otag(h, TAG_TBODY, 0, NULL); 324*95c635efSGarrett D'Amore 325*95c635efSGarrett D'Amore tt = print_otag(h, TAG_TR, 0, NULL); 326*95c635efSGarrett D'Amore 327*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "head-ltitle"); 328*95c635efSGarrett D'Amore print_otag(h, TAG_TD, 1, tag); 329*95c635efSGarrett D'Amore print_text(h, title); 330*95c635efSGarrett D'Amore print_stagq(h, tt); 331*95c635efSGarrett D'Amore 332*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "head-vol"); 333*95c635efSGarrett D'Amore PAIR_INIT(&tag[1], ATTR_ALIGN, "center"); 334*95c635efSGarrett D'Amore print_otag(h, TAG_TD, 2, tag); 335*95c635efSGarrett D'Amore print_text(h, b); 336*95c635efSGarrett D'Amore print_stagq(h, tt); 337*95c635efSGarrett D'Amore 338*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "head-rtitle"); 339*95c635efSGarrett D'Amore PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); 340*95c635efSGarrett D'Amore print_otag(h, TAG_TD, 2, tag); 341*95c635efSGarrett D'Amore print_text(h, title); 342*95c635efSGarrett D'Amore print_tagq(h, t); 343*95c635efSGarrett D'Amore } 344*95c635efSGarrett D'Amore 345*95c635efSGarrett D'Amore 346*95c635efSGarrett D'Amore /* ARGSUSED */ 347*95c635efSGarrett D'Amore static void 348*95c635efSGarrett D'Amore man_root_post(MAN_ARGS) 349*95c635efSGarrett D'Amore { 350*95c635efSGarrett D'Amore struct htmlpair tag[3]; 351*95c635efSGarrett D'Amore struct tag *t, *tt; 352*95c635efSGarrett D'Amore 353*95c635efSGarrett D'Amore PAIR_SUMMARY_INIT(&tag[0], "Document Footer"); 354*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[1], "foot"); 355*95c635efSGarrett D'Amore PAIR_INIT(&tag[2], ATTR_WIDTH, "100%"); 356*95c635efSGarrett D'Amore t = print_otag(h, TAG_TABLE, 3, tag); 357*95c635efSGarrett D'Amore PAIR_INIT(&tag[0], ATTR_WIDTH, "50%"); 358*95c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 359*95c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 360*95c635efSGarrett D'Amore 361*95c635efSGarrett D'Amore tt = print_otag(h, TAG_TR, 0, NULL); 362*95c635efSGarrett D'Amore 363*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "foot-date"); 364*95c635efSGarrett D'Amore print_otag(h, TAG_TD, 1, tag); 365*95c635efSGarrett D'Amore 366*95c635efSGarrett D'Amore assert(m->date); 367*95c635efSGarrett D'Amore print_text(h, m->date); 368*95c635efSGarrett D'Amore print_stagq(h, tt); 369*95c635efSGarrett D'Amore 370*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "foot-os"); 371*95c635efSGarrett D'Amore PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); 372*95c635efSGarrett D'Amore print_otag(h, TAG_TD, 2, tag); 373*95c635efSGarrett D'Amore 374*95c635efSGarrett D'Amore if (m->source) 375*95c635efSGarrett D'Amore print_text(h, m->source); 376*95c635efSGarrett D'Amore print_tagq(h, t); 377*95c635efSGarrett D'Amore } 378*95c635efSGarrett D'Amore 379*95c635efSGarrett D'Amore 380*95c635efSGarrett D'Amore /* ARGSUSED */ 381*95c635efSGarrett D'Amore static int 382*95c635efSGarrett D'Amore man_br_pre(MAN_ARGS) 383*95c635efSGarrett D'Amore { 384*95c635efSGarrett D'Amore struct roffsu su; 385*95c635efSGarrett D'Amore struct htmlpair tag; 386*95c635efSGarrett D'Amore 387*95c635efSGarrett D'Amore SCALE_VS_INIT(&su, 1); 388*95c635efSGarrett D'Amore 389*95c635efSGarrett D'Amore if (MAN_sp == n->tok) { 390*95c635efSGarrett D'Amore if (NULL != (n = n->child)) 391*95c635efSGarrett D'Amore if ( ! a2roffsu(n->string, &su, SCALE_VS)) 392*95c635efSGarrett D'Amore SCALE_VS_INIT(&su, atoi(n->string)); 393*95c635efSGarrett D'Amore } else 394*95c635efSGarrett D'Amore su.scale = 0; 395*95c635efSGarrett D'Amore 396*95c635efSGarrett D'Amore bufinit(h); 397*95c635efSGarrett D'Amore bufcat_su(h, "height", &su); 398*95c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 399*95c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 400*95c635efSGarrett D'Amore 401*95c635efSGarrett D'Amore /* So the div isn't empty: */ 402*95c635efSGarrett D'Amore print_text(h, "\\~"); 403*95c635efSGarrett D'Amore 404*95c635efSGarrett D'Amore return(0); 405*95c635efSGarrett D'Amore } 406*95c635efSGarrett D'Amore 407*95c635efSGarrett D'Amore /* ARGSUSED */ 408*95c635efSGarrett D'Amore static int 409*95c635efSGarrett D'Amore man_SH_pre(MAN_ARGS) 410*95c635efSGarrett D'Amore { 411*95c635efSGarrett D'Amore struct htmlpair tag; 412*95c635efSGarrett D'Amore 413*95c635efSGarrett D'Amore if (MAN_BLOCK == n->type) { 414*95c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 415*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "section"); 416*95c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 417*95c635efSGarrett D'Amore return(1); 418*95c635efSGarrett D'Amore } else if (MAN_BODY == n->type) 419*95c635efSGarrett D'Amore return(1); 420*95c635efSGarrett D'Amore 421*95c635efSGarrett D'Amore print_otag(h, TAG_H1, 0, NULL); 422*95c635efSGarrett D'Amore return(1); 423*95c635efSGarrett D'Amore } 424*95c635efSGarrett D'Amore 425*95c635efSGarrett D'Amore /* ARGSUSED */ 426*95c635efSGarrett D'Amore static int 427*95c635efSGarrett D'Amore man_alt_pre(MAN_ARGS) 428*95c635efSGarrett D'Amore { 429*95c635efSGarrett D'Amore const struct man_node *nn; 430*95c635efSGarrett D'Amore int i, savelit; 431*95c635efSGarrett D'Amore enum htmltag fp; 432*95c635efSGarrett D'Amore struct tag *t; 433*95c635efSGarrett D'Amore 434*95c635efSGarrett D'Amore if ((savelit = mh->fl & MANH_LITERAL)) 435*95c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 436*95c635efSGarrett D'Amore 437*95c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 438*95c635efSGarrett D'Amore 439*95c635efSGarrett D'Amore for (i = 0, nn = n->child; nn; nn = nn->next, i++) { 440*95c635efSGarrett D'Amore t = NULL; 441*95c635efSGarrett D'Amore switch (n->tok) { 442*95c635efSGarrett D'Amore case (MAN_BI): 443*95c635efSGarrett D'Amore fp = i % 2 ? TAG_I : TAG_B; 444*95c635efSGarrett D'Amore break; 445*95c635efSGarrett D'Amore case (MAN_IB): 446*95c635efSGarrett D'Amore fp = i % 2 ? TAG_B : TAG_I; 447*95c635efSGarrett D'Amore break; 448*95c635efSGarrett D'Amore case (MAN_RI): 449*95c635efSGarrett D'Amore fp = i % 2 ? TAG_I : TAG_MAX; 450*95c635efSGarrett D'Amore break; 451*95c635efSGarrett D'Amore case (MAN_IR): 452*95c635efSGarrett D'Amore fp = i % 2 ? TAG_MAX : TAG_I; 453*95c635efSGarrett D'Amore break; 454*95c635efSGarrett D'Amore case (MAN_BR): 455*95c635efSGarrett D'Amore fp = i % 2 ? TAG_MAX : TAG_B; 456*95c635efSGarrett D'Amore break; 457*95c635efSGarrett D'Amore case (MAN_RB): 458*95c635efSGarrett D'Amore fp = i % 2 ? TAG_B : TAG_MAX; 459*95c635efSGarrett D'Amore break; 460*95c635efSGarrett D'Amore default: 461*95c635efSGarrett D'Amore abort(); 462*95c635efSGarrett D'Amore /* NOTREACHED */ 463*95c635efSGarrett D'Amore } 464*95c635efSGarrett D'Amore 465*95c635efSGarrett D'Amore if (i) 466*95c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 467*95c635efSGarrett D'Amore 468*95c635efSGarrett D'Amore if (TAG_MAX != fp) 469*95c635efSGarrett D'Amore t = print_otag(h, fp, 0, NULL); 470*95c635efSGarrett D'Amore 471*95c635efSGarrett D'Amore print_man_node(m, nn, mh, h); 472*95c635efSGarrett D'Amore 473*95c635efSGarrett D'Amore if (t) 474*95c635efSGarrett D'Amore print_tagq(h, t); 475*95c635efSGarrett D'Amore } 476*95c635efSGarrett D'Amore 477*95c635efSGarrett D'Amore if (savelit) 478*95c635efSGarrett D'Amore mh->fl |= MANH_LITERAL; 479*95c635efSGarrett D'Amore 480*95c635efSGarrett D'Amore return(0); 481*95c635efSGarrett D'Amore } 482*95c635efSGarrett D'Amore 483*95c635efSGarrett D'Amore /* ARGSUSED */ 484*95c635efSGarrett D'Amore static int 485*95c635efSGarrett D'Amore man_SM_pre(MAN_ARGS) 486*95c635efSGarrett D'Amore { 487*95c635efSGarrett D'Amore 488*95c635efSGarrett D'Amore print_otag(h, TAG_SMALL, 0, NULL); 489*95c635efSGarrett D'Amore if (MAN_SB == n->tok) 490*95c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 491*95c635efSGarrett D'Amore return(1); 492*95c635efSGarrett D'Amore } 493*95c635efSGarrett D'Amore 494*95c635efSGarrett D'Amore /* ARGSUSED */ 495*95c635efSGarrett D'Amore static int 496*95c635efSGarrett D'Amore man_SS_pre(MAN_ARGS) 497*95c635efSGarrett D'Amore { 498*95c635efSGarrett D'Amore struct htmlpair tag; 499*95c635efSGarrett D'Amore 500*95c635efSGarrett D'Amore if (MAN_BLOCK == n->type) { 501*95c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 502*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "subsection"); 503*95c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 504*95c635efSGarrett D'Amore return(1); 505*95c635efSGarrett D'Amore } else if (MAN_BODY == n->type) 506*95c635efSGarrett D'Amore return(1); 507*95c635efSGarrett D'Amore 508*95c635efSGarrett D'Amore print_otag(h, TAG_H2, 0, NULL); 509*95c635efSGarrett D'Amore return(1); 510*95c635efSGarrett D'Amore } 511*95c635efSGarrett D'Amore 512*95c635efSGarrett D'Amore /* ARGSUSED */ 513*95c635efSGarrett D'Amore static int 514*95c635efSGarrett D'Amore man_PP_pre(MAN_ARGS) 515*95c635efSGarrett D'Amore { 516*95c635efSGarrett D'Amore 517*95c635efSGarrett D'Amore if (MAN_HEAD == n->type) 518*95c635efSGarrett D'Amore return(0); 519*95c635efSGarrett D'Amore else if (MAN_BLOCK == n->type) 520*95c635efSGarrett D'Amore print_bvspace(h, n); 521*95c635efSGarrett D'Amore 522*95c635efSGarrett D'Amore return(1); 523*95c635efSGarrett D'Amore } 524*95c635efSGarrett D'Amore 525*95c635efSGarrett D'Amore /* ARGSUSED */ 526*95c635efSGarrett D'Amore static int 527*95c635efSGarrett D'Amore man_IP_pre(MAN_ARGS) 528*95c635efSGarrett D'Amore { 529*95c635efSGarrett D'Amore const struct man_node *nn; 530*95c635efSGarrett D'Amore 531*95c635efSGarrett D'Amore if (MAN_BODY == n->type) { 532*95c635efSGarrett D'Amore print_otag(h, TAG_DD, 0, NULL); 533*95c635efSGarrett D'Amore return(1); 534*95c635efSGarrett D'Amore } else if (MAN_HEAD != n->type) { 535*95c635efSGarrett D'Amore print_otag(h, TAG_DL, 0, NULL); 536*95c635efSGarrett D'Amore return(1); 537*95c635efSGarrett D'Amore } 538*95c635efSGarrett D'Amore 539*95c635efSGarrett D'Amore /* FIXME: width specification. */ 540*95c635efSGarrett D'Amore 541*95c635efSGarrett D'Amore print_otag(h, TAG_DT, 0, NULL); 542*95c635efSGarrett D'Amore 543*95c635efSGarrett D'Amore /* For IP, only print the first header element. */ 544*95c635efSGarrett D'Amore 545*95c635efSGarrett D'Amore if (MAN_IP == n->tok && n->child) 546*95c635efSGarrett D'Amore print_man_node(m, n->child, mh, h); 547*95c635efSGarrett D'Amore 548*95c635efSGarrett D'Amore /* For TP, only print next-line header elements. */ 549*95c635efSGarrett D'Amore 550*95c635efSGarrett D'Amore if (MAN_TP == n->tok) 551*95c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) 552*95c635efSGarrett D'Amore if (nn->line > n->line) 553*95c635efSGarrett D'Amore print_man_node(m, nn, mh, h); 554*95c635efSGarrett D'Amore 555*95c635efSGarrett D'Amore return(0); 556*95c635efSGarrett D'Amore } 557*95c635efSGarrett D'Amore 558*95c635efSGarrett D'Amore /* ARGSUSED */ 559*95c635efSGarrett D'Amore static int 560*95c635efSGarrett D'Amore man_HP_pre(MAN_ARGS) 561*95c635efSGarrett D'Amore { 562*95c635efSGarrett D'Amore struct htmlpair tag; 563*95c635efSGarrett D'Amore struct roffsu su; 564*95c635efSGarrett D'Amore const struct man_node *np; 565*95c635efSGarrett D'Amore 566*95c635efSGarrett D'Amore if (MAN_HEAD == n->type) 567*95c635efSGarrett D'Amore return(0); 568*95c635efSGarrett D'Amore else if (MAN_BLOCK != n->type) 569*95c635efSGarrett D'Amore return(1); 570*95c635efSGarrett D'Amore 571*95c635efSGarrett D'Amore np = n->head->child; 572*95c635efSGarrett D'Amore 573*95c635efSGarrett D'Amore if (NULL == np || ! a2width(np, &su)) 574*95c635efSGarrett D'Amore SCALE_HS_INIT(&su, INDENT); 575*95c635efSGarrett D'Amore 576*95c635efSGarrett D'Amore bufinit(h); 577*95c635efSGarrett D'Amore 578*95c635efSGarrett D'Amore print_bvspace(h, n); 579*95c635efSGarrett D'Amore bufcat_su(h, "margin-left", &su); 580*95c635efSGarrett D'Amore su.scale = -su.scale; 581*95c635efSGarrett D'Amore bufcat_su(h, "text-indent", &su); 582*95c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 583*95c635efSGarrett D'Amore print_otag(h, TAG_P, 1, &tag); 584*95c635efSGarrett D'Amore return(1); 585*95c635efSGarrett D'Amore } 586*95c635efSGarrett D'Amore 587*95c635efSGarrett D'Amore /* ARGSUSED */ 588*95c635efSGarrett D'Amore static int 589*95c635efSGarrett D'Amore man_OP_pre(MAN_ARGS) 590*95c635efSGarrett D'Amore { 591*95c635efSGarrett D'Amore struct tag *tt; 592*95c635efSGarrett D'Amore struct htmlpair tag; 593*95c635efSGarrett D'Amore 594*95c635efSGarrett D'Amore print_text(h, "["); 595*95c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 596*95c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "opt"); 597*95c635efSGarrett D'Amore tt = print_otag(h, TAG_SPAN, 1, &tag); 598*95c635efSGarrett D'Amore 599*95c635efSGarrett D'Amore if (NULL != (n = n->child)) { 600*95c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 601*95c635efSGarrett D'Amore print_text(h, n->string); 602*95c635efSGarrett D'Amore } 603*95c635efSGarrett D'Amore 604*95c635efSGarrett D'Amore print_stagq(h, tt); 605*95c635efSGarrett D'Amore 606*95c635efSGarrett D'Amore if (NULL != n && NULL != n->next) { 607*95c635efSGarrett D'Amore print_otag(h, TAG_I, 0, NULL); 608*95c635efSGarrett D'Amore print_text(h, n->next->string); 609*95c635efSGarrett D'Amore } 610*95c635efSGarrett D'Amore 611*95c635efSGarrett D'Amore print_stagq(h, tt); 612*95c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 613*95c635efSGarrett D'Amore print_text(h, "]"); 614*95c635efSGarrett D'Amore return(0); 615*95c635efSGarrett D'Amore } 616*95c635efSGarrett D'Amore 617*95c635efSGarrett D'Amore 618*95c635efSGarrett D'Amore /* ARGSUSED */ 619*95c635efSGarrett D'Amore static int 620*95c635efSGarrett D'Amore man_B_pre(MAN_ARGS) 621*95c635efSGarrett D'Amore { 622*95c635efSGarrett D'Amore 623*95c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 624*95c635efSGarrett D'Amore return(1); 625*95c635efSGarrett D'Amore } 626*95c635efSGarrett D'Amore 627*95c635efSGarrett D'Amore /* ARGSUSED */ 628*95c635efSGarrett D'Amore static int 629*95c635efSGarrett D'Amore man_I_pre(MAN_ARGS) 630*95c635efSGarrett D'Amore { 631*95c635efSGarrett D'Amore 632*95c635efSGarrett D'Amore print_otag(h, TAG_I, 0, NULL); 633*95c635efSGarrett D'Amore return(1); 634*95c635efSGarrett D'Amore } 635*95c635efSGarrett D'Amore 636*95c635efSGarrett D'Amore /* ARGSUSED */ 637*95c635efSGarrett D'Amore static int 638*95c635efSGarrett D'Amore man_literal_pre(MAN_ARGS) 639*95c635efSGarrett D'Amore { 640*95c635efSGarrett D'Amore 641*95c635efSGarrett D'Amore if (MAN_nf != n->tok) { 642*95c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 643*95c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 644*95c635efSGarrett D'Amore } else 645*95c635efSGarrett D'Amore mh->fl |= MANH_LITERAL; 646*95c635efSGarrett D'Amore 647*95c635efSGarrett D'Amore return(0); 648*95c635efSGarrett D'Amore } 649*95c635efSGarrett D'Amore 650*95c635efSGarrett D'Amore /* ARGSUSED */ 651*95c635efSGarrett D'Amore static int 652*95c635efSGarrett D'Amore man_in_pre(MAN_ARGS) 653*95c635efSGarrett D'Amore { 654*95c635efSGarrett D'Amore 655*95c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 656*95c635efSGarrett D'Amore return(0); 657*95c635efSGarrett D'Amore } 658*95c635efSGarrett D'Amore 659*95c635efSGarrett D'Amore /* ARGSUSED */ 660*95c635efSGarrett D'Amore static int 661*95c635efSGarrett D'Amore man_ign_pre(MAN_ARGS) 662*95c635efSGarrett D'Amore { 663*95c635efSGarrett D'Amore 664*95c635efSGarrett D'Amore return(0); 665*95c635efSGarrett D'Amore } 666*95c635efSGarrett D'Amore 667*95c635efSGarrett D'Amore /* ARGSUSED */ 668*95c635efSGarrett D'Amore static int 669*95c635efSGarrett D'Amore man_RS_pre(MAN_ARGS) 670*95c635efSGarrett D'Amore { 671*95c635efSGarrett D'Amore struct htmlpair tag; 672*95c635efSGarrett D'Amore struct roffsu su; 673*95c635efSGarrett D'Amore 674*95c635efSGarrett D'Amore if (MAN_HEAD == n->type) 675*95c635efSGarrett D'Amore return(0); 676*95c635efSGarrett D'Amore else if (MAN_BODY == n->type) 677*95c635efSGarrett D'Amore return(1); 678*95c635efSGarrett D'Amore 679*95c635efSGarrett D'Amore SCALE_HS_INIT(&su, INDENT); 680*95c635efSGarrett D'Amore if (n->head->child) 681*95c635efSGarrett D'Amore a2width(n->head->child, &su); 682*95c635efSGarrett D'Amore 683*95c635efSGarrett D'Amore bufinit(h); 684*95c635efSGarrett D'Amore bufcat_su(h, "margin-left", &su); 685*95c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 686*95c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 687*95c635efSGarrett D'Amore return(1); 688*95c635efSGarrett D'Amore } 689