1*698f87a4SGarrett D'Amore /* $Id: man_html.c,v 1.90 2013/10/17 20:54:58 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 3*698f87a4SGarrett D'Amore * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> 4*698f87a4SGarrett D'Amore * Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org> 595c635efSGarrett D'Amore * 695c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 795c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 895c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 995c635efSGarrett D'Amore * 1095c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1195c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1295c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1395c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1495c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1595c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1695c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1795c635efSGarrett D'Amore */ 1895c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 1995c635efSGarrett D'Amore #include "config.h" 2095c635efSGarrett D'Amore #endif 2195c635efSGarrett D'Amore 2295c635efSGarrett D'Amore #include <sys/types.h> 2395c635efSGarrett D'Amore 2495c635efSGarrett D'Amore #include <assert.h> 2595c635efSGarrett D'Amore #include <ctype.h> 2695c635efSGarrett D'Amore #include <stdio.h> 2795c635efSGarrett D'Amore #include <stdlib.h> 2895c635efSGarrett D'Amore #include <string.h> 2995c635efSGarrett D'Amore 3095c635efSGarrett D'Amore #include "mandoc.h" 3195c635efSGarrett D'Amore #include "out.h" 3295c635efSGarrett D'Amore #include "html.h" 3395c635efSGarrett D'Amore #include "man.h" 3495c635efSGarrett D'Amore #include "main.h" 3595c635efSGarrett D'Amore 3695c635efSGarrett D'Amore /* TODO: preserve ident widths. */ 3795c635efSGarrett D'Amore /* FIXME: have PD set the default vspace width. */ 3895c635efSGarrett D'Amore 3995c635efSGarrett D'Amore #define INDENT 5 4095c635efSGarrett D'Amore 41*698f87a4SGarrett D'Amore #define MAN_ARGS const struct man_meta *man, \ 4295c635efSGarrett D'Amore const struct man_node *n, \ 4395c635efSGarrett D'Amore struct mhtml *mh, \ 4495c635efSGarrett D'Amore struct html *h 4595c635efSGarrett D'Amore 4695c635efSGarrett D'Amore struct mhtml { 4795c635efSGarrett D'Amore int fl; 4895c635efSGarrett D'Amore #define MANH_LITERAL (1 << 0) /* literal context */ 4995c635efSGarrett D'Amore }; 5095c635efSGarrett D'Amore 5195c635efSGarrett D'Amore struct htmlman { 5295c635efSGarrett D'Amore int (*pre)(MAN_ARGS); 5395c635efSGarrett D'Amore int (*post)(MAN_ARGS); 5495c635efSGarrett D'Amore }; 5595c635efSGarrett D'Amore 5695c635efSGarrett D'Amore static void print_bvspace(struct html *, 5795c635efSGarrett D'Amore const struct man_node *); 5895c635efSGarrett D'Amore static void print_man(MAN_ARGS); 5995c635efSGarrett D'Amore static void print_man_head(MAN_ARGS); 6095c635efSGarrett D'Amore static void print_man_nodelist(MAN_ARGS); 6195c635efSGarrett D'Amore static void print_man_node(MAN_ARGS); 6295c635efSGarrett D'Amore static int a2width(const struct man_node *, 6395c635efSGarrett D'Amore struct roffsu *); 6495c635efSGarrett D'Amore static int man_B_pre(MAN_ARGS); 6595c635efSGarrett D'Amore static int man_HP_pre(MAN_ARGS); 6695c635efSGarrett D'Amore static int man_IP_pre(MAN_ARGS); 6795c635efSGarrett D'Amore static int man_I_pre(MAN_ARGS); 6895c635efSGarrett D'Amore static int man_OP_pre(MAN_ARGS); 6995c635efSGarrett D'Amore static int man_PP_pre(MAN_ARGS); 7095c635efSGarrett D'Amore static int man_RS_pre(MAN_ARGS); 7195c635efSGarrett D'Amore static int man_SH_pre(MAN_ARGS); 7295c635efSGarrett D'Amore static int man_SM_pre(MAN_ARGS); 7395c635efSGarrett D'Amore static int man_SS_pre(MAN_ARGS); 74*698f87a4SGarrett D'Amore static int man_UR_pre(MAN_ARGS); 7595c635efSGarrett D'Amore static int man_alt_pre(MAN_ARGS); 7695c635efSGarrett D'Amore static int man_br_pre(MAN_ARGS); 7795c635efSGarrett D'Amore static int man_ign_pre(MAN_ARGS); 7895c635efSGarrett D'Amore static int man_in_pre(MAN_ARGS); 7995c635efSGarrett D'Amore static int man_literal_pre(MAN_ARGS); 8095c635efSGarrett D'Amore static void man_root_post(MAN_ARGS); 8195c635efSGarrett D'Amore static void man_root_pre(MAN_ARGS); 8295c635efSGarrett D'Amore 8395c635efSGarrett D'Amore static const struct htmlman mans[MAN_MAX] = { 8495c635efSGarrett D'Amore { man_br_pre, NULL }, /* br */ 8595c635efSGarrett D'Amore { NULL, NULL }, /* TH */ 8695c635efSGarrett D'Amore { man_SH_pre, NULL }, /* SH */ 8795c635efSGarrett D'Amore { man_SS_pre, NULL }, /* SS */ 8895c635efSGarrett D'Amore { man_IP_pre, NULL }, /* TP */ 8995c635efSGarrett D'Amore { man_PP_pre, NULL }, /* LP */ 9095c635efSGarrett D'Amore { man_PP_pre, NULL }, /* PP */ 9195c635efSGarrett D'Amore { man_PP_pre, NULL }, /* P */ 9295c635efSGarrett D'Amore { man_IP_pre, NULL }, /* IP */ 9395c635efSGarrett D'Amore { man_HP_pre, NULL }, /* HP */ 9495c635efSGarrett D'Amore { man_SM_pre, NULL }, /* SM */ 9595c635efSGarrett D'Amore { man_SM_pre, NULL }, /* SB */ 9695c635efSGarrett D'Amore { man_alt_pre, NULL }, /* BI */ 9795c635efSGarrett D'Amore { man_alt_pre, NULL }, /* IB */ 9895c635efSGarrett D'Amore { man_alt_pre, NULL }, /* BR */ 9995c635efSGarrett D'Amore { man_alt_pre, NULL }, /* RB */ 10095c635efSGarrett D'Amore { NULL, NULL }, /* R */ 10195c635efSGarrett D'Amore { man_B_pre, NULL }, /* B */ 10295c635efSGarrett D'Amore { man_I_pre, NULL }, /* I */ 10395c635efSGarrett D'Amore { man_alt_pre, NULL }, /* IR */ 10495c635efSGarrett D'Amore { man_alt_pre, NULL }, /* RI */ 10595c635efSGarrett D'Amore { man_ign_pre, NULL }, /* na */ 10695c635efSGarrett D'Amore { man_br_pre, NULL }, /* sp */ 10795c635efSGarrett D'Amore { man_literal_pre, NULL }, /* nf */ 10895c635efSGarrett D'Amore { man_literal_pre, NULL }, /* fi */ 10995c635efSGarrett D'Amore { NULL, NULL }, /* RE */ 11095c635efSGarrett D'Amore { man_RS_pre, NULL }, /* RS */ 11195c635efSGarrett D'Amore { man_ign_pre, NULL }, /* DT */ 11295c635efSGarrett D'Amore { man_ign_pre, NULL }, /* UC */ 11395c635efSGarrett D'Amore { man_ign_pre, NULL }, /* PD */ 11495c635efSGarrett D'Amore { man_ign_pre, NULL }, /* AT */ 11595c635efSGarrett D'Amore { man_in_pre, NULL }, /* in */ 11695c635efSGarrett D'Amore { man_ign_pre, NULL }, /* ft */ 11795c635efSGarrett D'Amore { man_OP_pre, NULL }, /* OP */ 118*698f87a4SGarrett D'Amore { man_literal_pre, NULL }, /* EX */ 119*698f87a4SGarrett D'Amore { man_literal_pre, NULL }, /* EE */ 120*698f87a4SGarrett D'Amore { man_UR_pre, NULL }, /* UR */ 121*698f87a4SGarrett D'Amore { NULL, NULL }, /* UE */ 12295c635efSGarrett D'Amore }; 12395c635efSGarrett D'Amore 12495c635efSGarrett D'Amore /* 12595c635efSGarrett D'Amore * Printing leading vertical space before a block. 12695c635efSGarrett D'Amore * This is used for the paragraph macros. 12795c635efSGarrett D'Amore * The rules are pretty simple, since there's very little nesting going 12895c635efSGarrett D'Amore * on here. Basically, if we're the first within another block (SS/SH), 12995c635efSGarrett D'Amore * then don't emit vertical space. If we are (RS), then do. If not the 13095c635efSGarrett D'Amore * first, print it. 13195c635efSGarrett D'Amore */ 13295c635efSGarrett D'Amore static void 13395c635efSGarrett D'Amore print_bvspace(struct html *h, const struct man_node *n) 13495c635efSGarrett D'Amore { 13595c635efSGarrett D'Amore 13695c635efSGarrett D'Amore if (n->body && n->body->child) 13795c635efSGarrett D'Amore if (MAN_TBL == n->body->child->type) 13895c635efSGarrett D'Amore return; 13995c635efSGarrett D'Amore 14095c635efSGarrett D'Amore if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) 14195c635efSGarrett D'Amore if (NULL == n->prev) 14295c635efSGarrett D'Amore return; 14395c635efSGarrett D'Amore 14495c635efSGarrett D'Amore print_otag(h, TAG_P, 0, NULL); 14595c635efSGarrett D'Amore } 14695c635efSGarrett D'Amore 14795c635efSGarrett D'Amore void 148*698f87a4SGarrett D'Amore html_man(void *arg, const struct man *man) 14995c635efSGarrett D'Amore { 15095c635efSGarrett D'Amore struct mhtml mh; 15195c635efSGarrett D'Amore 15295c635efSGarrett D'Amore memset(&mh, 0, sizeof(struct mhtml)); 153*698f87a4SGarrett D'Amore print_man(man_meta(man), man_node(man), &mh, (struct html *)arg); 15495c635efSGarrett D'Amore putchar('\n'); 15595c635efSGarrett D'Amore } 15695c635efSGarrett D'Amore 15795c635efSGarrett D'Amore static void 15895c635efSGarrett D'Amore print_man(MAN_ARGS) 15995c635efSGarrett D'Amore { 16095c635efSGarrett D'Amore struct tag *t, *tt; 16195c635efSGarrett D'Amore struct htmlpair tag; 16295c635efSGarrett D'Amore 16395c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "mandoc"); 16495c635efSGarrett D'Amore 16595c635efSGarrett D'Amore if ( ! (HTML_FRAGMENT & h->oflags)) { 16695c635efSGarrett D'Amore print_gen_decls(h); 16795c635efSGarrett D'Amore t = print_otag(h, TAG_HTML, 0, NULL); 16895c635efSGarrett D'Amore tt = print_otag(h, TAG_HEAD, 0, NULL); 169*698f87a4SGarrett D'Amore print_man_head(man, n, mh, h); 17095c635efSGarrett D'Amore print_tagq(h, tt); 17195c635efSGarrett D'Amore print_otag(h, TAG_BODY, 0, NULL); 17295c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 17395c635efSGarrett D'Amore } else 17495c635efSGarrett D'Amore t = print_otag(h, TAG_DIV, 1, &tag); 17595c635efSGarrett D'Amore 176*698f87a4SGarrett D'Amore print_man_nodelist(man, n, mh, h); 17795c635efSGarrett D'Amore print_tagq(h, t); 17895c635efSGarrett D'Amore } 17995c635efSGarrett D'Amore 18095c635efSGarrett D'Amore 18195c635efSGarrett D'Amore /* ARGSUSED */ 18295c635efSGarrett D'Amore static void 18395c635efSGarrett D'Amore print_man_head(MAN_ARGS) 18495c635efSGarrett D'Amore { 18595c635efSGarrett D'Amore 18695c635efSGarrett D'Amore print_gen_head(h); 187*698f87a4SGarrett D'Amore assert(man->title); 188*698f87a4SGarrett D'Amore assert(man->msec); 189*698f87a4SGarrett D'Amore bufcat_fmt(h, "%s(%s)", man->title, man->msec); 19095c635efSGarrett D'Amore print_otag(h, TAG_TITLE, 0, NULL); 19195c635efSGarrett D'Amore print_text(h, h->buf); 19295c635efSGarrett D'Amore } 19395c635efSGarrett D'Amore 19495c635efSGarrett D'Amore 19595c635efSGarrett D'Amore static void 19695c635efSGarrett D'Amore print_man_nodelist(MAN_ARGS) 19795c635efSGarrett D'Amore { 19895c635efSGarrett D'Amore 199*698f87a4SGarrett D'Amore print_man_node(man, n, mh, h); 20095c635efSGarrett D'Amore if (n->next) 201*698f87a4SGarrett D'Amore print_man_nodelist(man, n->next, mh, h); 20295c635efSGarrett D'Amore } 20395c635efSGarrett D'Amore 20495c635efSGarrett D'Amore 20595c635efSGarrett D'Amore static void 20695c635efSGarrett D'Amore print_man_node(MAN_ARGS) 20795c635efSGarrett D'Amore { 20895c635efSGarrett D'Amore int child; 20995c635efSGarrett D'Amore struct tag *t; 21095c635efSGarrett D'Amore 21195c635efSGarrett D'Amore child = 1; 21295c635efSGarrett D'Amore t = h->tags.head; 21395c635efSGarrett D'Amore 21495c635efSGarrett D'Amore switch (n->type) { 21595c635efSGarrett D'Amore case (MAN_ROOT): 216*698f87a4SGarrett D'Amore man_root_pre(man, n, mh, h); 21795c635efSGarrett D'Amore break; 21895c635efSGarrett D'Amore case (MAN_TEXT): 21995c635efSGarrett D'Amore /* 22095c635efSGarrett D'Amore * If we have a blank line, output a vertical space. 22195c635efSGarrett D'Amore * If we have a space as the first character, break 22295c635efSGarrett D'Amore * before printing the line's data. 22395c635efSGarrett D'Amore */ 22495c635efSGarrett D'Amore if ('\0' == *n->string) { 22595c635efSGarrett D'Amore print_otag(h, TAG_P, 0, NULL); 22695c635efSGarrett D'Amore return; 22795c635efSGarrett D'Amore } 22895c635efSGarrett D'Amore 22995c635efSGarrett D'Amore if (' ' == *n->string && MAN_LINE & n->flags) 23095c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 23195c635efSGarrett D'Amore else if (MANH_LITERAL & mh->fl && n->prev) 23295c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 23395c635efSGarrett D'Amore 23495c635efSGarrett D'Amore print_text(h, n->string); 23595c635efSGarrett D'Amore return; 23695c635efSGarrett D'Amore case (MAN_EQN): 23795c635efSGarrett D'Amore print_eqn(h, n->eqn); 23895c635efSGarrett D'Amore break; 23995c635efSGarrett D'Amore case (MAN_TBL): 24095c635efSGarrett D'Amore /* 24195c635efSGarrett D'Amore * This will take care of initialising all of the table 24295c635efSGarrett D'Amore * state data for the first table, then tearing it down 24395c635efSGarrett D'Amore * for the last one. 24495c635efSGarrett D'Amore */ 24595c635efSGarrett D'Amore print_tbl(h, n->span); 24695c635efSGarrett D'Amore return; 24795c635efSGarrett D'Amore default: 24895c635efSGarrett D'Amore /* 24995c635efSGarrett D'Amore * Close out scope of font prior to opening a macro 25095c635efSGarrett D'Amore * scope. 25195c635efSGarrett D'Amore */ 25295c635efSGarrett D'Amore if (HTMLFONT_NONE != h->metac) { 25395c635efSGarrett D'Amore h->metal = h->metac; 25495c635efSGarrett D'Amore h->metac = HTMLFONT_NONE; 25595c635efSGarrett D'Amore } 25695c635efSGarrett D'Amore 25795c635efSGarrett D'Amore /* 25895c635efSGarrett D'Amore * Close out the current table, if it's open, and unset 25995c635efSGarrett D'Amore * the "meta" table state. This will be reopened on the 26095c635efSGarrett D'Amore * next table element. 26195c635efSGarrett D'Amore */ 26295c635efSGarrett D'Amore if (h->tblt) { 26395c635efSGarrett D'Amore print_tblclose(h); 26495c635efSGarrett D'Amore t = h->tags.head; 26595c635efSGarrett D'Amore } 26695c635efSGarrett D'Amore if (mans[n->tok].pre) 267*698f87a4SGarrett D'Amore child = (*mans[n->tok].pre)(man, n, mh, h); 26895c635efSGarrett D'Amore break; 26995c635efSGarrett D'Amore } 27095c635efSGarrett D'Amore 27195c635efSGarrett D'Amore if (child && n->child) 272*698f87a4SGarrett D'Amore print_man_nodelist(man, n->child, mh, h); 27395c635efSGarrett D'Amore 27495c635efSGarrett D'Amore /* This will automatically close out any font scope. */ 27595c635efSGarrett D'Amore print_stagq(h, t); 27695c635efSGarrett D'Amore 27795c635efSGarrett D'Amore switch (n->type) { 27895c635efSGarrett D'Amore case (MAN_ROOT): 279*698f87a4SGarrett D'Amore man_root_post(man, n, mh, h); 28095c635efSGarrett D'Amore break; 28195c635efSGarrett D'Amore case (MAN_EQN): 28295c635efSGarrett D'Amore break; 28395c635efSGarrett D'Amore default: 28495c635efSGarrett D'Amore if (mans[n->tok].post) 285*698f87a4SGarrett D'Amore (*mans[n->tok].post)(man, n, mh, h); 28695c635efSGarrett D'Amore break; 28795c635efSGarrett D'Amore } 28895c635efSGarrett D'Amore } 28995c635efSGarrett D'Amore 29095c635efSGarrett D'Amore 29195c635efSGarrett D'Amore static int 29295c635efSGarrett D'Amore a2width(const struct man_node *n, struct roffsu *su) 29395c635efSGarrett D'Amore { 29495c635efSGarrett D'Amore 29595c635efSGarrett D'Amore if (MAN_TEXT != n->type) 29695c635efSGarrett D'Amore return(0); 29795c635efSGarrett D'Amore if (a2roffsu(n->string, su, SCALE_BU)) 29895c635efSGarrett D'Amore return(1); 29995c635efSGarrett D'Amore 30095c635efSGarrett D'Amore return(0); 30195c635efSGarrett D'Amore } 30295c635efSGarrett D'Amore 30395c635efSGarrett D'Amore 30495c635efSGarrett D'Amore /* ARGSUSED */ 30595c635efSGarrett D'Amore static void 30695c635efSGarrett D'Amore man_root_pre(MAN_ARGS) 30795c635efSGarrett D'Amore { 30895c635efSGarrett D'Amore struct htmlpair tag[3]; 30995c635efSGarrett D'Amore struct tag *t, *tt; 31095c635efSGarrett D'Amore char b[BUFSIZ], title[BUFSIZ]; 31195c635efSGarrett D'Amore 31295c635efSGarrett D'Amore b[0] = 0; 313*698f87a4SGarrett D'Amore if (man->vol) 314*698f87a4SGarrett D'Amore (void)strlcat(b, man->vol, BUFSIZ); 31595c635efSGarrett D'Amore 316*698f87a4SGarrett D'Amore assert(man->title); 317*698f87a4SGarrett D'Amore assert(man->msec); 318*698f87a4SGarrett D'Amore snprintf(title, BUFSIZ - 1, "%s(%s)", man->title, man->msec); 31995c635efSGarrett D'Amore 32095c635efSGarrett D'Amore PAIR_SUMMARY_INIT(&tag[0], "Document Header"); 32195c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[1], "head"); 32295c635efSGarrett D'Amore PAIR_INIT(&tag[2], ATTR_WIDTH, "100%"); 32395c635efSGarrett D'Amore t = print_otag(h, TAG_TABLE, 3, tag); 32495c635efSGarrett D'Amore PAIR_INIT(&tag[0], ATTR_WIDTH, "30%"); 32595c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 32695c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 32795c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 32895c635efSGarrett D'Amore 32995c635efSGarrett D'Amore print_otag(h, TAG_TBODY, 0, NULL); 33095c635efSGarrett D'Amore 33195c635efSGarrett D'Amore tt = print_otag(h, TAG_TR, 0, NULL); 33295c635efSGarrett D'Amore 33395c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "head-ltitle"); 33495c635efSGarrett D'Amore print_otag(h, TAG_TD, 1, tag); 33595c635efSGarrett D'Amore print_text(h, title); 33695c635efSGarrett D'Amore print_stagq(h, tt); 33795c635efSGarrett D'Amore 33895c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "head-vol"); 33995c635efSGarrett D'Amore PAIR_INIT(&tag[1], ATTR_ALIGN, "center"); 34095c635efSGarrett D'Amore print_otag(h, TAG_TD, 2, tag); 34195c635efSGarrett D'Amore print_text(h, b); 34295c635efSGarrett D'Amore print_stagq(h, tt); 34395c635efSGarrett D'Amore 34495c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "head-rtitle"); 34595c635efSGarrett D'Amore PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); 34695c635efSGarrett D'Amore print_otag(h, TAG_TD, 2, tag); 34795c635efSGarrett D'Amore print_text(h, title); 34895c635efSGarrett D'Amore print_tagq(h, t); 34995c635efSGarrett D'Amore } 35095c635efSGarrett D'Amore 35195c635efSGarrett D'Amore 35295c635efSGarrett D'Amore /* ARGSUSED */ 35395c635efSGarrett D'Amore static void 35495c635efSGarrett D'Amore man_root_post(MAN_ARGS) 35595c635efSGarrett D'Amore { 35695c635efSGarrett D'Amore struct htmlpair tag[3]; 35795c635efSGarrett D'Amore struct tag *t, *tt; 35895c635efSGarrett D'Amore 35995c635efSGarrett D'Amore PAIR_SUMMARY_INIT(&tag[0], "Document Footer"); 36095c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[1], "foot"); 36195c635efSGarrett D'Amore PAIR_INIT(&tag[2], ATTR_WIDTH, "100%"); 36295c635efSGarrett D'Amore t = print_otag(h, TAG_TABLE, 3, tag); 36395c635efSGarrett D'Amore PAIR_INIT(&tag[0], ATTR_WIDTH, "50%"); 36495c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 36595c635efSGarrett D'Amore print_otag(h, TAG_COL, 1, tag); 36695c635efSGarrett D'Amore 36795c635efSGarrett D'Amore tt = print_otag(h, TAG_TR, 0, NULL); 36895c635efSGarrett D'Amore 36995c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "foot-date"); 37095c635efSGarrett D'Amore print_otag(h, TAG_TD, 1, tag); 37195c635efSGarrett D'Amore 372*698f87a4SGarrett D'Amore assert(man->date); 373*698f87a4SGarrett D'Amore print_text(h, man->date); 37495c635efSGarrett D'Amore print_stagq(h, tt); 37595c635efSGarrett D'Amore 37695c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "foot-os"); 37795c635efSGarrett D'Amore PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); 37895c635efSGarrett D'Amore print_otag(h, TAG_TD, 2, tag); 37995c635efSGarrett D'Amore 380*698f87a4SGarrett D'Amore if (man->source) 381*698f87a4SGarrett D'Amore print_text(h, man->source); 38295c635efSGarrett D'Amore print_tagq(h, t); 38395c635efSGarrett D'Amore } 38495c635efSGarrett D'Amore 38595c635efSGarrett D'Amore 38695c635efSGarrett D'Amore /* ARGSUSED */ 38795c635efSGarrett D'Amore static int 38895c635efSGarrett D'Amore man_br_pre(MAN_ARGS) 38995c635efSGarrett D'Amore { 39095c635efSGarrett D'Amore struct roffsu su; 39195c635efSGarrett D'Amore struct htmlpair tag; 39295c635efSGarrett D'Amore 39395c635efSGarrett D'Amore SCALE_VS_INIT(&su, 1); 39495c635efSGarrett D'Amore 39595c635efSGarrett D'Amore if (MAN_sp == n->tok) { 39695c635efSGarrett D'Amore if (NULL != (n = n->child)) 39795c635efSGarrett D'Amore if ( ! a2roffsu(n->string, &su, SCALE_VS)) 39895c635efSGarrett D'Amore SCALE_VS_INIT(&su, atoi(n->string)); 39995c635efSGarrett D'Amore } else 40095c635efSGarrett D'Amore su.scale = 0; 40195c635efSGarrett D'Amore 40295c635efSGarrett D'Amore bufinit(h); 40395c635efSGarrett D'Amore bufcat_su(h, "height", &su); 40495c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 40595c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 40695c635efSGarrett D'Amore 40795c635efSGarrett D'Amore /* So the div isn't empty: */ 40895c635efSGarrett D'Amore print_text(h, "\\~"); 40995c635efSGarrett D'Amore 41095c635efSGarrett D'Amore return(0); 41195c635efSGarrett D'Amore } 41295c635efSGarrett D'Amore 41395c635efSGarrett D'Amore /* ARGSUSED */ 41495c635efSGarrett D'Amore static int 41595c635efSGarrett D'Amore man_SH_pre(MAN_ARGS) 41695c635efSGarrett D'Amore { 41795c635efSGarrett D'Amore struct htmlpair tag; 41895c635efSGarrett D'Amore 41995c635efSGarrett D'Amore if (MAN_BLOCK == n->type) { 42095c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 42195c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "section"); 42295c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 42395c635efSGarrett D'Amore return(1); 42495c635efSGarrett D'Amore } else if (MAN_BODY == n->type) 42595c635efSGarrett D'Amore return(1); 42695c635efSGarrett D'Amore 42795c635efSGarrett D'Amore print_otag(h, TAG_H1, 0, NULL); 42895c635efSGarrett D'Amore return(1); 42995c635efSGarrett D'Amore } 43095c635efSGarrett D'Amore 43195c635efSGarrett D'Amore /* ARGSUSED */ 43295c635efSGarrett D'Amore static int 43395c635efSGarrett D'Amore man_alt_pre(MAN_ARGS) 43495c635efSGarrett D'Amore { 43595c635efSGarrett D'Amore const struct man_node *nn; 43695c635efSGarrett D'Amore int i, savelit; 43795c635efSGarrett D'Amore enum htmltag fp; 43895c635efSGarrett D'Amore struct tag *t; 43995c635efSGarrett D'Amore 44095c635efSGarrett D'Amore if ((savelit = mh->fl & MANH_LITERAL)) 44195c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 44295c635efSGarrett D'Amore 44395c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 44495c635efSGarrett D'Amore 44595c635efSGarrett D'Amore for (i = 0, nn = n->child; nn; nn = nn->next, i++) { 44695c635efSGarrett D'Amore t = NULL; 44795c635efSGarrett D'Amore switch (n->tok) { 44895c635efSGarrett D'Amore case (MAN_BI): 44995c635efSGarrett D'Amore fp = i % 2 ? TAG_I : TAG_B; 45095c635efSGarrett D'Amore break; 45195c635efSGarrett D'Amore case (MAN_IB): 45295c635efSGarrett D'Amore fp = i % 2 ? TAG_B : TAG_I; 45395c635efSGarrett D'Amore break; 45495c635efSGarrett D'Amore case (MAN_RI): 45595c635efSGarrett D'Amore fp = i % 2 ? TAG_I : TAG_MAX; 45695c635efSGarrett D'Amore break; 45795c635efSGarrett D'Amore case (MAN_IR): 45895c635efSGarrett D'Amore fp = i % 2 ? TAG_MAX : TAG_I; 45995c635efSGarrett D'Amore break; 46095c635efSGarrett D'Amore case (MAN_BR): 46195c635efSGarrett D'Amore fp = i % 2 ? TAG_MAX : TAG_B; 46295c635efSGarrett D'Amore break; 46395c635efSGarrett D'Amore case (MAN_RB): 46495c635efSGarrett D'Amore fp = i % 2 ? TAG_B : TAG_MAX; 46595c635efSGarrett D'Amore break; 46695c635efSGarrett D'Amore default: 46795c635efSGarrett D'Amore abort(); 46895c635efSGarrett D'Amore /* NOTREACHED */ 46995c635efSGarrett D'Amore } 47095c635efSGarrett D'Amore 47195c635efSGarrett D'Amore if (i) 47295c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 47395c635efSGarrett D'Amore 47495c635efSGarrett D'Amore if (TAG_MAX != fp) 47595c635efSGarrett D'Amore t = print_otag(h, fp, 0, NULL); 47695c635efSGarrett D'Amore 477*698f87a4SGarrett D'Amore print_man_node(man, nn, mh, h); 47895c635efSGarrett D'Amore 47995c635efSGarrett D'Amore if (t) 48095c635efSGarrett D'Amore print_tagq(h, t); 48195c635efSGarrett D'Amore } 48295c635efSGarrett D'Amore 48395c635efSGarrett D'Amore if (savelit) 48495c635efSGarrett D'Amore mh->fl |= MANH_LITERAL; 48595c635efSGarrett D'Amore 48695c635efSGarrett D'Amore return(0); 48795c635efSGarrett D'Amore } 48895c635efSGarrett D'Amore 48995c635efSGarrett D'Amore /* ARGSUSED */ 49095c635efSGarrett D'Amore static int 49195c635efSGarrett D'Amore man_SM_pre(MAN_ARGS) 49295c635efSGarrett D'Amore { 49395c635efSGarrett D'Amore 49495c635efSGarrett D'Amore print_otag(h, TAG_SMALL, 0, NULL); 49595c635efSGarrett D'Amore if (MAN_SB == n->tok) 49695c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 49795c635efSGarrett D'Amore return(1); 49895c635efSGarrett D'Amore } 49995c635efSGarrett D'Amore 50095c635efSGarrett D'Amore /* ARGSUSED */ 50195c635efSGarrett D'Amore static int 50295c635efSGarrett D'Amore man_SS_pre(MAN_ARGS) 50395c635efSGarrett D'Amore { 50495c635efSGarrett D'Amore struct htmlpair tag; 50595c635efSGarrett D'Amore 50695c635efSGarrett D'Amore if (MAN_BLOCK == n->type) { 50795c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 50895c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "subsection"); 50995c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 51095c635efSGarrett D'Amore return(1); 51195c635efSGarrett D'Amore } else if (MAN_BODY == n->type) 51295c635efSGarrett D'Amore return(1); 51395c635efSGarrett D'Amore 51495c635efSGarrett D'Amore print_otag(h, TAG_H2, 0, NULL); 51595c635efSGarrett D'Amore return(1); 51695c635efSGarrett D'Amore } 51795c635efSGarrett D'Amore 51895c635efSGarrett D'Amore /* ARGSUSED */ 51995c635efSGarrett D'Amore static int 52095c635efSGarrett D'Amore man_PP_pre(MAN_ARGS) 52195c635efSGarrett D'Amore { 52295c635efSGarrett D'Amore 52395c635efSGarrett D'Amore if (MAN_HEAD == n->type) 52495c635efSGarrett D'Amore return(0); 52595c635efSGarrett D'Amore else if (MAN_BLOCK == n->type) 52695c635efSGarrett D'Amore print_bvspace(h, n); 52795c635efSGarrett D'Amore 52895c635efSGarrett D'Amore return(1); 52995c635efSGarrett D'Amore } 53095c635efSGarrett D'Amore 53195c635efSGarrett D'Amore /* ARGSUSED */ 53295c635efSGarrett D'Amore static int 53395c635efSGarrett D'Amore man_IP_pre(MAN_ARGS) 53495c635efSGarrett D'Amore { 53595c635efSGarrett D'Amore const struct man_node *nn; 53695c635efSGarrett D'Amore 53795c635efSGarrett D'Amore if (MAN_BODY == n->type) { 53895c635efSGarrett D'Amore print_otag(h, TAG_DD, 0, NULL); 53995c635efSGarrett D'Amore return(1); 54095c635efSGarrett D'Amore } else if (MAN_HEAD != n->type) { 54195c635efSGarrett D'Amore print_otag(h, TAG_DL, 0, NULL); 54295c635efSGarrett D'Amore return(1); 54395c635efSGarrett D'Amore } 54495c635efSGarrett D'Amore 54595c635efSGarrett D'Amore /* FIXME: width specification. */ 54695c635efSGarrett D'Amore 54795c635efSGarrett D'Amore print_otag(h, TAG_DT, 0, NULL); 54895c635efSGarrett D'Amore 54995c635efSGarrett D'Amore /* For IP, only print the first header element. */ 55095c635efSGarrett D'Amore 55195c635efSGarrett D'Amore if (MAN_IP == n->tok && n->child) 552*698f87a4SGarrett D'Amore print_man_node(man, n->child, mh, h); 55395c635efSGarrett D'Amore 55495c635efSGarrett D'Amore /* For TP, only print next-line header elements. */ 55595c635efSGarrett D'Amore 55695c635efSGarrett D'Amore if (MAN_TP == n->tok) 55795c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) 55895c635efSGarrett D'Amore if (nn->line > n->line) 559*698f87a4SGarrett D'Amore print_man_node(man, nn, mh, h); 56095c635efSGarrett D'Amore 56195c635efSGarrett D'Amore return(0); 56295c635efSGarrett D'Amore } 56395c635efSGarrett D'Amore 56495c635efSGarrett D'Amore /* ARGSUSED */ 56595c635efSGarrett D'Amore static int 56695c635efSGarrett D'Amore man_HP_pre(MAN_ARGS) 56795c635efSGarrett D'Amore { 56895c635efSGarrett D'Amore struct htmlpair tag; 56995c635efSGarrett D'Amore struct roffsu su; 57095c635efSGarrett D'Amore const struct man_node *np; 57195c635efSGarrett D'Amore 57295c635efSGarrett D'Amore if (MAN_HEAD == n->type) 57395c635efSGarrett D'Amore return(0); 57495c635efSGarrett D'Amore else if (MAN_BLOCK != n->type) 57595c635efSGarrett D'Amore return(1); 57695c635efSGarrett D'Amore 57795c635efSGarrett D'Amore np = n->head->child; 57895c635efSGarrett D'Amore 57995c635efSGarrett D'Amore if (NULL == np || ! a2width(np, &su)) 58095c635efSGarrett D'Amore SCALE_HS_INIT(&su, INDENT); 58195c635efSGarrett D'Amore 58295c635efSGarrett D'Amore bufinit(h); 58395c635efSGarrett D'Amore 58495c635efSGarrett D'Amore print_bvspace(h, n); 58595c635efSGarrett D'Amore bufcat_su(h, "margin-left", &su); 58695c635efSGarrett D'Amore su.scale = -su.scale; 58795c635efSGarrett D'Amore bufcat_su(h, "text-indent", &su); 58895c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 58995c635efSGarrett D'Amore print_otag(h, TAG_P, 1, &tag); 59095c635efSGarrett D'Amore return(1); 59195c635efSGarrett D'Amore } 59295c635efSGarrett D'Amore 59395c635efSGarrett D'Amore /* ARGSUSED */ 59495c635efSGarrett D'Amore static int 59595c635efSGarrett D'Amore man_OP_pre(MAN_ARGS) 59695c635efSGarrett D'Amore { 59795c635efSGarrett D'Amore struct tag *tt; 59895c635efSGarrett D'Amore struct htmlpair tag; 59995c635efSGarrett D'Amore 60095c635efSGarrett D'Amore print_text(h, "["); 60195c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 60295c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "opt"); 60395c635efSGarrett D'Amore tt = print_otag(h, TAG_SPAN, 1, &tag); 60495c635efSGarrett D'Amore 60595c635efSGarrett D'Amore if (NULL != (n = n->child)) { 60695c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 60795c635efSGarrett D'Amore print_text(h, n->string); 60895c635efSGarrett D'Amore } 60995c635efSGarrett D'Amore 61095c635efSGarrett D'Amore print_stagq(h, tt); 61195c635efSGarrett D'Amore 61295c635efSGarrett D'Amore if (NULL != n && NULL != n->next) { 61395c635efSGarrett D'Amore print_otag(h, TAG_I, 0, NULL); 61495c635efSGarrett D'Amore print_text(h, n->next->string); 61595c635efSGarrett D'Amore } 61695c635efSGarrett D'Amore 61795c635efSGarrett D'Amore print_stagq(h, tt); 61895c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 61995c635efSGarrett D'Amore print_text(h, "]"); 62095c635efSGarrett D'Amore return(0); 62195c635efSGarrett D'Amore } 62295c635efSGarrett D'Amore 62395c635efSGarrett D'Amore 62495c635efSGarrett D'Amore /* ARGSUSED */ 62595c635efSGarrett D'Amore static int 62695c635efSGarrett D'Amore man_B_pre(MAN_ARGS) 62795c635efSGarrett D'Amore { 62895c635efSGarrett D'Amore 62995c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 63095c635efSGarrett D'Amore return(1); 63195c635efSGarrett D'Amore } 63295c635efSGarrett D'Amore 63395c635efSGarrett D'Amore /* ARGSUSED */ 63495c635efSGarrett D'Amore static int 63595c635efSGarrett D'Amore man_I_pre(MAN_ARGS) 63695c635efSGarrett D'Amore { 63795c635efSGarrett D'Amore 63895c635efSGarrett D'Amore print_otag(h, TAG_I, 0, NULL); 63995c635efSGarrett D'Amore return(1); 64095c635efSGarrett D'Amore } 64195c635efSGarrett D'Amore 64295c635efSGarrett D'Amore /* ARGSUSED */ 64395c635efSGarrett D'Amore static int 64495c635efSGarrett D'Amore man_literal_pre(MAN_ARGS) 64595c635efSGarrett D'Amore { 64695c635efSGarrett D'Amore 647*698f87a4SGarrett D'Amore if (MAN_fi == n->tok || MAN_EE == n->tok) { 64895c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 64995c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 65095c635efSGarrett D'Amore } else 65195c635efSGarrett D'Amore mh->fl |= MANH_LITERAL; 65295c635efSGarrett D'Amore 65395c635efSGarrett D'Amore return(0); 65495c635efSGarrett D'Amore } 65595c635efSGarrett D'Amore 65695c635efSGarrett D'Amore /* ARGSUSED */ 65795c635efSGarrett D'Amore static int 65895c635efSGarrett D'Amore man_in_pre(MAN_ARGS) 65995c635efSGarrett D'Amore { 66095c635efSGarrett D'Amore 66195c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 66295c635efSGarrett D'Amore return(0); 66395c635efSGarrett D'Amore } 66495c635efSGarrett D'Amore 66595c635efSGarrett D'Amore /* ARGSUSED */ 66695c635efSGarrett D'Amore static int 66795c635efSGarrett D'Amore man_ign_pre(MAN_ARGS) 66895c635efSGarrett D'Amore { 66995c635efSGarrett D'Amore 67095c635efSGarrett D'Amore return(0); 67195c635efSGarrett D'Amore } 67295c635efSGarrett D'Amore 67395c635efSGarrett D'Amore /* ARGSUSED */ 67495c635efSGarrett D'Amore static int 67595c635efSGarrett D'Amore man_RS_pre(MAN_ARGS) 67695c635efSGarrett D'Amore { 67795c635efSGarrett D'Amore struct htmlpair tag; 67895c635efSGarrett D'Amore struct roffsu su; 67995c635efSGarrett D'Amore 68095c635efSGarrett D'Amore if (MAN_HEAD == n->type) 68195c635efSGarrett D'Amore return(0); 68295c635efSGarrett D'Amore else if (MAN_BODY == n->type) 68395c635efSGarrett D'Amore return(1); 68495c635efSGarrett D'Amore 68595c635efSGarrett D'Amore SCALE_HS_INIT(&su, INDENT); 68695c635efSGarrett D'Amore if (n->head->child) 68795c635efSGarrett D'Amore a2width(n->head->child, &su); 68895c635efSGarrett D'Amore 68995c635efSGarrett D'Amore bufinit(h); 69095c635efSGarrett D'Amore bufcat_su(h, "margin-left", &su); 69195c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 69295c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 69395c635efSGarrett D'Amore return(1); 69495c635efSGarrett D'Amore } 695*698f87a4SGarrett D'Amore 696*698f87a4SGarrett D'Amore /* ARGSUSED */ 697*698f87a4SGarrett D'Amore static int 698*698f87a4SGarrett D'Amore man_UR_pre(MAN_ARGS) 699*698f87a4SGarrett D'Amore { 700*698f87a4SGarrett D'Amore struct htmlpair tag[2]; 701*698f87a4SGarrett D'Amore 702*698f87a4SGarrett D'Amore n = n->child; 703*698f87a4SGarrett D'Amore assert(MAN_HEAD == n->type); 704*698f87a4SGarrett D'Amore if (n->nchild) { 705*698f87a4SGarrett D'Amore assert(MAN_TEXT == n->child->type); 706*698f87a4SGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "link-ext"); 707*698f87a4SGarrett D'Amore PAIR_HREF_INIT(&tag[1], n->child->string); 708*698f87a4SGarrett D'Amore print_otag(h, TAG_A, 2, tag); 709*698f87a4SGarrett D'Amore } 710*698f87a4SGarrett D'Amore 711*698f87a4SGarrett D'Amore assert(MAN_BODY == n->next->type); 712*698f87a4SGarrett D'Amore if (n->next->nchild) 713*698f87a4SGarrett D'Amore n = n->next; 714*698f87a4SGarrett D'Amore 715*698f87a4SGarrett D'Amore print_man_nodelist(man, n->child, mh, h); 716*698f87a4SGarrett D'Amore 717*698f87a4SGarrett D'Amore return(0); 718*698f87a4SGarrett D'Amore } 719