Return to man_html.c CVS log | Up to [cvsweb.bsd.lv] / mandoc |
version 1.62, 2011/01/07 13:20:58 | version 1.101, 2014/09/27 09:20:03 | ||
---|---|---|---|
|
|
||
/* $Id$ */ | /* $Id$ */ | ||
/* | /* | ||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> | * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> | ||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> | |||
* | * | ||
* Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||
|
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | */ | ||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | #include "config.h" | ||
#endif | |||
#include <sys/types.h> | #include <sys/types.h> | ||
|
|
||
#include <string.h> | #include <string.h> | ||
#include "mandoc.h" | #include "mandoc.h" | ||
#include "mandoc_aux.h" | |||
#include "out.h" | #include "out.h" | ||
#include "html.h" | #include "html.h" | ||
#include "man.h" | #include "man.h" | ||
|
|
||
/* FIXME: have PD set the default vspace width. */ | /* FIXME: have PD set the default vspace width. */ | ||
#define INDENT 5 | #define INDENT 5 | ||
#define HALFINDENT 3 | |||
#define MAN_ARGS const struct man_meta *m, \ | #define MAN_ARGS const struct man_meta *man, \ | ||
const struct man_node *n, \ | const struct man_node *n, \ | ||
struct mhtml *mh, \ | struct mhtml *mh, \ | ||
struct html *h | struct html *h | ||
|
|
||
int (*post)(MAN_ARGS); | int (*post)(MAN_ARGS); | ||
}; | }; | ||
static void print_bvspace(struct html *, | |||
const struct man_node *); | |||
static void print_man(MAN_ARGS); | static void print_man(MAN_ARGS); | ||
static void print_man_head(MAN_ARGS); | static void print_man_head(MAN_ARGS); | ||
static void print_man_nodelist(MAN_ARGS); | static void print_man_nodelist(MAN_ARGS); | ||
static void print_man_node(MAN_ARGS); | static void print_man_node(MAN_ARGS); | ||
static int a2width(const struct man_node *, | static int a2width(const struct man_node *, | ||
struct roffsu *); | struct roffsu *); | ||
static int man_alt_pre(MAN_ARGS); | |||
static int man_br_pre(MAN_ARGS); | |||
static int man_ign_pre(MAN_ARGS); | |||
static int man_in_pre(MAN_ARGS); | |||
static int man_literal_pre(MAN_ARGS); | |||
static void man_root_post(MAN_ARGS); | |||
static int man_root_pre(MAN_ARGS); | |||
static int man_B_pre(MAN_ARGS); | static int man_B_pre(MAN_ARGS); | ||
static int man_HP_pre(MAN_ARGS); | static int man_HP_pre(MAN_ARGS); | ||
static int man_I_pre(MAN_ARGS); | |||
static int man_IP_pre(MAN_ARGS); | static int man_IP_pre(MAN_ARGS); | ||
static int man_I_pre(MAN_ARGS); | |||
static int man_OP_pre(MAN_ARGS); | |||
static int man_PP_pre(MAN_ARGS); | static int man_PP_pre(MAN_ARGS); | ||
static int man_RS_pre(MAN_ARGS); | static int man_RS_pre(MAN_ARGS); | ||
static int man_SH_pre(MAN_ARGS); | static int man_SH_pre(MAN_ARGS); | ||
static int man_SM_pre(MAN_ARGS); | static int man_SM_pre(MAN_ARGS); | ||
static int man_SS_pre(MAN_ARGS); | static int man_SS_pre(MAN_ARGS); | ||
static int man_UR_pre(MAN_ARGS); | |||
static int man_alt_pre(MAN_ARGS); | |||
static int man_br_pre(MAN_ARGS); | |||
static int man_ign_pre(MAN_ARGS); | |||
static int man_in_pre(MAN_ARGS); | |||
static int man_literal_pre(MAN_ARGS); | |||
static void man_root_post(MAN_ARGS); | |||
static void man_root_pre(MAN_ARGS); | |||
static const struct htmlman mans[MAN_MAX] = { | static const struct htmlman mans[MAN_MAX] = { | ||
{ man_br_pre, NULL }, /* br */ | { man_br_pre, NULL }, /* br */ | ||
|
|
||
{ man_PP_pre, NULL }, /* PP */ | { man_PP_pre, NULL }, /* PP */ | ||
{ man_PP_pre, NULL }, /* P */ | { man_PP_pre, NULL }, /* P */ | ||
{ man_IP_pre, NULL }, /* IP */ | { man_IP_pre, NULL }, /* IP */ | ||
{ man_HP_pre, NULL }, /* HP */ | { man_HP_pre, NULL }, /* HP */ | ||
{ man_SM_pre, NULL }, /* SM */ | { man_SM_pre, NULL }, /* SM */ | ||
{ man_SM_pre, NULL }, /* SB */ | { man_SM_pre, NULL }, /* SB */ | ||
{ man_alt_pre, NULL }, /* BI */ | { man_alt_pre, NULL }, /* BI */ | ||
|
|
||
{ man_I_pre, NULL }, /* I */ | { man_I_pre, NULL }, /* I */ | ||
{ man_alt_pre, NULL }, /* IR */ | { man_alt_pre, NULL }, /* IR */ | ||
{ man_alt_pre, NULL }, /* RI */ | { man_alt_pre, NULL }, /* RI */ | ||
{ NULL, NULL }, /* na */ | { man_ign_pre, NULL }, /* na */ | ||
{ man_br_pre, NULL }, /* sp */ | { man_br_pre, NULL }, /* sp */ | ||
{ man_literal_pre, NULL }, /* nf */ | { man_literal_pre, NULL }, /* nf */ | ||
{ man_literal_pre, NULL }, /* fi */ | { man_literal_pre, NULL }, /* fi */ | ||
|
|
||
{ man_ign_pre, NULL }, /* AT */ | { man_ign_pre, NULL }, /* AT */ | ||
{ man_in_pre, NULL }, /* in */ | { man_in_pre, NULL }, /* in */ | ||
{ man_ign_pre, NULL }, /* ft */ | { man_ign_pre, NULL }, /* ft */ | ||
{ man_OP_pre, NULL }, /* OP */ | |||
{ man_literal_pre, NULL }, /* EX */ | |||
{ man_literal_pre, NULL }, /* EE */ | |||
{ man_UR_pre, NULL }, /* UR */ | |||
{ NULL, NULL }, /* UE */ | |||
{ man_ign_pre, NULL }, /* ll */ | |||
}; | }; | ||
void | /* | ||
html_man(void *arg, const struct man *m) | * Printing leading vertical space before a block. | ||
* This is used for the paragraph macros. | |||
* The rules are pretty simple, since there's very little nesting going | |||
* on here. Basically, if we're the first within another block (SS/SH), | |||
* then don't emit vertical space. If we are (RS), then do. If not the | |||
* first, print it. | |||
*/ | |||
static void | |||
print_bvspace(struct html *h, const struct man_node *n) | |||
{ | { | ||
struct html *h; | |||
struct tag *t; | |||
struct mhtml mh; | |||
h = (struct html *)arg; | if (n->body && n->body->child) | ||
if (MAN_TBL == n->body->child->type) | |||
return; | |||
print_gen_decls(h); | if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) | ||
if (NULL == n->prev) | |||
return; | |||
memset(&mh, 0, sizeof(struct mhtml)); | print_otag(h, TAG_P, 0, NULL); | ||
} | |||
t = print_otag(h, TAG_HTML, 0, NULL); | void | ||
print_man(man_meta(m), man_node(m), &mh, h); | html_man(void *arg, const struct man *man) | ||
print_tagq(h, t); | { | ||
struct mhtml mh; | |||
printf("\n"); | memset(&mh, 0, sizeof(struct mhtml)); | ||
print_man(man_meta(man), man_node(man), &mh, (struct html *)arg); | |||
putchar('\n'); | |||
} | } | ||
static void | static void | ||
print_man(MAN_ARGS) | print_man(MAN_ARGS) | ||
{ | { | ||
struct tag *t; | struct tag *t, *tt; | ||
struct htmlpair tag; | |||
t = print_otag(h, TAG_HEAD, 0, NULL); | PAIR_CLASS_INIT(&tag, "mandoc"); | ||
print_man_head(m, n, mh, h); | |||
print_tagq(h, t); | |||
t = print_otag(h, TAG_BODY, 0, NULL); | if ( ! (HTML_FRAGMENT & h->oflags)) { | ||
print_man_nodelist(m, n, mh, h); | print_gen_decls(h); | ||
t = print_otag(h, TAG_HTML, 0, NULL); | |||
tt = print_otag(h, TAG_HEAD, 0, NULL); | |||
print_man_head(man, n, mh, h); | |||
print_tagq(h, tt); | |||
print_otag(h, TAG_BODY, 0, NULL); | |||
print_otag(h, TAG_DIV, 1, &tag); | |||
} else | |||
t = print_otag(h, TAG_DIV, 1, &tag); | |||
print_man_nodelist(man, n, mh, h); | |||
print_tagq(h, t); | print_tagq(h, t); | ||
} | } | ||
/* ARGSUSED */ | |||
static void | static void | ||
print_man_head(MAN_ARGS) | print_man_head(MAN_ARGS) | ||
{ | { | ||
print_gen_head(h); | print_gen_head(h); | ||
bufinit(h); | assert(man->title); | ||
buffmt(h, "%s(%s)", m->title, m->msec); | assert(man->msec); | ||
bufcat_fmt(h, "%s(%s)", man->title, man->msec); | |||
print_otag(h, TAG_TITLE, 0, NULL); | print_otag(h, TAG_TITLE, 0, NULL); | ||
print_text(h, h->buf); | print_text(h, h->buf); | ||
} | } | ||
static void | static void | ||
print_man_nodelist(MAN_ARGS) | print_man_nodelist(MAN_ARGS) | ||
{ | { | ||
print_man_node(m, n, mh, h); | print_man_node(man, n, mh, h); | ||
if (n->next) | if (n->next) | ||
print_man_nodelist(m, n->next, mh, h); | print_man_nodelist(man, n->next, mh, h); | ||
} | } | ||
static void | static void | ||
print_man_node(MAN_ARGS) | print_man_node(MAN_ARGS) | ||
{ | { | ||
|
|
||
child = 1; | child = 1; | ||
t = h->tags.head; | t = h->tags.head; | ||
bufinit(h); | |||
/* | |||
* FIXME: embedded elements within next-line scopes (e.g., `br' | |||
* within an empty `B') will cause formatting to be forgotten | |||
* due to scope closing out. | |||
*/ | |||
switch (n->type) { | switch (n->type) { | ||
case (MAN_ROOT): | case MAN_ROOT: | ||
child = man_root_pre(m, n, mh, h); | man_root_pre(man, n, mh, h); | ||
break; | break; | ||
case (MAN_TEXT): | case MAN_TEXT: | ||
print_text(h, n->string); | /* | ||
if (MANH_LITERAL & mh->fl) | * If we have a blank line, output a vertical space. | ||
* If we have a space as the first character, break | |||
* before printing the line's data. | |||
*/ | |||
if ('\0' == *n->string) { | |||
print_otag(h, TAG_P, 0, NULL); | |||
return; | |||
} | |||
if (' ' == *n->string && MAN_LINE & n->flags) | |||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, 0, NULL); | ||
else if (MANH_LITERAL & mh->fl && n->prev) | |||
print_otag(h, TAG_BR, 0, NULL); | |||
print_text(h, n->string); | |||
return; | return; | ||
case (MAN_TBL): | case MAN_EQN: | ||
print_tbl(h, n->span); | print_eqn(h, n->eqn); | ||
break; | break; | ||
case MAN_TBL: | |||
/* | |||
* This will take care of initialising all of the table | |||
* state data for the first table, then tearing it down | |||
* for the last one. | |||
*/ | |||
print_tbl(h, n->span); | |||
return; | |||
default: | default: | ||
/* | /* | ||
* Close out scope of font prior to opening a macro | * Close out scope of font prior to opening a macro | ||
* scope. Assert that the metafont is on the top of the | * scope. | ||
* stack (it's never nested). | |||
*/ | */ | ||
if (HTMLFONT_NONE != h->metac) { | if (HTMLFONT_NONE != h->metac) { | ||
h->metal = h->metac; | h->metal = h->metac; | ||
h->metac = HTMLFONT_NONE; | h->metac = HTMLFONT_NONE; | ||
} | } | ||
/* | |||
* Close out the current table, if it's open, and unset | |||
* the "meta" table state. This will be reopened on the | |||
* next table element. | |||
*/ | |||
if (h->tblt) { | |||
print_tblclose(h); | |||
t = h->tags.head; | |||
} | |||
if (mans[n->tok].pre) | if (mans[n->tok].pre) | ||
child = (*mans[n->tok].pre)(m, n, mh, h); | child = (*mans[n->tok].pre)(man, n, mh, h); | ||
break; | break; | ||
} | } | ||
if (child && n->child) | if (child && n->child) | ||
print_man_nodelist(m, n->child, mh, h); | print_man_nodelist(man, n->child, mh, h); | ||
/* This will automatically close out any font scope. */ | /* This will automatically close out any font scope. */ | ||
print_stagq(h, t); | print_stagq(h, t); | ||
bufinit(h); | |||
switch (n->type) { | switch (n->type) { | ||
case (MAN_ROOT): | case MAN_ROOT: | ||
man_root_post(m, n, mh, h); | man_root_post(man, n, mh, h); | ||
break; | break; | ||
case (MAN_TBL): | case MAN_EQN: | ||
break; | break; | ||
default: | default: | ||
if (mans[n->tok].post) | if (mans[n->tok].post) | ||
(*mans[n->tok].post)(m, n, mh, h); | (*mans[n->tok].post)(man, n, mh, h); | ||
break; | break; | ||
} | } | ||
} | } | ||
static int | static int | ||
a2width(const struct man_node *n, struct roffsu *su) | a2width(const struct man_node *n, struct roffsu *su) | ||
{ | { | ||
|
|
||
return(0); | return(0); | ||
} | } | ||
static void | |||
/* ARGSUSED */ | |||
static int | |||
man_root_pre(MAN_ARGS) | man_root_pre(MAN_ARGS) | ||
{ | { | ||
struct htmlpair tag[3]; | struct htmlpair tag; | ||
struct tag *t, *tt; | struct tag *t, *tt; | ||
char b[BUFSIZ], title[BUFSIZ]; | char *title; | ||
b[0] = 0; | assert(man->title); | ||
if (m->vol) | assert(man->msec); | ||
(void)strlcat(b, m->vol, BUFSIZ); | mandoc_asprintf(&title, "%s(%s)", man->title, man->msec); | ||
snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec); | PAIR_CLASS_INIT(&tag, "head"); | ||
t = print_otag(h, TAG_TABLE, 1, &tag); | |||
PAIR_INIT(&tag, ATTR_WIDTH, "30%"); | |||
print_otag(h, TAG_COL, 1, &tag); | |||
print_otag(h, TAG_COL, 1, &tag); | |||
print_otag(h, TAG_COL, 1, &tag); | |||
PAIR_SUMMARY_INIT(&tag[0], "Document Header"); | |||
PAIR_CLASS_INIT(&tag[1], "head"); | |||
if (NULL == h->style) { | |||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%"); | |||
t = print_otag(h, TAG_TABLE, 3, tag); | |||
PAIR_INIT(&tag[0], ATTR_WIDTH, "30%"); | |||
print_otag(h, TAG_COL, 1, tag); | |||
print_otag(h, TAG_COL, 1, tag); | |||
print_otag(h, TAG_COL, 1, tag); | |||
} else | |||
t = print_otag(h, TAG_TABLE, 2, tag); | |||
print_otag(h, TAG_TBODY, 0, NULL); | print_otag(h, TAG_TBODY, 0, NULL); | ||
tt = print_otag(h, TAG_TR, 0, NULL); | tt = print_otag(h, TAG_TR, 0, NULL); | ||
PAIR_CLASS_INIT(&tag[0], "head-ltitle"); | PAIR_CLASS_INIT(&tag, "head-ltitle"); | ||
print_otag(h, TAG_TD, 1, tag); | print_otag(h, TAG_TD, 1, &tag); | ||
print_text(h, title); | print_text(h, title); | ||
print_stagq(h, tt); | print_stagq(h, tt); | ||
PAIR_CLASS_INIT(&tag[0], "head-vol"); | PAIR_CLASS_INIT(&tag, "head-vol"); | ||
if (NULL == h->style) { | print_otag(h, TAG_TD, 1, &tag); | ||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center"); | if (NULL != man->vol) | ||
print_otag(h, TAG_TD, 2, tag); | print_text(h, man->vol); | ||
} else | |||
print_otag(h, TAG_TD, 1, tag); | |||
print_text(h, b); | |||
print_stagq(h, tt); | print_stagq(h, tt); | ||
PAIR_CLASS_INIT(&tag[0], "head-rtitle"); | PAIR_CLASS_INIT(&tag, "head-rtitle"); | ||
if (NULL == h->style) { | print_otag(h, TAG_TD, 1, &tag); | ||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); | |||
print_otag(h, TAG_TD, 2, tag); | |||
} else | |||
print_otag(h, TAG_TD, 1, tag); | |||
print_text(h, title); | print_text(h, title); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
return(1); | free(title); | ||
} | } | ||
/* ARGSUSED */ | |||
static void | static void | ||
man_root_post(MAN_ARGS) | man_root_post(MAN_ARGS) | ||
{ | { | ||
struct htmlpair tag[3]; | struct htmlpair tag; | ||
struct tag *t, *tt; | struct tag *t, *tt; | ||
char b[DATESIZ]; | |||
if (m->rawdate) | PAIR_CLASS_INIT(&tag, "foot"); | ||
strlcpy(b, m->rawdate, DATESIZ); | t = print_otag(h, TAG_TABLE, 1, &tag); | ||
else | PAIR_INIT(&tag, ATTR_WIDTH, "50%"); | ||
time2a(m->date, b, DATESIZ); | print_otag(h, TAG_COL, 1, &tag); | ||
print_otag(h, TAG_COL, 1, &tag); | |||
PAIR_SUMMARY_INIT(&tag[0], "Document Footer"); | |||
PAIR_CLASS_INIT(&tag[1], "foot"); | |||
if (NULL == h->style) { | |||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%"); | |||
t = print_otag(h, TAG_TABLE, 3, tag); | |||
PAIR_INIT(&tag[0], ATTR_WIDTH, "50%"); | |||
print_otag(h, TAG_COL, 1, tag); | |||
print_otag(h, TAG_COL, 1, tag); | |||
} else | |||
t = print_otag(h, TAG_TABLE, 2, tag); | |||
tt = print_otag(h, TAG_TR, 0, NULL); | tt = print_otag(h, TAG_TR, 0, NULL); | ||
PAIR_CLASS_INIT(&tag[0], "foot-date"); | PAIR_CLASS_INIT(&tag, "foot-date"); | ||
print_otag(h, TAG_TD, 1, tag); | print_otag(h, TAG_TD, 1, &tag); | ||
print_text(h, b); | assert(man->date); | ||
print_text(h, man->date); | |||
print_stagq(h, tt); | print_stagq(h, tt); | ||
PAIR_CLASS_INIT(&tag[0], "foot-os"); | PAIR_CLASS_INIT(&tag, "foot-os"); | ||
if (NULL == h->style) { | print_otag(h, TAG_TD, 1, &tag); | ||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); | |||
print_otag(h, TAG_TD, 2, tag); | |||
} else | |||
print_otag(h, TAG_TD, 1, tag); | |||
if (m->source) | if (man->source) | ||
print_text(h, m->source); | print_text(h, man->source); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_br_pre(MAN_ARGS) | man_br_pre(MAN_ARGS) | ||
{ | { | ||
|
|
||
SCALE_VS_INIT(&su, 1); | SCALE_VS_INIT(&su, 1); | ||
if (MAN_sp == n->tok) { | if (MAN_sp == n->tok) { | ||
if (n->child) | if (NULL != (n = n->child)) | ||
a2roffsu(n->child->string, &su, SCALE_VS); | if ( ! a2roffsu(n->string, &su, SCALE_VS)) | ||
SCALE_VS_INIT(&su, atoi(n->string)); | |||
} else | } else | ||
su.scale = 0; | su.scale = 0.0; | ||
bufinit(h); | |||
bufcat_su(h, "height", &su); | bufcat_su(h, "height", &su); | ||
PAIR_STYLE_INIT(&tag, h); | PAIR_STYLE_INIT(&tag, h); | ||
print_otag(h, TAG_DIV, 1, &tag); | print_otag(h, TAG_DIV, 1, &tag); | ||
|
|
||
return(0); | return(0); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_SH_pre(MAN_ARGS) | man_SH_pre(MAN_ARGS) | ||
{ | { | ||
struct htmlpair tag; | struct htmlpair tag; | ||
if (MAN_BLOCK == n->type) { | if (MAN_BLOCK == n->type) { | ||
mh->fl &= ~MANH_LITERAL; | |||
PAIR_CLASS_INIT(&tag, "section"); | PAIR_CLASS_INIT(&tag, "section"); | ||
print_otag(h, TAG_DIV, 1, &tag); | print_otag(h, TAG_DIV, 1, &tag); | ||
return(1); | return(1); | ||
|
|
||
return(1); | return(1); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_alt_pre(MAN_ARGS) | man_alt_pre(MAN_ARGS) | ||
{ | { | ||
const struct man_node *nn; | const struct man_node *nn; | ||
int i; | int i, savelit; | ||
enum htmltag fp; | enum htmltag fp; | ||
struct tag *t; | struct tag *t; | ||
if ((savelit = mh->fl & MANH_LITERAL)) | |||
print_otag(h, TAG_BR, 0, NULL); | |||
mh->fl &= ~MANH_LITERAL; | |||
for (i = 0, nn = n->child; nn; nn = nn->next, i++) { | for (i = 0, nn = n->child; nn; nn = nn->next, i++) { | ||
t = NULL; | t = NULL; | ||
switch (n->tok) { | switch (n->tok) { | ||
case (MAN_BI): | case MAN_BI: | ||
fp = i % 2 ? TAG_I : TAG_B; | fp = i % 2 ? TAG_I : TAG_B; | ||
break; | break; | ||
case (MAN_IB): | case MAN_IB: | ||
fp = i % 2 ? TAG_B : TAG_I; | fp = i % 2 ? TAG_B : TAG_I; | ||
break; | break; | ||
case (MAN_RI): | case MAN_RI: | ||
fp = i % 2 ? TAG_I : TAG_MAX; | fp = i % 2 ? TAG_I : TAG_MAX; | ||
break; | break; | ||
case (MAN_IR): | case MAN_IR: | ||
fp = i % 2 ? TAG_MAX : TAG_I; | fp = i % 2 ? TAG_MAX : TAG_I; | ||
break; | break; | ||
case (MAN_BR): | case MAN_BR: | ||
fp = i % 2 ? TAG_MAX : TAG_B; | fp = i % 2 ? TAG_MAX : TAG_B; | ||
break; | break; | ||
case (MAN_RB): | case MAN_RB: | ||
fp = i % 2 ? TAG_B : TAG_MAX; | fp = i % 2 ? TAG_B : TAG_MAX; | ||
break; | break; | ||
default: | default: | ||
|
|
||
if (TAG_MAX != fp) | if (TAG_MAX != fp) | ||
t = print_otag(h, fp, 0, NULL); | t = print_otag(h, fp, 0, NULL); | ||
print_man_node(m, nn, mh, h); | print_man_node(man, nn, mh, h); | ||
if (t) | if (t) | ||
print_tagq(h, t); | print_tagq(h, t); | ||
} | } | ||
if (savelit) | |||
mh->fl |= MANH_LITERAL; | |||
return(0); | return(0); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_SM_pre(MAN_ARGS) | man_SM_pre(MAN_ARGS) | ||
{ | { | ||
print_otag(h, TAG_SMALL, 0, NULL); | print_otag(h, TAG_SMALL, 0, NULL); | ||
if (MAN_SB == n->tok) | if (MAN_SB == n->tok) | ||
print_otag(h, TAG_B, 0, NULL); | print_otag(h, TAG_B, 0, NULL); | ||
return(1); | return(1); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_SS_pre(MAN_ARGS) | man_SS_pre(MAN_ARGS) | ||
{ | { | ||
struct htmlpair tag; | struct htmlpair tag; | ||
if (MAN_BLOCK == n->type) { | if (MAN_BLOCK == n->type) { | ||
mh->fl &= ~MANH_LITERAL; | |||
PAIR_CLASS_INIT(&tag, "subsection"); | PAIR_CLASS_INIT(&tag, "subsection"); | ||
print_otag(h, TAG_DIV, 1, &tag); | print_otag(h, TAG_DIV, 1, &tag); | ||
return(1); | return(1); | ||
|
|
||
return(1); | return(1); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_PP_pre(MAN_ARGS) | man_PP_pre(MAN_ARGS) | ||
{ | { | ||
if (MAN_HEAD == n->type) | if (MAN_HEAD == n->type) | ||
return(0); | return(0); | ||
else if (MAN_BODY == n->type && n->prev) | else if (MAN_BLOCK == n->type) | ||
print_otag(h, TAG_P, 0, NULL); | print_bvspace(h, n); | ||
return(1); | return(1); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_IP_pre(MAN_ARGS) | man_IP_pre(MAN_ARGS) | ||
{ | { | ||
struct roffsu su; | |||
struct htmlpair tag; | |||
const struct man_node *nn; | const struct man_node *nn; | ||
/* | if (MAN_BODY == n->type) { | ||
* This scattering of 1-BU margins and pads is to make sure that | print_otag(h, TAG_DD, 0, NULL); | ||
* when text overruns its box, the subsequent text isn't flush | |||
* up against it. However, the rest of the right-hand box must | |||
* also be adjusted in consideration of this 1-BU space. | |||
*/ | |||
if (MAN_BODY == n->type) { | |||
print_otag(h, TAG_TD, 0, NULL); | |||
return(1); | return(1); | ||
} else if (MAN_HEAD != n->type) { | |||
print_otag(h, TAG_DL, 0, NULL); | |||
return(1); | |||
} | } | ||
nn = MAN_BLOCK == n->type ? | /* FIXME: width specification. */ | ||
n->head->child : n->parent->head->child; | |||
SCALE_HS_INIT(&su, INDENT); | print_otag(h, TAG_DT, 0, NULL); | ||
/* Width is the second token. */ | |||
if (MAN_IP == n->tok && NULL != nn) | |||
if (NULL != (nn = nn->next)) | |||
a2width(nn, &su); | |||
/* Width is the first token. */ | |||
if (MAN_TP == n->tok && NULL != nn) { | |||
/* Skip past non-text children. */ | |||
while (nn && MAN_TEXT != nn->type) | |||
nn = nn->next; | |||
if (nn) | |||
a2width(nn, &su); | |||
} | |||
if (MAN_BLOCK == n->type) { | |||
print_otag(h, TAG_P, 0, NULL); | |||
print_otag(h, TAG_TABLE, 0, NULL); | |||
bufcat_su(h, "width", &su); | |||
PAIR_STYLE_INIT(&tag, h); | |||
print_otag(h, TAG_COL, 1, &tag); | |||
print_otag(h, TAG_COL, 0, NULL); | |||
print_otag(h, TAG_TBODY, 0, NULL); | |||
print_otag(h, TAG_TR, 0, NULL); | |||
return(1); | |||
} | |||
print_otag(h, TAG_TD, 0, NULL); | |||
/* For IP, only print the first header element. */ | /* For IP, only print the first header element. */ | ||
if (MAN_IP == n->tok && n->child) | if (MAN_IP == n->tok && n->child) | ||
print_man_node(m, n->child, mh, h); | print_man_node(man, n->child, mh, h); | ||
/* For TP, only print next-line header elements. */ | /* For TP, only print next-line header elements. */ | ||
if (MAN_TP == n->tok) | if (MAN_TP == n->tok) { | ||
for (nn = n->child; nn; nn = nn->next) | nn = n->child; | ||
if (nn->line > n->line) | while (NULL != nn && 0 == (MAN_LINE & nn->flags)) | ||
print_man_node(m, nn, mh, h); | nn = nn->next; | ||
while (NULL != nn) { | |||
print_man_node(man, nn, mh, h); | |||
nn = nn->next; | |||
} | |||
} | |||
return(0); | return(0); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_HP_pre(MAN_ARGS) | man_HP_pre(MAN_ARGS) | ||
{ | { | ||
|
|
||
struct roffsu su; | struct roffsu su; | ||
const struct man_node *np; | const struct man_node *np; | ||
np = MAN_BLOCK == n->type ? | if (MAN_HEAD == n->type) | ||
n->head->child : | return(0); | ||
n->parent->head->child; | else if (MAN_BLOCK != n->type) | ||
return(1); | |||
np = n->head->child; | |||
if (NULL == np || ! a2width(np, &su)) | if (NULL == np || ! a2width(np, &su)) | ||
SCALE_HS_INIT(&su, INDENT); | SCALE_HS_INIT(&su, INDENT); | ||
if (MAN_HEAD == n->type) { | bufinit(h); | ||
print_otag(h, TAG_TD, 0, NULL); | |||
return(0); | |||
} else if (MAN_BLOCK == n->type) { | |||
print_otag(h, TAG_P, 0, NULL); | |||
print_otag(h, TAG_TABLE, 0, NULL); | |||
bufcat_su(h, "width", &su); | |||
PAIR_STYLE_INIT(&tag, h); | |||
print_otag(h, TAG_COL, 1, &tag); | |||
print_otag(h, TAG_COL, 0, NULL); | |||
print_otag(h, TAG_TBODY, 0, NULL); | |||
print_otag(h, TAG_TR, 0, NULL); | |||
return(1); | |||
} | |||
print_bvspace(h, n); | |||
bufcat_su(h, "margin-left", &su); | |||
su.scale = -su.scale; | su.scale = -su.scale; | ||
bufcat_su(h, "text-indent", &su); | bufcat_su(h, "text-indent", &su); | ||
PAIR_STYLE_INIT(&tag, h); | PAIR_STYLE_INIT(&tag, h); | ||
print_otag(h, TAG_TD, 1, &tag); | print_otag(h, TAG_P, 1, &tag); | ||
return(1); | return(1); | ||
} | } | ||
static int | |||
man_OP_pre(MAN_ARGS) | |||
{ | |||
struct tag *tt; | |||
struct htmlpair tag; | |||
/* ARGSUSED */ | print_text(h, "["); | ||
h->flags |= HTML_NOSPACE; | |||
PAIR_CLASS_INIT(&tag, "opt"); | |||
tt = print_otag(h, TAG_SPAN, 1, &tag); | |||
if (NULL != (n = n->child)) { | |||
print_otag(h, TAG_B, 0, NULL); | |||
print_text(h, n->string); | |||
} | |||
print_stagq(h, tt); | |||
if (NULL != n && NULL != n->next) { | |||
print_otag(h, TAG_I, 0, NULL); | |||
print_text(h, n->next->string); | |||
} | |||
print_stagq(h, tt); | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, "]"); | |||
return(0); | |||
} | |||
static int | static int | ||
man_B_pre(MAN_ARGS) | man_B_pre(MAN_ARGS) | ||
{ | { | ||
|
|
||
return(1); | return(1); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_I_pre(MAN_ARGS) | man_I_pre(MAN_ARGS) | ||
{ | { | ||
print_otag(h, TAG_I, 0, NULL); | print_otag(h, TAG_I, 0, NULL); | ||
return(1); | return(1); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_literal_pre(MAN_ARGS) | man_literal_pre(MAN_ARGS) | ||
{ | { | ||
if (MAN_nf == n->tok) { | if (MAN_fi == n->tok || MAN_EE == n->tok) { | ||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, 0, NULL); | ||
mh->fl |= MANH_LITERAL; | |||
} else | |||
mh->fl &= ~MANH_LITERAL; | mh->fl &= ~MANH_LITERAL; | ||
} else | |||
mh->fl |= MANH_LITERAL; | |||
return(1); | return(0); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_in_pre(MAN_ARGS) | man_in_pre(MAN_ARGS) | ||
{ | { | ||
|
|
||
return(0); | return(0); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_ign_pre(MAN_ARGS) | man_ign_pre(MAN_ARGS) | ||
{ | { | ||
|
|
||
return(0); | return(0); | ||
} | } | ||
/* ARGSUSED */ | |||
static int | static int | ||
man_RS_pre(MAN_ARGS) | man_RS_pre(MAN_ARGS) | ||
{ | { | ||
|
|
||
if (n->head->child) | if (n->head->child) | ||
a2width(n->head->child, &su); | a2width(n->head->child, &su); | ||
bufinit(h); | |||
bufcat_su(h, "margin-left", &su); | bufcat_su(h, "margin-left", &su); | ||
PAIR_STYLE_INIT(&tag, h); | PAIR_STYLE_INIT(&tag, h); | ||
print_otag(h, TAG_DIV, 1, &tag); | print_otag(h, TAG_DIV, 1, &tag); | ||
return(1); | return(1); | ||
} | |||
static int | |||
man_UR_pre(MAN_ARGS) | |||
{ | |||
struct htmlpair tag[2]; | |||
n = n->child; | |||
assert(MAN_HEAD == n->type); | |||
if (n->nchild) { | |||
assert(MAN_TEXT == n->child->type); | |||
PAIR_CLASS_INIT(&tag[0], "link-ext"); | |||
PAIR_HREF_INIT(&tag[1], n->child->string); | |||
print_otag(h, TAG_A, 2, tag); | |||
} | |||
assert(MAN_BODY == n->next->type); | |||
if (n->next->nchild) | |||
n = n->next; | |||
print_man_nodelist(man, n->child, mh, h); | |||
return(0); | |||
} | } |