=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.33 retrieving revision 1.35 diff -u -p -r1.33 -r1.35 --- mandoc/html.c 2009/09/17 13:17:30 1.33 +++ mandoc/html.c 2009/09/20 11:05:22 1.35 @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.33 2009/09/17 13:17:30 kristaps Exp $ */ +/* $Id: html.c,v 1.35 2009/09/20 11:05:22 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -32,6 +32,7 @@ #define INDENT 5 #define HALFINDENT 3 +#define PX_MULT 8 enum htmltag { TAG_HTML, @@ -51,6 +52,9 @@ enum htmltag { TAG_COL, TAG_TR, TAG_TD, + TAG_LI, + TAG_UL, + TAG_OL, TAG_MAX }; @@ -94,6 +98,9 @@ static const struct htmldata htmltags[TAG_MAX] = { {"col", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_COL */ {"tr", HTML_CLRLINE}, /* TAG_TR */ {"td", HTML_CLRLINE}, /* TAG_TD */ + {"li", HTML_CLRLINE}, /* TAG_LI */ + {"ul", HTML_CLRLINE}, /* TAG_UL */ + {"ol", HTML_CLRLINE}, /* TAG_OL */ }; static const char *const htmlattrs[ATTR_MAX] = { @@ -164,28 +171,42 @@ static void print_spec(struct html *, const char *, static int a2width(const char *); static int a2offs(const char *); -static int mdoc_list_pre(MDOC_ARGS); +static int mdoc_list_pre(MDOC_ARGS, int); +static int mdoc_listitem_pre(MDOC_ARGS); static int mdoc_root_pre(MDOC_ARGS); -static int mdoc_hang_pre(MDOC_ARGS); +static int mdoc_tbl_pre(MDOC_ARGS, int); +static int mdoc_tbl_block_pre(MDOC_ARGS, int, int, int); +static int mdoc_tbl_body_pre(MDOC_ARGS, int, int); +static int mdoc_tbl_head_pre(MDOC_ARGS, int, int); static int mdoc_ar_pre(MDOC_ARGS); static int mdoc_bl_pre(MDOC_ARGS); +static int mdoc_d1_pre(MDOC_ARGS); +static void mdoc_dq_post(MDOC_ARGS); +static int mdoc_dq_pre(MDOC_ARGS); static int mdoc_fl_pre(MDOC_ARGS); +static int mdoc_em_pre(MDOC_ARGS); +static int mdoc_ex_pre(MDOC_ARGS); static int mdoc_it_pre(MDOC_ARGS); static int mdoc_nd_pre(MDOC_ARGS); static int mdoc_nm_pre(MDOC_ARGS); static int mdoc_ns_pre(MDOC_ARGS); -static int mdoc_op_pre(MDOC_ARGS); static void mdoc_op_post(MDOC_ARGS); +static int mdoc_op_pre(MDOC_ARGS); static int mdoc_pp_pre(MDOC_ARGS); +static void mdoc_pq_post(MDOC_ARGS); +static int mdoc_pq_pre(MDOC_ARGS); static int mdoc_sh_pre(MDOC_ARGS); +static void mdoc_sq_post(MDOC_ARGS); +static int mdoc_sq_pre(MDOC_ARGS); static int mdoc_ss_pre(MDOC_ARGS); +static int mdoc_sx_pre(MDOC_ARGS); static int mdoc_xr_pre(MDOC_ARGS); static int mdoc_xx_pre(MDOC_ARGS); #ifdef __linux__ -extern size_t strlcpy(char *, const char *, size_t); -extern size_t strlcat(char *, const char *, size_t); +extern size_t strlcpy(char *, const char *, size_t); +extern size_t strlcat(char *, const char *, size_t); #endif static const struct htmlmdoc mdocs[MDOC_MAX] = { @@ -196,8 +217,8 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {mdoc_sh_pre, NULL }, /* Sh */ {mdoc_ss_pre, NULL }, /* Ss */ {mdoc_pp_pre, NULL}, /* Pp */ - {NULL, NULL}, /* D1 */ - {NULL, NULL}, /* Dl */ + {mdoc_d1_pre, NULL}, /* D1 */ + {mdoc_d1_pre, NULL}, /* Dl */ {NULL, NULL}, /* Bd */ {NULL, NULL}, /* Ed */ {mdoc_bl_pre, NULL}, /* Bl */ @@ -211,7 +232,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {NULL, NULL}, /* Dv */ {NULL, NULL}, /* Er */ {NULL, NULL}, /* Ev */ - {NULL, NULL}, /* Ex */ + {mdoc_ex_pre, NULL}, /* Ex */ {NULL, NULL}, /* Fa */ {NULL, NULL}, /* Fd */ {mdoc_fl_pre, NULL}, /* Fl */ @@ -254,10 +275,10 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {NULL, NULL}, /* Db */ {NULL, NULL}, /* Dc */ {NULL, NULL}, /* Do */ - {NULL, NULL}, /* Dq */ + {mdoc_dq_pre, mdoc_dq_post}, /* Dq */ {NULL, NULL}, /* Ec */ {NULL, NULL}, /* Ef */ - {NULL, NULL}, /* Em */ + {mdoc_em_pre, NULL}, /* Em */ {NULL, NULL}, /* Eo */ {mdoc_xx_pre, NULL}, /* Fx */ {NULL, NULL}, /* Ms */ @@ -267,8 +288,8 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {mdoc_xx_pre, NULL}, /* Ox */ {NULL, NULL}, /* Pc */ {NULL, NULL}, /* Pf */ - {NULL, NULL}, /* Po */ - {NULL, NULL}, /* Pq */ + {mdoc_pq_pre, mdoc_pq_post}, /* Po */ + {mdoc_pq_pre, mdoc_pq_post}, /* Pq */ {NULL, NULL}, /* Qc */ {NULL, NULL}, /* Ql */ {NULL, NULL}, /* Qo */ @@ -276,10 +297,10 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {NULL, NULL}, /* Re */ {NULL, NULL}, /* Rs */ {NULL, NULL}, /* Sc */ - {NULL, NULL}, /* So */ - {NULL, NULL}, /* Sq */ + {mdoc_sq_pre, mdoc_sq_post}, /* So */ + {mdoc_sq_pre, mdoc_sq_post}, /* Sq */ {NULL, NULL}, /* Sm */ - {NULL, NULL}, /* Sx */ + {mdoc_sx_pre, NULL}, /* Sx */ {NULL, NULL}, /* Sy */ {NULL, NULL}, /* Tn */ {mdoc_xx_pre, NULL}, /* Ux */ @@ -311,7 +332,12 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {NULL, NULL}, /* sp */ }; +static char buf[BUFSIZ]; /* XXX */ +#define bufcat(x) (void)strlcat(buf, (x), BUFSIZ) +#define bufinit() buf[0] = 0 +#define buffmt(...) (void)snprintf(buf, BUFSIZ - 1, __VA_ARGS__) + void html_mdoc(void *arg, const struct mdoc *m) { @@ -406,7 +432,7 @@ print_gen_head(struct html *h) meta0[0].key = ATTR_HTTPEQUIV; meta0[0].val = "Content-Type"; meta0[1].key = ATTR_CONTENT; - meta0[1].val = "text/html; charest-utf-8"; + meta0[1].val = "text/html; charset=utf-8"; meta1[0].key = ATTR_NAME; meta1[0].val = "resource-type"; @@ -457,6 +483,8 @@ print_mdoc_node(MDOC_ARGS) child = 1; t = SLIST_FIRST(&h->stack); + bufinit(); + switch (n->type) { case (MDOC_ROOT): child = mdoc_root_pre(m, n, h); @@ -475,6 +503,8 @@ print_mdoc_node(MDOC_ARGS) print_stagq(h, t); + bufinit(); + switch (n->type) { case (MDOC_ROOT): break; @@ -663,11 +693,24 @@ print_encode(struct html *h, const char *p) { for (; *p; p++) { - if ('\\' != *p) { - putchar(*p); + if ('\\' == *p) { + print_escape(h, &p); continue; } - print_escape(h, &p); + switch (*p) { + case ('<'): + printf("<"); + break; + case ('>'): + printf(">"); + break; + case ('&'): + printf("&"); + break; + default: + putchar(*p); + break; + } } } @@ -819,6 +862,7 @@ print_stagq(struct html *h, const struct tag *suntil) } +/* FIXME: put in utility file for front-ends. */ static int a2offs(const char *p) { @@ -846,6 +890,7 @@ a2offs(const char *p) } +/* FIXME: put in utility file for front-ends. */ static int a2width(const char *p) { @@ -883,13 +928,78 @@ mdoc_root_pre(MDOC_ARGS) /* ARGSUSED */ static int +mdoc_sh_pre(MDOC_ARGS) +{ + struct htmlpair tag[2]; + + if (MDOC_HEAD == n->type) { + tag[0].key = ATTR_CLASS; + tag[0].val = "sec-head"; + print_otag(h, TAG_DIV, 1, tag); + print_otag(h, TAG_SPAN, 1, tag); + return(1); + } else if (MDOC_BLOCK == n->type) { + tag[0].key = ATTR_CLASS; + tag[0].val = "sec-block"; + print_otag(h, TAG_DIV, 1, tag); + return(1); + } + + buffmt("margin-left: %dem;", INDENT); + + if (n->parent->next && n->child) + bufcat("margin-bottom: 1em;"); + + tag[0].key = ATTR_CLASS; + tag[0].val = "sec-body"; + tag[1].key = ATTR_STYLE; + tag[1].val = buf; + + print_otag(h, TAG_DIV, 2, tag); + return(1); +} + + +/* ARGSUSED */ +static int mdoc_ss_pre(MDOC_ARGS) { + struct htmlpair tag[2]; + int i; - if (MDOC_BODY == n->type) - print_otag(h, TAG_DIV, 0, NULL); - if (MDOC_HEAD == n->type) - print_otag(h, TAG_H2, 0, NULL); + i = 0; + + if (MDOC_BODY == n->type) { + tag[i].key = ATTR_CLASS; + tag[i++].val = "ssec-body"; + if (n->parent->next && n->child) { + bufcat("margin-bottom: 1em;"); + tag[i].key = ATTR_STYLE; + tag[i++].val = buf; + } + print_otag(h, TAG_DIV, i, tag); + return(1); + } else if (MDOC_BLOCK == n->type) { + tag[i].key = ATTR_CLASS; + tag[i++].val = "ssec-block"; + if (n->prev) { + bufcat("margin-top: 1em;"); + tag[i].key = ATTR_STYLE; + tag[i++].val = buf; + } + print_otag(h, TAG_DIV, i, tag); + return(1); + } + + buffmt("margin-left: -%dem;", INDENT - HALFINDENT); + + tag[0].key = ATTR_CLASS; + tag[0].val = "ssec-head"; + tag[1].key = ATTR_STYLE; + tag[1].val = buf; + + print_otag(h, TAG_DIV, 2, tag); + print_otag(h, TAG_SPAN, 1, tag); return(1); } @@ -914,9 +1024,15 @@ mdoc_fl_pre(MDOC_ARGS) static int mdoc_pp_pre(MDOC_ARGS) { + struct htmlpair tag; - print_otag(h, TAG_BR, 0, NULL); - print_otag(h, TAG_BR, 0, NULL); + bufcat("clear: both;"); + bufcat("height: 1em;"); + + tag.key = ATTR_STYLE; + tag.val = buf; + + print_otag(h, TAG_DIV, 1, &tag); return(0); } @@ -925,9 +1041,16 @@ mdoc_pp_pre(MDOC_ARGS) static int mdoc_nd_pre(MDOC_ARGS) { + struct htmlpair tag; - if (MDOC_BODY == n->type) - print_text(h, "\\(en"); + if (MDOC_BODY != n->type) + return(1); + + /* XXX - this can contain block elements! */ + print_text(h, "\\(em"); + tag.key = ATTR_CLASS; + tag.val = "desc-body"; + print_otag(h, TAG_SPAN, 1, &tag); return(1); } @@ -936,11 +1059,16 @@ mdoc_nd_pre(MDOC_ARGS) static int mdoc_op_pre(MDOC_ARGS) { + struct htmlpair tag; - if (MDOC_BODY == n->type) { - print_text(h, "\\(lB"); - h->flags |= HTML_NOSPACE; - } + if (MDOC_BODY != n->type) + return(1); + + /* XXX - this can contain block elements! */ + print_text(h, "\\(lB"); + tag.key = ATTR_CLASS; + tag.val = "opt"; + print_otag(h, TAG_SPAN, 1, &tag); return(1); } @@ -960,16 +1088,19 @@ mdoc_op_post(MDOC_ARGS) static int mdoc_nm_pre(MDOC_ARGS) { - struct htmlpair class; + struct htmlpair tag; if ( ! (HTML_NEWLINE & h->flags)) - if (SEC_SYNOPSIS == n->sec) - print_otag(h, TAG_BR, 0, NULL); + if (SEC_SYNOPSIS == n->sec) { + tag.key = ATTR_STYLE; + tag.val = "clear: both;"; + print_otag(h, TAG_BR, 1, &tag); + } - class.key = ATTR_CLASS; - class.val = "name"; + tag.key = ATTR_CLASS; + tag.val = "name"; - print_otag(h, TAG_SPAN, 1, &class); + print_otag(h, TAG_SPAN, 1, &tag); if (NULL == n->child) print_text(h, m->name); @@ -979,27 +1110,16 @@ mdoc_nm_pre(MDOC_ARGS) /* ARGSUSED */ static int -mdoc_sh_pre(MDOC_ARGS) -{ - - if (MDOC_BODY == n->type) - print_otag(h, TAG_DIV, 0, NULL); - if (MDOC_HEAD == n->type) - print_otag(h, TAG_H1, 0, NULL); - return(1); -} - - -/* ARGSUSED */ -static int mdoc_xr_pre(MDOC_ARGS) { - struct htmlpair tag; + struct htmlpair tag[2]; - tag.key = ATTR_HREF; - tag.val = "#"; /* TODO */ + tag[0].key = ATTR_CLASS; + tag[0].val = "link-man"; + tag[1].key = ATTR_HREF; + tag[1].val = "#"; /* TODO */ - print_otag(h, TAG_A, 1, &tag); + print_otag(h, TAG_A, 2, tag); n = n->child; print_text(h, n->string); @@ -1026,6 +1146,7 @@ mdoc_ns_pre(MDOC_ARGS) return(1); } + /* ARGSUSED */ static int mdoc_ar_pre(MDOC_ARGS) @@ -1039,11 +1160,13 @@ mdoc_ar_pre(MDOC_ARGS) return(1); } + /* ARGSUSED */ static int mdoc_xx_pre(MDOC_ARGS) { const char *pp; + struct htmlpair tag; switch (n->tok) { case (MDOC_Bsx): @@ -1068,97 +1191,224 @@ mdoc_xx_pre(MDOC_ARGS) return(1); } + tag.key = ATTR_CLASS; + tag.val = "unix"; + + print_otag(h, TAG_SPAN, 1, &tag); print_text(h, pp); return(1); } +/* ARGSUSED */ static int -mdoc_hang_pre(MDOC_ARGS) +mdoc_tbl_block_pre(MDOC_ARGS, int w, int o, int c) { - int i, width, offs; - struct htmlpair tag; - char buf[BUFSIZ]; - const struct mdoc_node *bl; + struct htmlpair tag; - if (MDOC_BODY == n->type) { - print_otag(h, TAG_DIV, 0, NULL); - return(1); + buffmt("margin-left: %dem; clear: both;", w + o); + + if ( ! c) + bufcat("padding-top: 1em;"); + + tag.key = ATTR_STYLE; + tag.val = buf; + print_otag(h, TAG_DIV, 1, &tag); + return(1); +} + + +/* ARGSUSED */ +static int +mdoc_tbl_body_pre(MDOC_ARGS, int t, int w) +{ + struct htmlpair tag; + int i; + + switch (t) { + case (MDOC_Tag): + i = 1; + tag.key = ATTR_STYLE; + tag.val = buf; + bufcat("clear: right;"); + bufcat("float: left;"); + bufcat("width: 100%%;"); + break; + default: + i = 0; + break; } + print_otag(h, TAG_DIV, i, &tag); + return(1); +} + + +/* ARGSUSED */ +static int +mdoc_tbl_head_pre(MDOC_ARGS, int t, int w) +{ + struct htmlpair tag; + int i; + + switch (t) { + case (MDOC_Hang): + /* FALLTHROUGH */ + case (MDOC_Tag): + i = 1; + tag.key = ATTR_STYLE; + tag.val = buf; + buffmt("margin-left: -%dem;", w); + bufcat("clear: left;"); + bufcat("float: left;"); + bufcat("padding-right: 1em;"); + break; + default: + i = 0; + break; + } + + print_otag(h, TAG_DIV, i, &tag); + return(1); +} + + +static int +mdoc_tbl_pre(MDOC_ARGS, int type) +{ + int i, w, o, c; + const struct mdoc_node *bl; + bl = n->parent->parent; if (MDOC_BLOCK != n->type) bl = bl->parent; + /* FIXME: fmt_vspace() equivalent. */ + assert(bl->args); - for (width = i = 0; i < (int)bl->args->argc; i++) + w = o = c = 0; + + for (i = 0; i < (int)bl->args->argc; i++) if (MDOC_Width == bl->args->argv[i].arg) { assert(bl->args->argv[i].sz); - width = a2width(bl->args->argv[i].value[0]); - break; + w = a2width(bl->args->argv[i].value[0]); } else if (MDOC_Offset == bl->args->argv[i].arg) { assert(bl->args->argv[i].sz); - offs = a2offs(bl->args->argv[i].value[0]); - break; - } + o = a2offs(bl->args->argv[i].value[0]); + } else if (MDOC_Compact == bl->args->argv[i].arg) + c = 1; - if (0 == width) - width = 10; + if (0 == w) + w = 10; + + switch (n->type) { + case (MDOC_BLOCK): + break; + case (MDOC_HEAD): + return(mdoc_tbl_head_pre(m, n, h, type, w)); + case (MDOC_BODY): + return(mdoc_tbl_body_pre(m, n, h, type, w)); + default: + abort(); + /* NOTREACHED */ + } - width *= 10; + return(mdoc_tbl_block_pre(m, n, h, w, o, c)); +} - if (MDOC_BLOCK == n->type) - snprintf(buf, BUFSIZ - 1, "margin-left: %dpx; " - "clear: both;", width); - else - snprintf(buf, BUFSIZ - 1, "float: left; " - "margin-left: -%dpx;", width); +/* ARGSUSED */ +static int +mdoc_listitem_pre(MDOC_ARGS) +{ + int i, w, o, c; + const struct mdoc_node *bl; + struct htmlpair tag; + + /* FIXME: fmt_vspace() equivalent. */ + + if (MDOC_BLOCK != n->type) + return(1); + + bl = n->parent->parent; + assert(bl); + + w = o = c = 0; + + for (i = 0; i < (int)bl->args->argc; i++) + if (MDOC_Width == bl->args->argv[i].arg) { + assert(bl->args->argv[i].sz); + w = a2width(bl->args->argv[i].value[0]); + } else if (MDOC_Offset == bl->args->argv[i].arg) { + assert(bl->args->argv[i].sz); + o = a2offs(bl->args->argv[i].value[0]); + } else if (MDOC_Compact == bl->args->argv[i].arg) + c = 1; + + if (o && w) + buffmt("margin-left: %dem; padding-left: %dem;", o, w); + else if (w) + buffmt("padding-left: %dem;", w > 4 ? w - 4 : w); + else if (o) + buffmt("margin-left: %dem;", o); + + if ( ! c) + bufcat("padding-top: 1em;"); + tag.key = ATTR_STYLE; tag.val = buf; - print_otag(h, TAG_DIV, 1, &tag); - + print_otag(h, TAG_LI, 1, &tag); return(1); } +/* ARGSUSED */ static int -mdoc_list_pre(MDOC_ARGS) +mdoc_list_pre(MDOC_ARGS, int type) { - /* TODO */ - return(0); + switch (type) { + case (MDOC_Enum): + print_otag(h, TAG_OL, 0, NULL); + break; + case (MDOC_Bullet): + print_otag(h, TAG_UL, 0, NULL); + break; + default: + break; + } + + return(1); } static int -mdoc_it_pre(MDOC_ARGS) +mdoc_bl_pre(MDOC_ARGS) { - int i, len; - const struct mdoc_node *bl; + int i, len, type; - if (MDOC_BLOCK == n->type) - bl = n->parent->parent; - else - bl = n->parent->parent->parent; + if (MDOC_BLOCK != n->type) + return(1); - assert(bl->args); - len = (int)bl->args->argc; + assert(n->args); + len = (int)n->args->argc; for (i = 0; i < len; i++) - switch (bl->args->argv[i].arg) { + switch ((type = n->args->argv[i].arg)) { + case (MDOC_Enum): + /* FALLTHROUGH */ case (MDOC_Bullet): + return(mdoc_list_pre(m, n, h, type)); + case (MDOC_Tag): /* FALLTHROUGH */ + case (MDOC_Hang): + /* FALLTHROUGH */ case (MDOC_Dash): /* FALLTHROUGH */ - case (MDOC_Enum): - /* FALLTHROUGH */ case (MDOC_Hyphen): - return(0); /* TODO */ - case (MDOC_Tag): - return(0); + /* FALLTHROUGH */ case (MDOC_Inset): /* FALLTHROUGH */ case (MDOC_Diag): @@ -1167,14 +1417,10 @@ mdoc_it_pre(MDOC_ARGS) /* FALLTHROUGH */ case (MDOC_Column): /* FALLTHROUGH */ - case (MDOC_Hang): - return(mdoc_hang_pre(m, n, h)); - /* FALLTHROUGH */ case (MDOC_Ohang): - return(0); /* TODO */ + return(1); default: - abort(); - /* NOTREACHED */ + break; } abort(); @@ -1183,28 +1429,33 @@ mdoc_it_pre(MDOC_ARGS) static int -mdoc_bl_pre(MDOC_ARGS) +mdoc_it_pre(MDOC_ARGS) { - int i, len; + int i, len, type; + const struct mdoc_node *bl; - if (MDOC_BLOCK != n->type) - return(1); + if (MDOC_BLOCK == n->type) + bl = n->parent->parent; + else + bl = n->parent->parent->parent; - assert(n->args); - len = (int)n->args->argc; + assert(bl->args); + len = (int)bl->args->argc; for (i = 0; i < len; i++) - switch (n->args->argv[i].arg) { - case (MDOC_Bullet): + switch ((type = bl->args->argv[i].arg)) { + case (MDOC_Tag): /* FALLTHROUGH */ - case (MDOC_Dash): - /* FALLTHROUGH */ + case (MDOC_Hang): + return(mdoc_tbl_pre(m, n, h, type)); case (MDOC_Enum): /* FALLTHROUGH */ + case (MDOC_Bullet): + return(mdoc_listitem_pre(m, n, h)); + case (MDOC_Dash): + /* FALLTHROUGH */ case (MDOC_Hyphen): - return(mdoc_list_pre(m, n, h)); - case (MDOC_Tag): - return(0); + /* FALLTHROUGH */ case (MDOC_Inset): /* FALLTHROUGH */ case (MDOC_Diag): @@ -1213,15 +1464,176 @@ mdoc_bl_pre(MDOC_ARGS) /* FALLTHROUGH */ case (MDOC_Column): /* FALLTHROUGH */ - case (MDOC_Hang): - return(1); case (MDOC_Ohang): - return(0); /* TODO */ + return(0); default: - abort(); - /* NOTREACHED */ + break; } abort(); /* NOTREACHED */ +} + + +/* ARGSUSED */ +static int +mdoc_ex_pre(MDOC_ARGS) +{ + const struct mdoc_node *nn; + struct tag *t; + struct htmlpair tag; + + print_text(h, "The"); + + tag.key = ATTR_CLASS; + tag.val = "utility"; + + for (nn = n->child; nn; nn = nn->next) { + t = print_otag(h, TAG_SPAN, 1, &tag); + print_text(h, nn->string); + print_tagq(h, t); + + h->flags |= HTML_NOSPACE; + + if (nn->next && NULL == nn->next->next) + print_text(h, ", and"); + else if (nn->next) + print_text(h, ","); + else + h->flags &= ~HTML_NOSPACE; + } + + if (n->child->next) + print_text(h, "utilities exit"); + else + print_text(h, "utility exits"); + + print_text(h, "0 on success, and >0 if an error occurs."); + return(0); +} + + +/* ARGSUSED */ +static int +mdoc_dq_pre(MDOC_ARGS) +{ + + if (MDOC_BODY != n->type) + return(1); + print_text(h, "\\(lq"); + h->flags |= HTML_NOSPACE; + return(1); +} + + +/* ARGSUSED */ +static void +mdoc_dq_post(MDOC_ARGS) +{ + + if (MDOC_BODY != n->type) + return; + h->flags |= HTML_NOSPACE; + print_text(h, "\\(rq"); +} + + +/* ARGSUSED */ +static int +mdoc_pq_pre(MDOC_ARGS) +{ + + if (MDOC_BODY != n->type) + return(1); + print_text(h, "\\&("); + h->flags |= HTML_NOSPACE; + return(1); +} + + +/* ARGSUSED */ +static void +mdoc_pq_post(MDOC_ARGS) +{ + + if (MDOC_BODY != n->type) + return; + print_text(h, ")"); +} + + +/* ARGSUSED */ +static int +mdoc_sq_pre(MDOC_ARGS) +{ + + if (MDOC_BODY != n->type) + return(1); + print_text(h, "\\(oq"); + h->flags |= HTML_NOSPACE; + return(1); +} + + +/* ARGSUSED */ +static void +mdoc_sq_post(MDOC_ARGS) +{ + + if (MDOC_BODY != n->type) + return; + h->flags |= HTML_NOSPACE; + print_text(h, "\\(aq"); +} + + +/* ARGSUSED */ +static int +mdoc_em_pre(MDOC_ARGS) +{ + struct htmlpair tag; + + tag.key = ATTR_CLASS; + tag.val = "emph"; + + print_otag(h, TAG_SPAN, 1, &tag); + return(1); +} + + +/* ARGSUSED */ +static int +mdoc_d1_pre(MDOC_ARGS) +{ + struct htmlpair tag[2]; + + if (MDOC_BLOCK != n->type) + return(1); + + buffmt("margin-left: %dem;", INDENT); + bufcat("margin-bottom: 0px;"); + + tag[0].key = ATTR_CLASS; + tag[0].val = "lit-block"; + tag[1].key = ATTR_STYLE; + tag[1].val = buf; + + print_otag(h, TAG_DIV, 2, tag); + return(1); +} + + +/* ARGSUSED */ +static int +mdoc_sx_pre(MDOC_ARGS) +{ + struct htmlpair tag[2]; + + tag[0].key = ATTR_HREF; + tag[0].val = "#"; /* XXX */ + tag[1].key = ATTR_CLASS; + tag[1].val = "link-sec"; + + print_otag(h, TAG_A, 2, tag); + return(1); }