=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.41 retrieving revision 1.49 diff -u -p -r1.41 -r1.49 --- mandoc/html.c 2009/09/21 00:39:02 1.41 +++ mandoc/html.c 2009/09/21 14:08:13 1.49 @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.41 2009/09/21 00:39:02 kristaps Exp $ */ +/* $Id: html.c,v 1.49 2009/09/21 14:08:13 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -23,11 +23,11 @@ #include #include #include +#include #include "chars.h" #include "mdoc.h" #include "man.h" -#include "out.h" #define DOCTYPE "-//W3C//DTD HTML 4.01//EN" #define DTD "http://www.w3.org/TR/html4/strict.dtd" @@ -180,6 +180,10 @@ static void print_text(struct html *, const char *) static void print_res(struct html *, const char *, int); static void print_spec(struct html *, const char *, int); +static int a2width(const char *); +static int a2offs(const char *); +static int a2list(const struct mdoc_node *); + static void mdoc_root_post(MDOC_ARGS); static int mdoc_root_pre(MDOC_ARGS); static int mdoc_tbl_pre(MDOC_ARGS, int); @@ -216,12 +220,12 @@ static int mdoc_ns_pre(MDOC_ARGS); static void mdoc_op_post(MDOC_ARGS); static int mdoc_op_pre(MDOC_ARGS); static int mdoc_pa_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 void mdoc_qq_post(MDOC_ARGS); static int mdoc_qq_pre(MDOC_ARGS); static int mdoc_sh_pre(MDOC_ARGS); +static int mdoc_sp_pre(MDOC_ARGS); static void mdoc_sq_post(MDOC_ARGS); static int mdoc_sq_pre(MDOC_ARGS); static int mdoc_ss_pre(MDOC_ARGS); @@ -231,18 +235,19 @@ static int mdoc_xr_pre(MDOC_ARGS); static int mdoc_xx_pre(MDOC_ARGS); #ifdef __linux__ +extern int getsubopt(char **, char * const *, char **); 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] = { - {mdoc_pp_pre, NULL}, /* Ap */ + {NULL, NULL}, /* Ap */ {NULL, NULL}, /* Dd */ {NULL, NULL}, /* Dt */ {NULL, NULL}, /* Os */ {mdoc_sh_pre, NULL }, /* Sh */ {mdoc_ss_pre, NULL }, /* Ss */ - {mdoc_pp_pre, NULL}, /* Pp */ + {mdoc_sp_pre, NULL}, /* Pp */ {mdoc_d1_pre, NULL}, /* D1 */ {mdoc_d1_pre, NULL}, /* Dl */ {mdoc_bd_pre, NULL}, /* Bd */ @@ -343,7 +348,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {NULL, NULL}, /* Fr */ {NULL, NULL}, /* Ud */ {NULL, NULL}, /* Lb */ - {NULL, NULL}, /* Lp */ + {mdoc_sp_pre, NULL}, /* Lp */ {NULL, NULL}, /* Lk */ {NULL, NULL}, /* Mt */ {NULL, NULL}, /* Brq */ @@ -354,8 +359,8 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {NULL, NULL}, /* En */ {mdoc_xx_pre, NULL}, /* Dx */ {NULL, NULL}, /* %Q */ - {NULL, NULL}, /* br */ - {NULL, NULL}, /* sp */ + {mdoc_sp_pre, NULL}, /* br */ + {mdoc_sp_pre, NULL}, /* sp */ }; static char buf[BUFSIZ]; /* XXX */ @@ -399,10 +404,15 @@ html_man(void *arg, const struct man *m) void * -html_alloc(void) +html_alloc(char *outopts) { struct html *h; + char *toks[3], *v; + toks[0] = "style"; + toks[1] = "base"; + toks[2] = NULL; + if (NULL == (h = calloc(1, sizeof(struct html)))) return(NULL); @@ -414,8 +424,18 @@ html_alloc(void) return(NULL); } - /* h->base = xxx; */ - /* h->style = xxx; */ + while (outopts && *outopts) + switch (getsubopt(&outopts, toks, &v)) { + case (0): + h->style = v; + break; + case (1): + h->base = v; + break; + default: + break; + } + return(h); } @@ -447,16 +467,109 @@ html_free(void *p) } +static int +a2list(const struct mdoc_node *n) +{ + int i; + + assert(MDOC_BLOCK == n->type && MDOC_Bl == n->tok); + assert(n->args); + + for (i = 0; i < (int)n->args->argc; i++) + switch (n->args->argv[i].arg) { + case (MDOC_Enum): + /* FALLTHROUGH */ + case (MDOC_Dash): + /* FALLTHROUGH */ + case (MDOC_Hyphen): + /* FALLTHROUGH */ + case (MDOC_Bullet): + /* FALLTHROUGH */ + case (MDOC_Tag): + /* FALLTHROUGH */ + case (MDOC_Hang): + /* FALLTHROUGH */ + case (MDOC_Inset): + /* FALLTHROUGH */ + case (MDOC_Diag): + /* FALLTHROUGH */ + case (MDOC_Item): + /* FALLTHROUGH */ + case (MDOC_Column): + /* FALLTHROUGH */ + case (MDOC_Ohang): + return(n->args->argv[i].arg); + default: + break; + } + + abort(); + /* NOTREACHED */ +} + + +static int +a2width(const char *p) +{ + int i, len; + + if (0 == (len = (int)strlen(p))) + return(0); + for (i = 0; i < len - 1; i++) + if ( ! isdigit((u_char)p[i])) + break; + + if (i == len - 1) + if ('n' == p[len - 1] || 'm' == p[len - 1]) + return(atoi(p) + 2); + + return(len + 2); +} + + +static int +a2offs(const char *p) +{ + int len, i; + + if (0 == strcmp(p, "left")) + return(0); + if (0 == strcmp(p, "indent")) + return(INDENT + 1); + if (0 == strcmp(p, "indent-two")) + return((INDENT + 1) * 2); + + if (0 == (len = (int)strlen(p))) + return(0); + + for (i = 0; i < len - 1; i++) + if ( ! isdigit((u_char)p[i])) + break; + + if (i == len - 1) + if ('n' == p[len - 1] || 'm' == p[len - 1]) + return(atoi(p)); + + return(len); +} + + static void print_mdoc(MDOC_ARGS) { struct tag *t; + struct htmlpair tag; t = print_otag(h, TAG_HEAD, 0, NULL); print_mdoc_head(m, n, h); print_tagq(h, t); t = print_otag(h, TAG_BODY, 0, NULL); + + tag.key = ATTR_CLASS; + tag.val = "body"; + print_otag(h, TAG_DIV, 1, &tag); + print_mdoc_nodelist(m, n, h); print_tagq(h, t); } @@ -808,7 +921,7 @@ static void print_gen_doctype(struct html *h) { - printf("\n", DOCTYPE, DTD); + printf("", DOCTYPE, DTD); } @@ -952,14 +1065,10 @@ mdoc_root_pre(MDOC_ARGS) "%s(%d)", m->title, m->msec); tag[0].key = ATTR_CLASS; - tag[0].val = "body"; - t = print_otag(h, TAG_DIV, 1, tag); - - tag[0].key = ATTR_CLASS; tag[0].val = "header"; tag[1].key = ATTR_STYLE; tag[1].val = "width: 100%;"; - print_otag(h, TAG_TABLE, 2, tag); + t = print_otag(h, TAG_TABLE, 2, tag); tt = print_otag(h, TAG_TR, 0, NULL); tag[0].key = ATTR_STYLE; @@ -978,7 +1087,7 @@ mdoc_root_pre(MDOC_ARGS) tag[0].val = "width: 33%; text-align: right;"; print_otag(h, TAG_TD, 1, tag); print_text(h, b); - print_stagq(h, t); + print_tagq(h, t); return(1); } @@ -1114,19 +1223,6 @@ mdoc_fl_pre(MDOC_ARGS) /* ARGSUSED */ static int -mdoc_pp_pre(MDOC_ARGS) -{ - struct htmlpair tag; - - tag.key = ATTR_STYLE; - tag.val = "clear: both; height: 1em;"; - print_otag(h, TAG_DIV, 1, &tag); - return(0); -} - - -/* ARGSUSED */ -static int mdoc_nd_pre(MDOC_ARGS) { struct htmlpair tag; @@ -1154,6 +1250,7 @@ mdoc_op_pre(MDOC_ARGS) /* XXX - this can contain block elements! */ print_text(h, "\\(lB"); + h->flags |= HTML_NOSPACE; tag.key = ATTR_CLASS; tag.val = "opt"; print_otag(h, TAG_SPAN, 1, &tag); @@ -1315,8 +1412,12 @@ mdoc_tbl_block_pre(MDOC_ARGS, int t, int w, int o, int break; } - if ( ! c && n->prev && n->prev->body->child) - bufcat("padding-top: 1em;"); + if ( ! c && MDOC_Column != t) { + if (n->prev && n->prev->body->child) + bufcat("padding-top: 1em;"); + else if (NULL == n->prev) + bufcat("padding-top: 1em;"); + } tag.key = ATTR_STYLE; tag.val = buf; @@ -1420,11 +1521,10 @@ mdoc_tbl_pre(MDOC_ARGS, int type) if (MDOC_Width == bl->args->argv[i].arg) { assert(bl->args->argv[i].sz); wp = i; - w = out_a2width(bl->args->argv[i].value[0]); + w = a2width(bl->args->argv[i].value[0]); } else if (MDOC_Offset == bl->args->argv[i].arg) { assert(bl->args->argv[i].sz); - o = out_a2offs - (bl->args->argv[i].value[0], INDENT); + o = a2offs(bl->args->argv[i].value[0]); } else if (MDOC_Compact == bl->args->argv[i].arg) c = 1; @@ -1435,7 +1535,7 @@ mdoc_tbl_pre(MDOC_ARGS, int type) /* Counter... */ ; assert(nn); if (wp >= 0 && i < (int)bl->args[wp].argv->sz) - w = out_a2width(bl->args->argv[wp].value[i]); + w = a2width(bl->args->argv[wp].value[i]); } switch (type) { @@ -1484,7 +1584,7 @@ mdoc_bl_pre(MDOC_ARGS) if (MDOC_BLOCK != n->type) return(1); - if (MDOC_Enum != out_a2list(n)) + if (MDOC_Enum != a2list(n)) return(1); ord = malloc(sizeof(struct ord)); @@ -1506,7 +1606,7 @@ mdoc_bl_post(MDOC_ARGS) if (MDOC_BLOCK != n->type) return; - if (MDOC_Enum != out_a2list(n)) + if (MDOC_Enum != a2list(n)) return; ord = SLIST_FIRST(&h->ords); @@ -1522,9 +1622,9 @@ mdoc_it_pre(MDOC_ARGS) int type; if (MDOC_BLOCK == n->type) - type = out_a2list(n->parent->parent); + type = a2list(n->parent->parent); else - type = out_a2list(n->parent->parent->parent); + type = a2list(n->parent->parent->parent); return(mdoc_tbl_pre(m, n, h, type)); } @@ -1749,8 +1849,7 @@ mdoc_bd_pre(MDOC_ARGS) switch (bl->args->argv[i].arg) { case (MDOC_Offset): assert(bl->args->argv[i].sz); - o = out_a2offs - (bl->args->argv[i].value[0], INDENT); + o = a2offs (bl->args->argv[i].value[0]); break; case (MDOC_Compact): c = 1; @@ -2059,4 +2158,32 @@ mdoc_fn_pre(MDOC_ARGS) print_text(h, ";"); return(0); +} + + +/* ARGSUSED */ +static int +mdoc_sp_pre(MDOC_ARGS) +{ + int len; + struct htmlpair tag; + + switch (n->tok) { + case (MDOC_sp): + len = n->child ? atoi(n->child->string) : 1; + break; + case (MDOC_br): + len = 0; + break; + default: + len = 1; + break; + } + + buffmt("height: %dem", len); + tag.key = ATTR_STYLE; + tag.val = buf; + print_otag(h, TAG_DIV, 1, &tag); + return(1); + }