=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.20 retrieving revision 1.27 diff -u -p -r1.20 -r1.27 --- mandoc/html.c 2008/12/10 00:58:15 1.20 +++ mandoc/html.c 2008/12/12 10:11:10 1.27 @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.20 2008/12/10 00:58:15 kristaps Exp $ */ +/* $Id: html.c,v 1.27 2008/12/12 10:11:10 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -49,35 +49,32 @@ static int html_loadcss(struct md_mbuf *, const char *); static int html_alloc(void **); static void html_free(void *); -static ssize_t html_endtag(struct md_mbuf *, void *, - const struct md_args *, +static ssize_t html_endtag(struct ml_args *, enum md_ns, int); -static ssize_t html_beginstring(struct md_mbuf *, - const struct md_args *, +static ssize_t html_beginstring(struct ml_args *, const char *, size_t); -static ssize_t html_beginhttp(struct md_mbuf *, - const struct md_args *, +static ssize_t html_endstring(struct ml_args *, const char *, size_t); -static ssize_t html_endstring(struct md_mbuf *, - const struct md_args *, - const char *, size_t); -static ssize_t html_endhttp(struct md_mbuf *, - const struct md_args *, - const char *, size_t); -static ssize_t html_begintag(struct md_mbuf *, void *, - const struct md_args *, - enum md_ns, int, +static ssize_t html_begintag(struct ml_args *, + enum md_ns, int, const int *, const char **); -static int html_begin(struct md_mbuf *, - const struct md_args *, +static int html_begin(struct ml_args *, const struct tm *, const char *, const char *, - enum roffmsec, const char *); + enum roffmsec, enum roffvol); +static int html_end(struct ml_args *, + const struct tm *, + const char *, const char *, + enum roffmsec, enum roffvol); static int html_printargs(struct md_mbuf *, int, const char *, const int *, const char **, size_t *); -static int html_end(struct md_mbuf *, - const struct md_args *); +static ssize_t html_beginhttp(struct md_mbuf *, + const struct md_args *, + const char *, size_t); +static ssize_t html_endhttp(struct md_mbuf *, + const struct md_args *, + const char *, size_t); static int html_blocktagname(struct md_mbuf *, const struct md_args *, int, struct htmlq *, const int *, @@ -130,6 +127,7 @@ html_It_headtagname(struct md_mbuf *mbuf, struct htmlq { struct htmlnode *n; int i; + struct html_pair attr[2]; for (n = q->last; n; n = n->parent) if (n->tok == ROFF_Bl) @@ -144,9 +142,17 @@ html_It_headtagname(struct md_mbuf *mbuf, struct htmlq case (ROFF_Ohang): return(html_stput(mbuf, HTML_TAG_DIV, res)); case (ROFF_Tag): - /* FALLTHROUGH */ + attr[0].attr = HTML_ATTR_VALIGN; + attr[0].val = "top"; + attr[1].attr = HTML_ATTR_NOWRAP; + attr[1].val = "true"; + return(html_saput(mbuf, HTML_TAG_TD, + res, 2, attr)); case (ROFF_Column): - return(html_stput(mbuf, HTML_TAG_TD, res)); + attr[0].attr = HTML_ATTR_VALIGN; + attr[0].val = "top"; + return(html_saput(mbuf, HTML_TAG_TD, + res, 1, attr)); default: break; } @@ -163,6 +169,7 @@ html_It_bodytagname(struct md_mbuf *mbuf, struct htmlq { struct htmlnode *n; int i; + struct html_pair attr[1]; for (n = q->last; n; n = n->parent) if (n->tok == ROFF_Bl) @@ -195,7 +202,10 @@ html_It_bodytagname(struct md_mbuf *mbuf, struct htmlq case (ROFF_Tag): /* FALLTHROUGH */ case (ROFF_Column): - return(html_stput(mbuf, HTML_TAG_TD, res)); + attr[0].attr = HTML_ATTR_VALIGN; + attr[0].val = "top"; + return(html_saput(mbuf, HTML_TAG_TD, + res, 1, attr)); default: break; } @@ -380,24 +390,68 @@ html_aputln(struct md_mbuf *mbuf, enum ml_scope scope, /* ARGSUSED */ static int -html_begin(struct md_mbuf *mbuf, const struct md_args *args, - const struct tm *tm, const char *os, - const char *name, enum roffmsec msec, const char *vol) +html_begin(struct ml_args *p, const struct tm *tm, const char *os, + const char *name, enum roffmsec msec, enum roffvol vol) { + enum roffvol bvol; struct html_pair attr[4]; - char ts[32]; + char ts[32], title[64]; int i; (void)snprintf(ts, sizeof(ts), "%s(%s)", name, roff_msecname(msec)); + if (vol >= ROFF_ARCH_START) { + switch (msec) { + case(ROFF_MSEC_1): + /* FALLTHROUGH */ + case(ROFF_MSEC_6): + /* FALLTHROUGH */ + case(ROFF_MSEC_7): + bvol = ROFF_VOL_URM; + break; + case(ROFF_MSEC_2): + /* FALLTHROUGH */ + case(ROFF_MSEC_3): + /* FALLTHROUGH */ + case(ROFF_MSEC_3p): + /* FALLTHROUGH */ + case(ROFF_MSEC_4): + /* FALLTHROUGH */ + case(ROFF_MSEC_5): + bvol = ROFF_VOL_PRM; + break; + case(ROFF_MSEC_8): + bvol = ROFF_VOL_PRM; + break; + case(ROFF_MSEC_9): + bvol = ROFF_VOL_KM; + break; + case(ROFF_MSEC_UNASS): + /* FALLTHROUGH */ + case(ROFF_MSEC_DRAFT): + /* FALLTHROUGH */ + case(ROFF_MSEC_PAPER): + bvol = ROFF_VOL_NONE; + break; + default: + abort(); + /* NOTREACHED */ + } + + (void)snprintf(title, sizeof(title), "%s (%s)", + roff_volname(bvol), roff_volname(vol)); + } else + (void)snprintf(title, sizeof(title), "%s", roff_volname(vol)); + + i = 0; - if ( ! html_typeput(mbuf, HTML_TYPE_4_01_STRICT, NULL)) + if ( ! html_typeput(p->mbuf, HTML_TYPE_4_01_STRICT, NULL)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i, HTML_TAG_HTML)) + if ( ! html_tputln(p->mbuf, ML_OPEN, i, HTML_TAG_HTML)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i++, HTML_TAG_HEAD)) + if ( ! html_tputln(p->mbuf, ML_OPEN, i++, HTML_TAG_HEAD)) return(0); attr[0].attr = HTML_ATTR_HTTP_EQUIV; @@ -405,7 +459,7 @@ html_begin(struct md_mbuf *mbuf, const struct md_args attr[1].attr = HTML_ATTR_CONTENT; attr[1].val = "text/html;charset=utf-8"; - if ( ! html_aputln(mbuf, ML_OPEN, i, HTML_TAG_META, 2, attr)) + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_META, 2, attr)) return(0); attr[0].attr = HTML_ATTR_NAME; @@ -413,104 +467,169 @@ html_begin(struct md_mbuf *mbuf, const struct md_args attr[1].attr = HTML_ATTR_CONTENT; attr[1].val = "document"; - if ( ! html_aputln(mbuf, ML_OPEN, i, HTML_TAG_META, 2, attr)) + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_META, 2, attr)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i, HTML_TAG_TITLE)) + if ( ! html_tputln(p->mbuf, ML_OPEN, i, HTML_TAG_TITLE)) return(0); - if ( ! ml_putstring(mbuf, ts, NULL)) + if ( ! ml_putstring(p->mbuf, ts, NULL)) return(0); - if ( ! html_tputln(mbuf, ML_CLOSE, i, HTML_TAG_TITLE)) + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TITLE)) return(0); - if (HTML_CSS_EMBED & args->params.html.flags) { + if (HTML_CSS_EMBED & p->args->params.html.flags) { attr[0].attr = HTML_ATTR_TYPE; attr[0].val = "text/css"; - if ( ! html_aputln(mbuf, ML_OPEN, i, + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_STYLE, 1, attr)) return(0); - if ( ! html_commentput(mbuf, ML_OPEN, NULL)) - return(NULL); + if ( ! html_commentput(p->mbuf, ML_OPEN, NULL)) + return(0); - if ( ! html_loadcss(mbuf, args->params.html.css)) + if ( ! html_loadcss(p->mbuf, p->args->params.html.css)) return(0); - if ( ! html_commentput(mbuf, ML_CLOSE, NULL)) - return(NULL); - if ( ! html_tputln(mbuf, ML_CLOSE, i, HTML_TAG_STYLE)) + if ( ! html_commentput(p->mbuf, ML_CLOSE, NULL)) return(0); + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_STYLE)) + return(0); } else { attr[0].attr = HTML_ATTR_REL; attr[0].val = "stylesheet"; attr[1].attr = HTML_ATTR_TYPE; attr[1].val = "text/css"; attr[2].attr = HTML_ATTR_HREF; - attr[2].val = args->params.html.css; + attr[2].val = p->args->params.html.css; - if ( ! html_aputln(mbuf, ML_OPEN, i, + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_LINK, 3, attr)) return(0); } - if ( ! html_tputln(mbuf, ML_CLOSE, --i, HTML_TAG_HEAD)) + if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_HEAD)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i, HTML_TAG_BODY)) + if ( ! html_tputln(p->mbuf, ML_OPEN, i, HTML_TAG_BODY)) return(0); attr[0].attr = HTML_ATTR_CLASS; attr[0].val = "mdoc"; - if ( ! html_aputln(mbuf, ML_OPEN, i, HTML_TAG_DIV, 1, attr)) + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_DIV, 1, attr)) return(0); attr[0].attr = HTML_ATTR_WIDTH; attr[0].val = "100%"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "header-table"; - if ( ! html_aputln(mbuf, ML_OPEN, i++, HTML_TAG_TABLE, 1, attr)) + if ( ! html_aputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TABLE, 2, attr)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i++, HTML_TAG_TR)) + if ( ! html_tputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TR)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i, HTML_TAG_TD)) + attr[0].attr = HTML_ATTR_ALIGN; + attr[0].val = "left"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "header-section"; + + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr)) return(0); - if ( ! ml_putstring(mbuf, ts, NULL)) + if ( ! ml_putstring(p->mbuf, ts, NULL)) return(0); - if ( ! html_tputln(mbuf, ML_CLOSE, i, HTML_TAG_TD)) + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD)) return(0); - if ( ! html_tputln(mbuf, ML_OPEN, i, HTML_TAG_TD)) + attr[0].attr = HTML_ATTR_ALIGN; + attr[0].val = "center"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "header-volume"; + + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr)) return(0); - /* TODO: middle. */ - if ( ! html_tputln(mbuf, ML_CLOSE, i, HTML_TAG_TD)) + if ( ! ml_putstring(p->mbuf, title, NULL)) return(0); + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD)) + return(0); attr[0].attr = HTML_ATTR_ALIGN; attr[0].val = "right"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "header-section"; - if ( ! html_aputln(mbuf, ML_OPEN, i, HTML_TAG_TD, 1, attr)) + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr)) return(0); - if ( ! ml_putstring(mbuf, ts, NULL)) + if ( ! ml_putstring(p->mbuf, ts, NULL)) return(0); - if ( ! html_tputln(mbuf, ML_CLOSE, i, HTML_TAG_TD)) + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD)) return(0); - if ( ! html_tputln(mbuf, ML_CLOSE, --i, HTML_TAG_TR)) + if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TR)) return(0); - return(html_tputln(mbuf, ML_CLOSE, --i, HTML_TAG_TABLE)); + return(html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TABLE)); } /* ARGSUSED */ static int -html_end(struct md_mbuf *mbuf, const struct md_args *args) +html_end(struct ml_args *p, const struct tm *tm, const char *os, + const char *name, enum roffmsec msec, enum roffvol vol) { + struct html_pair attr[4]; + int i; + char ts[64]; - if ( ! html_tputln(mbuf, ML_CLOSE, 0, HTML_TAG_DIV)) + if (0 == strftime(ts, sizeof(ts), "%B %d, %Y", tm)) { + warn("strftime"); return(0); - if ( ! html_tputln(mbuf, ML_CLOSE, 0, HTML_TAG_BODY)) + } + + i = 0; + + attr[0].attr = HTML_ATTR_WIDTH; + attr[0].val = "100%"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "header-footer"; + + if ( ! html_aputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TABLE, 2, attr)) return(0); - return(html_tputln(mbuf, ML_CLOSE, 0, HTML_TAG_HTML)); + if ( ! html_tputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TR)) + return(0); + + attr[0].attr = HTML_ATTR_ALIGN; + attr[0].val = "left"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "footer-os"; + + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr)) + return(0); + if ( ! ml_putstring(p->mbuf, os, NULL)) + return(0); + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD)) + return(0); + + attr[0].attr = HTML_ATTR_ALIGN; + attr[0].val = "right"; + attr[1].attr = HTML_ATTR_CLASS; + attr[1].val = "footer-date"; + + if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr)) + return(0); + if ( ! ml_putstring(p->mbuf, ts, NULL)) + return(0); + if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD)) + return(0); + + if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TR)) + return(0); + if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TABLE)) + return(0); + + if ( ! html_tputln(p->mbuf, ML_CLOSE, 0, HTML_TAG_DIV)) + return(0); + if ( ! html_tputln(p->mbuf, ML_CLOSE, 0, HTML_TAG_BODY)) + return(0); + return(html_tputln(p->mbuf, ML_CLOSE, 0, HTML_TAG_HTML)); } @@ -650,6 +769,25 @@ html_inlinetagargs(struct md_mbuf *mbuf, return(0); switch (tok) { + case (ROFF_Sh): + + /* FIXME: use API in ml.h. */ + + assert(*argv); + if ( ! ml_nputs(mbuf, " name=\"", 7, res)) + return(0); + if ( ! ml_putstring(mbuf, *argv++, res)) + return(0); + while (*argv) { + if ( ! ml_putstring(mbuf, "_", res)) + return(0); + if ( ! ml_putstring(mbuf, *argv++, res)) + return(0); + } + if ( ! ml_nputs(mbuf, "\"", 1, res)) + return(0); + break; + case (ROFF_Sx): /* FIXME: use API in ml.h. */ @@ -657,10 +795,17 @@ html_inlinetagargs(struct md_mbuf *mbuf, assert(*argv); if ( ! ml_nputs(mbuf, " href=\"#", 8, res)) return(0); - if ( ! ml_putstring(mbuf, *argv, res)) + if ( ! ml_putstring(mbuf, *argv++, res)) return(0); + while (*argv) { + if ( ! ml_putstring(mbuf, "_", res)) + return(0); + if ( ! ml_putstring(mbuf, *argv++, res)) + return(0); + } if ( ! ml_nputs(mbuf, "\"", 1, res)) return(0); + break; default: break; @@ -677,6 +822,12 @@ html_inlinetagname(struct md_mbuf *mbuf, { switch (tok) { + case (ROFF_Dl): + /* FALLTHROUGH */ + case (ROFF_D1): + return(html_stput(mbuf, HTML_TAG_DIV, res)); + case (ROFF_Sh): + return(html_stput(mbuf, HTML_TAG_A, res)); case (ROFF_Pp): return(html_stput(mbuf, HTML_TAG_DIV, res)); case (ROFF_Sx): @@ -690,8 +841,7 @@ html_inlinetagname(struct md_mbuf *mbuf, static ssize_t -html_begintag(struct md_mbuf *mbuf, void *data, - const struct md_args *args, enum md_ns ns, +html_begintag(struct ml_args *p, enum md_ns ns, int tok, const int *argc, const char **argv) { size_t res; @@ -702,8 +852,7 @@ html_begintag(struct md_mbuf *mbuf, void *data, assert(ns != MD_NS_DEFAULT); res = 0; - assert(data); - q = (struct htmlq *)data; + q = (struct htmlq *)p->data; if (NULL == (node = calloc(1, sizeof(struct htmlnode)))) { warn("calloc"); @@ -730,33 +879,33 @@ html_begintag(struct md_mbuf *mbuf, void *data, switch (ns) { case (MD_NS_BLOCK): - if ( ! html_blocktagname(mbuf, args, tok, + if ( ! html_blocktagname(p->mbuf, p->args, tok, q, argc, argv, &res)) return(-1); - if ( ! html_blocktagargs(mbuf, args, tok, + if ( ! html_blocktagargs(p->mbuf, p->args, tok, argc, argv, &res)) return(-1); break; case (MD_NS_BODY): - if ( ! html_bodytagname(mbuf, args, tok, + if ( ! html_bodytagname(p->mbuf, p->args, tok, q, argc, argv, &res)) return(-1); - if ( ! html_bodytagargs(mbuf, args, tok, + if ( ! html_bodytagargs(p->mbuf, p->args, tok, argc, argv, &res)) return(-1); break; case (MD_NS_HEAD): - if ( ! html_headtagname(mbuf, args, tok, q, + if ( ! html_headtagname(p->mbuf, p->args, tok, q, argc, argv, &res)) return(-1); - if ( ! html_headtagargs(mbuf, args, tok, + if ( ! html_headtagargs(p->mbuf, p->args, tok, argc, argv, &res)) return(-1); break; default: - if ( ! html_inlinetagname(mbuf, args, tok, &res)) + if ( ! html_inlinetagname(p->mbuf, p->args, tok, &res)) return(-1); - if ( ! html_inlinetagargs(mbuf, args, tok, + if ( ! html_inlinetagargs(p->mbuf, p->args, tok, argc, argv, &res)) return(-1); break; @@ -767,8 +916,7 @@ html_begintag(struct md_mbuf *mbuf, void *data, static ssize_t -html_endtag(struct md_mbuf *mbuf, void *data, - const struct md_args *args, enum md_ns ns, int tok) +html_endtag(struct ml_args *p, enum md_ns ns, int tok) { size_t res; struct htmlq *q; @@ -777,31 +925,30 @@ html_endtag(struct md_mbuf *mbuf, void *data, assert(ns != MD_NS_DEFAULT); res = 0; - assert(data); - q = (struct htmlq *)data; + q = (struct htmlq *)p->data; node = q->last; switch (ns) { case (MD_NS_BLOCK): - if ( ! html_blocktagname(mbuf, args, tok, + if ( ! html_blocktagname(p->mbuf, p->args, tok, q, node->argc, (const char **)node->argv, &res)) return(-1); break; case (MD_NS_BODY): - if ( ! html_bodytagname(mbuf, args, tok, + if ( ! html_bodytagname(p->mbuf, p->args, tok, q, node->argc, (const char **)node->argv, &res)) return(-1); break; case (MD_NS_HEAD): - if ( ! html_headtagname(mbuf, args, tok, + if ( ! html_headtagname(p->mbuf, p->args, tok, q, node->argc, (const char **)node->argv, &res)) return(-1); break; default: - if ( ! html_inlinetagname(mbuf, args, tok, &res)) + if ( ! html_inlinetagname(p->mbuf, p->args, tok, &res)) return(-1); break; } @@ -845,6 +992,7 @@ html_free(void *p) } +/* ARGSUSED */ static ssize_t html_beginhttp(struct md_mbuf *mbuf, const struct md_args *args, @@ -863,6 +1011,7 @@ html_beginhttp(struct md_mbuf *mbuf, } +/* ARGSUSED */ static ssize_t html_endhttp(struct md_mbuf *mbuf, const struct md_args *args, @@ -879,13 +1028,11 @@ html_endhttp(struct md_mbuf *mbuf, /* ARGSUSED */ static ssize_t -html_beginstring(struct md_mbuf *mbuf, - const struct md_args *args, - const char *buf, size_t sz) +html_beginstring(struct ml_args *p, const char *buf, size_t sz) { if (0 == strncmp(buf, "http://", 7)) - return(html_beginhttp(mbuf, args, buf, sz)); + return(html_beginhttp(p->mbuf, p->args, buf, sz)); return(0); } @@ -893,13 +1040,11 @@ html_beginstring(struct md_mbuf *mbuf, /* ARGSUSED */ static ssize_t -html_endstring(struct md_mbuf *mbuf, - const struct md_args *args, - const char *buf, size_t sz) +html_endstring(struct ml_args *p, const char *buf, size_t sz) { if (0 == strncmp(buf, "http://", 7)) - return(html_endhttp(mbuf, args, buf, sz)); + return(html_endhttp(p->mbuf, p->args, buf, sz)); return(0); }