1*260e9a87SYuri Pankov /* $Id: man_html.c,v 1.112 2015/03/03 21:11:34 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 3*260e9a87SYuri Pankov * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> 4*260e9a87SYuri Pankov * Copyright (c) 2013, 2014, 2015 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 #include "config.h" 1995c635efSGarrett D'Amore 2095c635efSGarrett D'Amore #include <sys/types.h> 2195c635efSGarrett D'Amore 2295c635efSGarrett D'Amore #include <assert.h> 2395c635efSGarrett D'Amore #include <ctype.h> 2495c635efSGarrett D'Amore #include <stdio.h> 2595c635efSGarrett D'Amore #include <stdlib.h> 2695c635efSGarrett D'Amore #include <string.h> 2795c635efSGarrett D'Amore 28*260e9a87SYuri Pankov #include "mandoc_aux.h" 29*260e9a87SYuri Pankov #include "man.h" 3095c635efSGarrett D'Amore #include "out.h" 3195c635efSGarrett D'Amore #include "html.h" 3295c635efSGarrett D'Amore #include "main.h" 3395c635efSGarrett D'Amore 3495c635efSGarrett D'Amore /* TODO: preserve ident widths. */ 3595c635efSGarrett D'Amore /* FIXME: have PD set the default vspace width. */ 3695c635efSGarrett D'Amore 3795c635efSGarrett D'Amore #define INDENT 5 3895c635efSGarrett D'Amore 39698f87a4SGarrett D'Amore #define MAN_ARGS const struct man_meta *man, \ 4095c635efSGarrett D'Amore const struct man_node *n, \ 4195c635efSGarrett D'Amore struct mhtml *mh, \ 4295c635efSGarrett D'Amore struct html *h 4395c635efSGarrett D'Amore 4495c635efSGarrett D'Amore struct mhtml { 4595c635efSGarrett D'Amore int fl; 4695c635efSGarrett D'Amore #define MANH_LITERAL (1 << 0) /* literal context */ 4795c635efSGarrett D'Amore }; 4895c635efSGarrett D'Amore 4995c635efSGarrett D'Amore struct htmlman { 5095c635efSGarrett D'Amore int (*pre)(MAN_ARGS); 5195c635efSGarrett D'Amore int (*post)(MAN_ARGS); 5295c635efSGarrett D'Amore }; 5395c635efSGarrett D'Amore 5495c635efSGarrett D'Amore static void print_bvspace(struct html *, 5595c635efSGarrett D'Amore const struct man_node *); 5695c635efSGarrett D'Amore static void print_man(MAN_ARGS); 5795c635efSGarrett D'Amore static void print_man_head(MAN_ARGS); 5895c635efSGarrett D'Amore static void print_man_nodelist(MAN_ARGS); 5995c635efSGarrett D'Amore static void print_man_node(MAN_ARGS); 6095c635efSGarrett D'Amore static int a2width(const struct man_node *, 6195c635efSGarrett D'Amore struct roffsu *); 6295c635efSGarrett D'Amore static int man_B_pre(MAN_ARGS); 6395c635efSGarrett D'Amore static int man_HP_pre(MAN_ARGS); 6495c635efSGarrett D'Amore static int man_IP_pre(MAN_ARGS); 6595c635efSGarrett D'Amore static int man_I_pre(MAN_ARGS); 6695c635efSGarrett D'Amore static int man_OP_pre(MAN_ARGS); 6795c635efSGarrett D'Amore static int man_PP_pre(MAN_ARGS); 6895c635efSGarrett D'Amore static int man_RS_pre(MAN_ARGS); 6995c635efSGarrett D'Amore static int man_SH_pre(MAN_ARGS); 7095c635efSGarrett D'Amore static int man_SM_pre(MAN_ARGS); 7195c635efSGarrett D'Amore static int man_SS_pre(MAN_ARGS); 72698f87a4SGarrett D'Amore static int man_UR_pre(MAN_ARGS); 7395c635efSGarrett D'Amore static int man_alt_pre(MAN_ARGS); 7495c635efSGarrett D'Amore static int man_br_pre(MAN_ARGS); 7595c635efSGarrett D'Amore static int man_ign_pre(MAN_ARGS); 7695c635efSGarrett D'Amore static int man_in_pre(MAN_ARGS); 7795c635efSGarrett D'Amore static int man_literal_pre(MAN_ARGS); 7895c635efSGarrett D'Amore static void man_root_post(MAN_ARGS); 7995c635efSGarrett D'Amore static void man_root_pre(MAN_ARGS); 8095c635efSGarrett D'Amore 8195c635efSGarrett D'Amore static const struct htmlman mans[MAN_MAX] = { 8295c635efSGarrett D'Amore { man_br_pre, NULL }, /* br */ 8395c635efSGarrett D'Amore { NULL, NULL }, /* TH */ 8495c635efSGarrett D'Amore { man_SH_pre, NULL }, /* SH */ 8595c635efSGarrett D'Amore { man_SS_pre, NULL }, /* SS */ 8695c635efSGarrett D'Amore { man_IP_pre, NULL }, /* TP */ 8795c635efSGarrett D'Amore { man_PP_pre, NULL }, /* LP */ 8895c635efSGarrett D'Amore { man_PP_pre, NULL }, /* PP */ 8995c635efSGarrett D'Amore { man_PP_pre, NULL }, /* P */ 9095c635efSGarrett D'Amore { man_IP_pre, NULL }, /* IP */ 9195c635efSGarrett D'Amore { man_HP_pre, NULL }, /* HP */ 9295c635efSGarrett D'Amore { man_SM_pre, NULL }, /* SM */ 9395c635efSGarrett D'Amore { man_SM_pre, NULL }, /* SB */ 9495c635efSGarrett D'Amore { man_alt_pre, NULL }, /* BI */ 9595c635efSGarrett D'Amore { man_alt_pre, NULL }, /* IB */ 9695c635efSGarrett D'Amore { man_alt_pre, NULL }, /* BR */ 9795c635efSGarrett D'Amore { man_alt_pre, NULL }, /* RB */ 9895c635efSGarrett D'Amore { NULL, NULL }, /* R */ 9995c635efSGarrett D'Amore { man_B_pre, NULL }, /* B */ 10095c635efSGarrett D'Amore { man_I_pre, NULL }, /* I */ 10195c635efSGarrett D'Amore { man_alt_pre, NULL }, /* IR */ 10295c635efSGarrett D'Amore { man_alt_pre, NULL }, /* RI */ 10395c635efSGarrett D'Amore { man_br_pre, NULL }, /* sp */ 10495c635efSGarrett D'Amore { man_literal_pre, NULL }, /* nf */ 10595c635efSGarrett D'Amore { man_literal_pre, NULL }, /* fi */ 10695c635efSGarrett D'Amore { NULL, NULL }, /* RE */ 10795c635efSGarrett D'Amore { man_RS_pre, NULL }, /* RS */ 10895c635efSGarrett D'Amore { man_ign_pre, NULL }, /* DT */ 10995c635efSGarrett D'Amore { man_ign_pre, NULL }, /* UC */ 11095c635efSGarrett D'Amore { man_ign_pre, NULL }, /* PD */ 11195c635efSGarrett D'Amore { man_ign_pre, NULL }, /* AT */ 11295c635efSGarrett D'Amore { man_in_pre, NULL }, /* in */ 11395c635efSGarrett D'Amore { man_ign_pre, NULL }, /* ft */ 11495c635efSGarrett D'Amore { man_OP_pre, NULL }, /* OP */ 115698f87a4SGarrett D'Amore { man_literal_pre, NULL }, /* EX */ 116698f87a4SGarrett D'Amore { man_literal_pre, NULL }, /* EE */ 117698f87a4SGarrett D'Amore { man_UR_pre, NULL }, /* UR */ 118698f87a4SGarrett D'Amore { NULL, NULL }, /* UE */ 119*260e9a87SYuri Pankov { man_ign_pre, NULL }, /* ll */ 12095c635efSGarrett D'Amore }; 12195c635efSGarrett D'Amore 122*260e9a87SYuri Pankov 12395c635efSGarrett D'Amore /* 12495c635efSGarrett D'Amore * Printing leading vertical space before a block. 12595c635efSGarrett D'Amore * This is used for the paragraph macros. 12695c635efSGarrett D'Amore * The rules are pretty simple, since there's very little nesting going 12795c635efSGarrett D'Amore * on here. Basically, if we're the first within another block (SS/SH), 12895c635efSGarrett D'Amore * then don't emit vertical space. If we are (RS), then do. If not the 12995c635efSGarrett D'Amore * first, print it. 13095c635efSGarrett D'Amore */ 13195c635efSGarrett D'Amore static void 13295c635efSGarrett D'Amore print_bvspace(struct html *h, const struct man_node *n) 13395c635efSGarrett D'Amore { 13495c635efSGarrett D'Amore 13595c635efSGarrett D'Amore if (n->body && n->body->child) 13695c635efSGarrett D'Amore if (MAN_TBL == n->body->child->type) 13795c635efSGarrett D'Amore return; 13895c635efSGarrett D'Amore 13995c635efSGarrett D'Amore if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) 14095c635efSGarrett D'Amore if (NULL == n->prev) 14195c635efSGarrett D'Amore return; 14295c635efSGarrett D'Amore 143*260e9a87SYuri Pankov print_paragraph(h); 14495c635efSGarrett D'Amore } 14595c635efSGarrett D'Amore 14695c635efSGarrett D'Amore void 147698f87a4SGarrett D'Amore html_man(void *arg, const struct man *man) 14895c635efSGarrett D'Amore { 14995c635efSGarrett D'Amore struct mhtml mh; 15095c635efSGarrett D'Amore 15195c635efSGarrett D'Amore memset(&mh, 0, sizeof(struct mhtml)); 152698f87a4SGarrett D'Amore print_man(man_meta(man), man_node(man), &mh, (struct html *)arg); 15395c635efSGarrett D'Amore putchar('\n'); 15495c635efSGarrett D'Amore } 15595c635efSGarrett D'Amore 15695c635efSGarrett D'Amore static void 15795c635efSGarrett D'Amore print_man(MAN_ARGS) 15895c635efSGarrett D'Amore { 15995c635efSGarrett D'Amore struct tag *t, *tt; 16095c635efSGarrett D'Amore struct htmlpair tag; 16195c635efSGarrett D'Amore 16295c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "mandoc"); 16395c635efSGarrett D'Amore 16495c635efSGarrett D'Amore if ( ! (HTML_FRAGMENT & h->oflags)) { 16595c635efSGarrett D'Amore print_gen_decls(h); 16695c635efSGarrett D'Amore t = print_otag(h, TAG_HTML, 0, NULL); 16795c635efSGarrett D'Amore tt = print_otag(h, TAG_HEAD, 0, NULL); 168698f87a4SGarrett D'Amore print_man_head(man, n, mh, h); 16995c635efSGarrett D'Amore print_tagq(h, tt); 17095c635efSGarrett D'Amore print_otag(h, TAG_BODY, 0, NULL); 17195c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 17295c635efSGarrett D'Amore } else 17395c635efSGarrett D'Amore t = print_otag(h, TAG_DIV, 1, &tag); 17495c635efSGarrett D'Amore 175698f87a4SGarrett D'Amore print_man_nodelist(man, n, mh, h); 17695c635efSGarrett D'Amore print_tagq(h, t); 17795c635efSGarrett D'Amore } 17895c635efSGarrett D'Amore 17995c635efSGarrett D'Amore static void 18095c635efSGarrett D'Amore print_man_head(MAN_ARGS) 18195c635efSGarrett D'Amore { 18295c635efSGarrett D'Amore 18395c635efSGarrett D'Amore print_gen_head(h); 184698f87a4SGarrett D'Amore assert(man->title); 185698f87a4SGarrett D'Amore assert(man->msec); 186698f87a4SGarrett D'Amore bufcat_fmt(h, "%s(%s)", man->title, man->msec); 18795c635efSGarrett D'Amore print_otag(h, TAG_TITLE, 0, NULL); 18895c635efSGarrett D'Amore print_text(h, h->buf); 18995c635efSGarrett D'Amore } 19095c635efSGarrett D'Amore 19195c635efSGarrett D'Amore static void 19295c635efSGarrett D'Amore print_man_nodelist(MAN_ARGS) 19395c635efSGarrett D'Amore { 19495c635efSGarrett D'Amore 195*260e9a87SYuri Pankov while (n != NULL) { 196698f87a4SGarrett D'Amore print_man_node(man, n, mh, h); 197*260e9a87SYuri Pankov n = n->next; 19895c635efSGarrett D'Amore } 199*260e9a87SYuri Pankov } 20095c635efSGarrett D'Amore 20195c635efSGarrett D'Amore static void 20295c635efSGarrett D'Amore print_man_node(MAN_ARGS) 20395c635efSGarrett D'Amore { 20495c635efSGarrett D'Amore int child; 20595c635efSGarrett D'Amore struct tag *t; 20695c635efSGarrett D'Amore 20795c635efSGarrett D'Amore child = 1; 20895c635efSGarrett D'Amore t = h->tags.head; 20995c635efSGarrett D'Amore 21095c635efSGarrett D'Amore switch (n->type) { 211*260e9a87SYuri Pankov case MAN_ROOT: 212698f87a4SGarrett D'Amore man_root_pre(man, n, mh, h); 21395c635efSGarrett D'Amore break; 214*260e9a87SYuri Pankov case MAN_TEXT: 21595c635efSGarrett D'Amore if ('\0' == *n->string) { 216*260e9a87SYuri Pankov print_paragraph(h); 21795c635efSGarrett D'Amore return; 21895c635efSGarrett D'Amore } 219*260e9a87SYuri Pankov if (n->flags & MAN_LINE && (*n->string == ' ' || 220*260e9a87SYuri Pankov (n->prev != NULL && mh->fl & MANH_LITERAL && 221*260e9a87SYuri Pankov ! (h->flags & HTML_NONEWLINE)))) 22295c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 22395c635efSGarrett D'Amore print_text(h, n->string); 22495c635efSGarrett D'Amore return; 225*260e9a87SYuri Pankov case MAN_EQN: 226*260e9a87SYuri Pankov if (n->flags & MAN_LINE) 227*260e9a87SYuri Pankov putchar('\n'); 22895c635efSGarrett D'Amore print_eqn(h, n->eqn); 22995c635efSGarrett D'Amore break; 230*260e9a87SYuri Pankov case MAN_TBL: 23195c635efSGarrett D'Amore /* 23295c635efSGarrett D'Amore * This will take care of initialising all of the table 23395c635efSGarrett D'Amore * state data for the first table, then tearing it down 23495c635efSGarrett D'Amore * for the last one. 23595c635efSGarrett D'Amore */ 23695c635efSGarrett D'Amore print_tbl(h, n->span); 23795c635efSGarrett D'Amore return; 23895c635efSGarrett D'Amore default: 23995c635efSGarrett D'Amore /* 24095c635efSGarrett D'Amore * Close out scope of font prior to opening a macro 24195c635efSGarrett D'Amore * scope. 24295c635efSGarrett D'Amore */ 24395c635efSGarrett D'Amore if (HTMLFONT_NONE != h->metac) { 24495c635efSGarrett D'Amore h->metal = h->metac; 24595c635efSGarrett D'Amore h->metac = HTMLFONT_NONE; 24695c635efSGarrett D'Amore } 24795c635efSGarrett D'Amore 24895c635efSGarrett D'Amore /* 24995c635efSGarrett D'Amore * Close out the current table, if it's open, and unset 25095c635efSGarrett D'Amore * the "meta" table state. This will be reopened on the 25195c635efSGarrett D'Amore * next table element. 25295c635efSGarrett D'Amore */ 25395c635efSGarrett D'Amore if (h->tblt) { 25495c635efSGarrett D'Amore print_tblclose(h); 25595c635efSGarrett D'Amore t = h->tags.head; 25695c635efSGarrett D'Amore } 25795c635efSGarrett D'Amore if (mans[n->tok].pre) 258698f87a4SGarrett D'Amore child = (*mans[n->tok].pre)(man, n, mh, h); 25995c635efSGarrett D'Amore break; 26095c635efSGarrett D'Amore } 26195c635efSGarrett D'Amore 26295c635efSGarrett D'Amore if (child && n->child) 263698f87a4SGarrett D'Amore print_man_nodelist(man, n->child, mh, h); 26495c635efSGarrett D'Amore 26595c635efSGarrett D'Amore /* This will automatically close out any font scope. */ 26695c635efSGarrett D'Amore print_stagq(h, t); 26795c635efSGarrett D'Amore 26895c635efSGarrett D'Amore switch (n->type) { 269*260e9a87SYuri Pankov case MAN_ROOT: 270698f87a4SGarrett D'Amore man_root_post(man, n, mh, h); 27195c635efSGarrett D'Amore break; 272*260e9a87SYuri Pankov case MAN_EQN: 27395c635efSGarrett D'Amore break; 27495c635efSGarrett D'Amore default: 27595c635efSGarrett D'Amore if (mans[n->tok].post) 276698f87a4SGarrett D'Amore (*mans[n->tok].post)(man, n, mh, h); 27795c635efSGarrett D'Amore break; 27895c635efSGarrett D'Amore } 27995c635efSGarrett D'Amore } 28095c635efSGarrett D'Amore 28195c635efSGarrett D'Amore static int 28295c635efSGarrett D'Amore a2width(const struct man_node *n, struct roffsu *su) 28395c635efSGarrett D'Amore { 28495c635efSGarrett D'Amore 28595c635efSGarrett D'Amore if (MAN_TEXT != n->type) 28695c635efSGarrett D'Amore return(0); 287*260e9a87SYuri Pankov if (a2roffsu(n->string, su, SCALE_EN)) 28895c635efSGarrett D'Amore return(1); 28995c635efSGarrett D'Amore 29095c635efSGarrett D'Amore return(0); 29195c635efSGarrett D'Amore } 29295c635efSGarrett D'Amore 29395c635efSGarrett D'Amore static void 29495c635efSGarrett D'Amore man_root_pre(MAN_ARGS) 29595c635efSGarrett D'Amore { 296*260e9a87SYuri Pankov struct htmlpair tag; 29795c635efSGarrett D'Amore struct tag *t, *tt; 298*260e9a87SYuri Pankov char *title; 29995c635efSGarrett D'Amore 300698f87a4SGarrett D'Amore assert(man->title); 301698f87a4SGarrett D'Amore assert(man->msec); 302*260e9a87SYuri Pankov mandoc_asprintf(&title, "%s(%s)", man->title, man->msec); 30395c635efSGarrett D'Amore 304*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "head"); 305*260e9a87SYuri Pankov t = print_otag(h, TAG_TABLE, 1, &tag); 30695c635efSGarrett D'Amore 30795c635efSGarrett D'Amore print_otag(h, TAG_TBODY, 0, NULL); 30895c635efSGarrett D'Amore 30995c635efSGarrett D'Amore tt = print_otag(h, TAG_TR, 0, NULL); 31095c635efSGarrett D'Amore 311*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "head-ltitle"); 312*260e9a87SYuri Pankov print_otag(h, TAG_TD, 1, &tag); 31395c635efSGarrett D'Amore print_text(h, title); 31495c635efSGarrett D'Amore print_stagq(h, tt); 31595c635efSGarrett D'Amore 316*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "head-vol"); 317*260e9a87SYuri Pankov print_otag(h, TAG_TD, 1, &tag); 318*260e9a87SYuri Pankov if (NULL != man->vol) 319*260e9a87SYuri Pankov print_text(h, man->vol); 32095c635efSGarrett D'Amore print_stagq(h, tt); 32195c635efSGarrett D'Amore 322*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "head-rtitle"); 323*260e9a87SYuri Pankov print_otag(h, TAG_TD, 1, &tag); 32495c635efSGarrett D'Amore print_text(h, title); 32595c635efSGarrett D'Amore print_tagq(h, t); 326*260e9a87SYuri Pankov free(title); 32795c635efSGarrett D'Amore } 32895c635efSGarrett D'Amore 32995c635efSGarrett D'Amore static void 33095c635efSGarrett D'Amore man_root_post(MAN_ARGS) 33195c635efSGarrett D'Amore { 332*260e9a87SYuri Pankov struct htmlpair tag; 33395c635efSGarrett D'Amore struct tag *t, *tt; 33495c635efSGarrett D'Amore 335*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "foot"); 336*260e9a87SYuri Pankov t = print_otag(h, TAG_TABLE, 1, &tag); 33795c635efSGarrett D'Amore 33895c635efSGarrett D'Amore tt = print_otag(h, TAG_TR, 0, NULL); 33995c635efSGarrett D'Amore 340*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "foot-date"); 341*260e9a87SYuri Pankov print_otag(h, TAG_TD, 1, &tag); 34295c635efSGarrett D'Amore 343698f87a4SGarrett D'Amore assert(man->date); 344698f87a4SGarrett D'Amore print_text(h, man->date); 34595c635efSGarrett D'Amore print_stagq(h, tt); 34695c635efSGarrett D'Amore 347*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag, "foot-os"); 348*260e9a87SYuri Pankov print_otag(h, TAG_TD, 1, &tag); 34995c635efSGarrett D'Amore 350698f87a4SGarrett D'Amore if (man->source) 351698f87a4SGarrett D'Amore print_text(h, man->source); 35295c635efSGarrett D'Amore print_tagq(h, t); 35395c635efSGarrett D'Amore } 35495c635efSGarrett D'Amore 35595c635efSGarrett D'Amore 35695c635efSGarrett D'Amore static int 35795c635efSGarrett D'Amore man_br_pre(MAN_ARGS) 35895c635efSGarrett D'Amore { 35995c635efSGarrett D'Amore struct roffsu su; 36095c635efSGarrett D'Amore struct htmlpair tag; 36195c635efSGarrett D'Amore 36295c635efSGarrett D'Amore SCALE_VS_INIT(&su, 1); 36395c635efSGarrett D'Amore 36495c635efSGarrett D'Amore if (MAN_sp == n->tok) { 36595c635efSGarrett D'Amore if (NULL != (n = n->child)) 36695c635efSGarrett D'Amore if ( ! a2roffsu(n->string, &su, SCALE_VS)) 367*260e9a87SYuri Pankov su.scale = 1.0; 36895c635efSGarrett D'Amore } else 369*260e9a87SYuri Pankov su.scale = 0.0; 37095c635efSGarrett D'Amore 37195c635efSGarrett D'Amore bufinit(h); 37295c635efSGarrett D'Amore bufcat_su(h, "height", &su); 37395c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 37495c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 37595c635efSGarrett D'Amore 37695c635efSGarrett D'Amore /* So the div isn't empty: */ 37795c635efSGarrett D'Amore print_text(h, "\\~"); 37895c635efSGarrett D'Amore 37995c635efSGarrett D'Amore return(0); 38095c635efSGarrett D'Amore } 38195c635efSGarrett D'Amore 38295c635efSGarrett D'Amore static int 38395c635efSGarrett D'Amore man_SH_pre(MAN_ARGS) 38495c635efSGarrett D'Amore { 38595c635efSGarrett D'Amore struct htmlpair tag; 38695c635efSGarrett D'Amore 38795c635efSGarrett D'Amore if (MAN_BLOCK == n->type) { 38895c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 38995c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "section"); 39095c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 39195c635efSGarrett D'Amore return(1); 39295c635efSGarrett D'Amore } else if (MAN_BODY == n->type) 39395c635efSGarrett D'Amore return(1); 39495c635efSGarrett D'Amore 39595c635efSGarrett D'Amore print_otag(h, TAG_H1, 0, NULL); 39695c635efSGarrett D'Amore return(1); 39795c635efSGarrett D'Amore } 39895c635efSGarrett D'Amore 39995c635efSGarrett D'Amore static int 40095c635efSGarrett D'Amore man_alt_pre(MAN_ARGS) 40195c635efSGarrett D'Amore { 40295c635efSGarrett D'Amore const struct man_node *nn; 40395c635efSGarrett D'Amore int i, savelit; 40495c635efSGarrett D'Amore enum htmltag fp; 40595c635efSGarrett D'Amore struct tag *t; 40695c635efSGarrett D'Amore 40795c635efSGarrett D'Amore if ((savelit = mh->fl & MANH_LITERAL)) 40895c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 40995c635efSGarrett D'Amore 41095c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 41195c635efSGarrett D'Amore 41295c635efSGarrett D'Amore for (i = 0, nn = n->child; nn; nn = nn->next, i++) { 41395c635efSGarrett D'Amore t = NULL; 41495c635efSGarrett D'Amore switch (n->tok) { 415*260e9a87SYuri Pankov case MAN_BI: 41695c635efSGarrett D'Amore fp = i % 2 ? TAG_I : TAG_B; 41795c635efSGarrett D'Amore break; 418*260e9a87SYuri Pankov case MAN_IB: 41995c635efSGarrett D'Amore fp = i % 2 ? TAG_B : TAG_I; 42095c635efSGarrett D'Amore break; 421*260e9a87SYuri Pankov case MAN_RI: 42295c635efSGarrett D'Amore fp = i % 2 ? TAG_I : TAG_MAX; 42395c635efSGarrett D'Amore break; 424*260e9a87SYuri Pankov case MAN_IR: 42595c635efSGarrett D'Amore fp = i % 2 ? TAG_MAX : TAG_I; 42695c635efSGarrett D'Amore break; 427*260e9a87SYuri Pankov case MAN_BR: 42895c635efSGarrett D'Amore fp = i % 2 ? TAG_MAX : TAG_B; 42995c635efSGarrett D'Amore break; 430*260e9a87SYuri Pankov case MAN_RB: 43195c635efSGarrett D'Amore fp = i % 2 ? TAG_B : TAG_MAX; 43295c635efSGarrett D'Amore break; 43395c635efSGarrett D'Amore default: 43495c635efSGarrett D'Amore abort(); 43595c635efSGarrett D'Amore /* NOTREACHED */ 43695c635efSGarrett D'Amore } 43795c635efSGarrett D'Amore 43895c635efSGarrett D'Amore if (i) 43995c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 44095c635efSGarrett D'Amore 44195c635efSGarrett D'Amore if (TAG_MAX != fp) 44295c635efSGarrett D'Amore t = print_otag(h, fp, 0, NULL); 44395c635efSGarrett D'Amore 444698f87a4SGarrett D'Amore print_man_node(man, nn, mh, h); 44595c635efSGarrett D'Amore 44695c635efSGarrett D'Amore if (t) 44795c635efSGarrett D'Amore print_tagq(h, t); 44895c635efSGarrett D'Amore } 44995c635efSGarrett D'Amore 45095c635efSGarrett D'Amore if (savelit) 45195c635efSGarrett D'Amore mh->fl |= MANH_LITERAL; 45295c635efSGarrett D'Amore 45395c635efSGarrett D'Amore return(0); 45495c635efSGarrett D'Amore } 45595c635efSGarrett D'Amore 45695c635efSGarrett D'Amore static int 45795c635efSGarrett D'Amore man_SM_pre(MAN_ARGS) 45895c635efSGarrett D'Amore { 45995c635efSGarrett D'Amore 46095c635efSGarrett D'Amore print_otag(h, TAG_SMALL, 0, NULL); 46195c635efSGarrett D'Amore if (MAN_SB == n->tok) 46295c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 46395c635efSGarrett D'Amore return(1); 46495c635efSGarrett D'Amore } 46595c635efSGarrett D'Amore 46695c635efSGarrett D'Amore static int 46795c635efSGarrett D'Amore man_SS_pre(MAN_ARGS) 46895c635efSGarrett D'Amore { 46995c635efSGarrett D'Amore struct htmlpair tag; 47095c635efSGarrett D'Amore 47195c635efSGarrett D'Amore if (MAN_BLOCK == n->type) { 47295c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 47395c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "subsection"); 47495c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 47595c635efSGarrett D'Amore return(1); 47695c635efSGarrett D'Amore } else if (MAN_BODY == n->type) 47795c635efSGarrett D'Amore return(1); 47895c635efSGarrett D'Amore 47995c635efSGarrett D'Amore print_otag(h, TAG_H2, 0, NULL); 48095c635efSGarrett D'Amore return(1); 48195c635efSGarrett D'Amore } 48295c635efSGarrett D'Amore 48395c635efSGarrett D'Amore static int 48495c635efSGarrett D'Amore man_PP_pre(MAN_ARGS) 48595c635efSGarrett D'Amore { 48695c635efSGarrett D'Amore 48795c635efSGarrett D'Amore if (MAN_HEAD == n->type) 48895c635efSGarrett D'Amore return(0); 48995c635efSGarrett D'Amore else if (MAN_BLOCK == n->type) 49095c635efSGarrett D'Amore print_bvspace(h, n); 49195c635efSGarrett D'Amore 49295c635efSGarrett D'Amore return(1); 49395c635efSGarrett D'Amore } 49495c635efSGarrett D'Amore 49595c635efSGarrett D'Amore static int 49695c635efSGarrett D'Amore man_IP_pre(MAN_ARGS) 49795c635efSGarrett D'Amore { 49895c635efSGarrett D'Amore const struct man_node *nn; 49995c635efSGarrett D'Amore 50095c635efSGarrett D'Amore if (MAN_BODY == n->type) { 50195c635efSGarrett D'Amore print_otag(h, TAG_DD, 0, NULL); 50295c635efSGarrett D'Amore return(1); 50395c635efSGarrett D'Amore } else if (MAN_HEAD != n->type) { 50495c635efSGarrett D'Amore print_otag(h, TAG_DL, 0, NULL); 50595c635efSGarrett D'Amore return(1); 50695c635efSGarrett D'Amore } 50795c635efSGarrett D'Amore 50895c635efSGarrett D'Amore /* FIXME: width specification. */ 50995c635efSGarrett D'Amore 51095c635efSGarrett D'Amore print_otag(h, TAG_DT, 0, NULL); 51195c635efSGarrett D'Amore 51295c635efSGarrett D'Amore /* For IP, only print the first header element. */ 51395c635efSGarrett D'Amore 51495c635efSGarrett D'Amore if (MAN_IP == n->tok && n->child) 515698f87a4SGarrett D'Amore print_man_node(man, n->child, mh, h); 51695c635efSGarrett D'Amore 51795c635efSGarrett D'Amore /* For TP, only print next-line header elements. */ 51895c635efSGarrett D'Amore 519*260e9a87SYuri Pankov if (MAN_TP == n->tok) { 520*260e9a87SYuri Pankov nn = n->child; 521*260e9a87SYuri Pankov while (NULL != nn && 0 == (MAN_LINE & nn->flags)) 522*260e9a87SYuri Pankov nn = nn->next; 523*260e9a87SYuri Pankov while (NULL != nn) { 524698f87a4SGarrett D'Amore print_man_node(man, nn, mh, h); 525*260e9a87SYuri Pankov nn = nn->next; 526*260e9a87SYuri Pankov } 527*260e9a87SYuri Pankov } 52895c635efSGarrett D'Amore 52995c635efSGarrett D'Amore return(0); 53095c635efSGarrett D'Amore } 53195c635efSGarrett D'Amore 53295c635efSGarrett D'Amore static int 53395c635efSGarrett D'Amore man_HP_pre(MAN_ARGS) 53495c635efSGarrett D'Amore { 535*260e9a87SYuri Pankov struct htmlpair tag[2]; 53695c635efSGarrett D'Amore struct roffsu su; 53795c635efSGarrett D'Amore const struct man_node *np; 53895c635efSGarrett D'Amore 53995c635efSGarrett D'Amore if (MAN_HEAD == n->type) 54095c635efSGarrett D'Amore return(0); 54195c635efSGarrett D'Amore else if (MAN_BLOCK != n->type) 54295c635efSGarrett D'Amore return(1); 54395c635efSGarrett D'Amore 54495c635efSGarrett D'Amore np = n->head->child; 54595c635efSGarrett D'Amore 54695c635efSGarrett D'Amore if (NULL == np || ! a2width(np, &su)) 54795c635efSGarrett D'Amore SCALE_HS_INIT(&su, INDENT); 54895c635efSGarrett D'Amore 54995c635efSGarrett D'Amore bufinit(h); 55095c635efSGarrett D'Amore 55195c635efSGarrett D'Amore print_bvspace(h, n); 55295c635efSGarrett D'Amore bufcat_su(h, "margin-left", &su); 55395c635efSGarrett D'Amore su.scale = -su.scale; 55495c635efSGarrett D'Amore bufcat_su(h, "text-indent", &su); 555*260e9a87SYuri Pankov PAIR_STYLE_INIT(&tag[0], h); 556*260e9a87SYuri Pankov PAIR_CLASS_INIT(&tag[1], "spacer"); 557*260e9a87SYuri Pankov print_otag(h, TAG_DIV, 2, tag); 55895c635efSGarrett D'Amore return(1); 55995c635efSGarrett D'Amore } 56095c635efSGarrett D'Amore 56195c635efSGarrett D'Amore static int 56295c635efSGarrett D'Amore man_OP_pre(MAN_ARGS) 56395c635efSGarrett D'Amore { 56495c635efSGarrett D'Amore struct tag *tt; 56595c635efSGarrett D'Amore struct htmlpair tag; 56695c635efSGarrett D'Amore 56795c635efSGarrett D'Amore print_text(h, "["); 56895c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 56995c635efSGarrett D'Amore PAIR_CLASS_INIT(&tag, "opt"); 57095c635efSGarrett D'Amore tt = print_otag(h, TAG_SPAN, 1, &tag); 57195c635efSGarrett D'Amore 57295c635efSGarrett D'Amore if (NULL != (n = n->child)) { 57395c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 57495c635efSGarrett D'Amore print_text(h, n->string); 57595c635efSGarrett D'Amore } 57695c635efSGarrett D'Amore 57795c635efSGarrett D'Amore print_stagq(h, tt); 57895c635efSGarrett D'Amore 57995c635efSGarrett D'Amore if (NULL != n && NULL != n->next) { 58095c635efSGarrett D'Amore print_otag(h, TAG_I, 0, NULL); 58195c635efSGarrett D'Amore print_text(h, n->next->string); 58295c635efSGarrett D'Amore } 58395c635efSGarrett D'Amore 58495c635efSGarrett D'Amore print_stagq(h, tt); 58595c635efSGarrett D'Amore h->flags |= HTML_NOSPACE; 58695c635efSGarrett D'Amore print_text(h, "]"); 58795c635efSGarrett D'Amore return(0); 58895c635efSGarrett D'Amore } 58995c635efSGarrett D'Amore 59095c635efSGarrett D'Amore static int 59195c635efSGarrett D'Amore man_B_pre(MAN_ARGS) 59295c635efSGarrett D'Amore { 59395c635efSGarrett D'Amore 59495c635efSGarrett D'Amore print_otag(h, TAG_B, 0, NULL); 59595c635efSGarrett D'Amore return(1); 59695c635efSGarrett D'Amore } 59795c635efSGarrett D'Amore 59895c635efSGarrett D'Amore static int 59995c635efSGarrett D'Amore man_I_pre(MAN_ARGS) 60095c635efSGarrett D'Amore { 60195c635efSGarrett D'Amore 60295c635efSGarrett D'Amore print_otag(h, TAG_I, 0, NULL); 60395c635efSGarrett D'Amore return(1); 60495c635efSGarrett D'Amore } 60595c635efSGarrett D'Amore 60695c635efSGarrett D'Amore static int 60795c635efSGarrett D'Amore man_literal_pre(MAN_ARGS) 60895c635efSGarrett D'Amore { 60995c635efSGarrett D'Amore 610698f87a4SGarrett D'Amore if (MAN_fi == n->tok || MAN_EE == n->tok) { 61195c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 61295c635efSGarrett D'Amore mh->fl &= ~MANH_LITERAL; 61395c635efSGarrett D'Amore } else 61495c635efSGarrett D'Amore mh->fl |= MANH_LITERAL; 61595c635efSGarrett D'Amore 61695c635efSGarrett D'Amore return(0); 61795c635efSGarrett D'Amore } 61895c635efSGarrett D'Amore 61995c635efSGarrett D'Amore static int 62095c635efSGarrett D'Amore man_in_pre(MAN_ARGS) 62195c635efSGarrett D'Amore { 62295c635efSGarrett D'Amore 62395c635efSGarrett D'Amore print_otag(h, TAG_BR, 0, NULL); 62495c635efSGarrett D'Amore return(0); 62595c635efSGarrett D'Amore } 62695c635efSGarrett D'Amore 62795c635efSGarrett D'Amore static int 62895c635efSGarrett D'Amore man_ign_pre(MAN_ARGS) 62995c635efSGarrett D'Amore { 63095c635efSGarrett D'Amore 63195c635efSGarrett D'Amore return(0); 63295c635efSGarrett D'Amore } 63395c635efSGarrett D'Amore 63495c635efSGarrett D'Amore static int 63595c635efSGarrett D'Amore man_RS_pre(MAN_ARGS) 63695c635efSGarrett D'Amore { 63795c635efSGarrett D'Amore struct htmlpair tag; 63895c635efSGarrett D'Amore struct roffsu su; 63995c635efSGarrett D'Amore 64095c635efSGarrett D'Amore if (MAN_HEAD == n->type) 64195c635efSGarrett D'Amore return(0); 64295c635efSGarrett D'Amore else if (MAN_BODY == n->type) 64395c635efSGarrett D'Amore return(1); 64495c635efSGarrett D'Amore 64595c635efSGarrett D'Amore SCALE_HS_INIT(&su, INDENT); 64695c635efSGarrett D'Amore if (n->head->child) 64795c635efSGarrett D'Amore a2width(n->head->child, &su); 64895c635efSGarrett D'Amore 64995c635efSGarrett D'Amore bufinit(h); 65095c635efSGarrett D'Amore bufcat_su(h, "margin-left", &su); 65195c635efSGarrett D'Amore PAIR_STYLE_INIT(&tag, h); 65295c635efSGarrett D'Amore print_otag(h, TAG_DIV, 1, &tag); 65395c635efSGarrett D'Amore return(1); 65495c635efSGarrett D'Amore } 655698f87a4SGarrett D'Amore 656698f87a4SGarrett D'Amore static int 657698f87a4SGarrett D'Amore man_UR_pre(MAN_ARGS) 658698f87a4SGarrett D'Amore { 659698f87a4SGarrett D'Amore struct htmlpair tag[2]; 660698f87a4SGarrett D'Amore 661698f87a4SGarrett D'Amore n = n->child; 662698f87a4SGarrett D'Amore assert(MAN_HEAD == n->type); 663698f87a4SGarrett D'Amore if (n->nchild) { 664698f87a4SGarrett D'Amore assert(MAN_TEXT == n->child->type); 665698f87a4SGarrett D'Amore PAIR_CLASS_INIT(&tag[0], "link-ext"); 666698f87a4SGarrett D'Amore PAIR_HREF_INIT(&tag[1], n->child->string); 667698f87a4SGarrett D'Amore print_otag(h, TAG_A, 2, tag); 668698f87a4SGarrett D'Amore } 669698f87a4SGarrett D'Amore 670698f87a4SGarrett D'Amore assert(MAN_BODY == n->next->type); 671698f87a4SGarrett D'Amore if (n->next->nchild) 672698f87a4SGarrett D'Amore n = n->next; 673698f87a4SGarrett D'Amore 674698f87a4SGarrett D'Amore print_man_nodelist(man, n->child, mh, h); 675698f87a4SGarrett D'Amore 676698f87a4SGarrett D'Amore return(0); 677698f87a4SGarrett D'Amore } 678