=================================================================== RCS file: /cvs/mandoc/mdoc_html.c,v retrieving revision 1.248 retrieving revision 1.255 diff -u -p -r1.248 -r1.255 --- mandoc/mdoc_html.c 2017/01/17 01:47:51 1.248 +++ mandoc/mdoc_html.c 2017/01/19 16:59:30 1.255 @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.248 2017/01/17 01:47:51 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.255 2017/01/19 16:59:30 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze @@ -48,6 +48,7 @@ struct htmlmdoc { void (*post)(MDOC_ARGS); }; +static char *make_id(const struct roff_node *); static void print_mdoc_head(MDOC_ARGS); static void print_mdoc_node(MDOC_ARGS); static void print_mdoc_nodelist(MDOC_ARGS); @@ -299,42 +300,47 @@ void html_mdoc(void *arg, const struct roff_man *mdoc) { struct html *h; - struct tag *t, *tt; + struct tag *t; h = (struct html *)arg; - if ( ! (HTML_FRAGMENT & h->oflags)) { + if ((h->oflags & HTML_FRAGMENT) == 0) { print_gen_decls(h); - t = print_otag(h, TAG_HTML, ""); - tt = print_otag(h, TAG_HEAD, ""); + print_otag(h, TAG_HTML, ""); + t = print_otag(h, TAG_HEAD, ""); print_mdoc_head(&mdoc->meta, mdoc->first->child, h); - print_tagq(h, tt); + print_tagq(h, t); print_otag(h, TAG_BODY, ""); - print_otag(h, TAG_DIV, "c", "mandoc"); - } else - t = print_otag(h, TAG_DIV, "c", "mandoc"); + } mdoc_root_pre(&mdoc->meta, mdoc->first->child, h); + t = print_otag(h, TAG_DIV, "c", "manual-text"); print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h); - mdoc_root_post(&mdoc->meta, mdoc->first->child, h); print_tagq(h, t); - putchar('\n'); + mdoc_root_post(&mdoc->meta, mdoc->first->child, h); + print_tagq(h, NULL); } static void print_mdoc_head(MDOC_ARGS) { + char *cp; print_gen_head(h); - bufinit(h); - bufcat(h, meta->title); - if (meta->msec) - bufcat_fmt(h, "(%s)", meta->msec); - if (meta->arch) - bufcat_fmt(h, " (%s)", meta->arch); + if (meta->arch != NULL && meta->msec != NULL) + mandoc_asprintf(&cp, "%s(%s) (%s)", meta->title, + meta->msec, meta->arch); + else if (meta->msec != NULL) + mandoc_asprintf(&cp, "%s(%s)", meta->title, meta->msec); + else if (meta->arch != NULL) + mandoc_asprintf(&cp, "%s (%s)", meta->title, meta->arch); + else + cp = mandoc_strdup(meta->title); + print_otag(h, TAG_TITLE, ""); - print_text(h, h->buf); + print_text(h, cp); + free(cp); } static void @@ -379,8 +385,6 @@ print_mdoc_node(MDOC_ARGS) h->flags |= HTML_NOSPACE; return; case ROFFT_EQN: - if (n->flags & NODE_LINE) - putchar('\n'); print_eqn(h, n->eqn); break; case ROFFT_TBL: @@ -489,12 +493,35 @@ mdoc_root_pre(MDOC_ARGS) return 1; } +static char * +make_id(const struct roff_node *n) +{ + const struct roff_node *nch; + char *buf, *cp; + + for (nch = n->child; nch != NULL; nch = nch->next) + if (nch->type != ROFFT_TEXT) + return NULL; + + buf = NULL; + deroff(&buf, n); + + /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */ + + for (cp = buf; *cp != '\0'; cp++) + if (*cp == ' ') + *cp = '_'; + + return buf; +} + static int mdoc_sh_pre(MDOC_ARGS) { + char *id; + switch (n->type) { case ROFFT_BLOCK: - print_otag(h, TAG_DIV, "c", "section"); return 1; case ROFFT_BODY: if (n->sec == SEC_AUTHORS) @@ -504,44 +531,29 @@ mdoc_sh_pre(MDOC_ARGS) break; } - bufinit(h); + if ((id = make_id(n)) != NULL) { + print_otag(h, TAG_H1, "ci", "Sh", id); + free(id); + } else + print_otag(h, TAG_H1, "c", "Sh"); - for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) { - bufcat_id(h, n->string); - if (NULL != (n = n->next)) - bufcat_id(h, " "); - } - - if (NULL == n) - print_otag(h, TAG_H1, "i", h->buf); - else - print_otag(h, TAG_H1, ""); - return 1; } static int mdoc_ss_pre(MDOC_ARGS) { - if (n->type == ROFFT_BLOCK) { - print_otag(h, TAG_DIV, "c", "subsection"); + char *id; + + if (n->type != ROFFT_HEAD) return 1; - } else if (n->type == ROFFT_BODY) - return 1; - bufinit(h); + if ((id = make_id(n)) != NULL) { + print_otag(h, TAG_H2, "ci", "Ss", id); + free(id); + } else + print_otag(h, TAG_H2, "c", "Ss"); - for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) { - bufcat_id(h, n->string); - if (NULL != (n = n->next)) - bufcat_id(h, " "); - } - - if (NULL == n) - print_otag(h, TAG_H2, "i", h->buf); - else - print_otag(h, TAG_H2, ""); - return 1; } @@ -623,13 +635,12 @@ mdoc_xr_pre(MDOC_ARGS) if (NULL == n->child) return 0; - if (h->base_man) { - buffmt_man(h, n->child->string, - n->child->next ? - n->child->next->string : NULL); - print_otag(h, TAG_A, "ch", "link-man", h->buf); - } else - print_otag(h, TAG_A, "c", "link-man"); + if (h->base_man) + print_otag(h, TAG_A, "chM", "Xr", + n->child->string, n->child->next == NULL ? + NULL : n->child->next->string); + else + print_otag(h, TAG_A, "c", "Xr"); n = n->child; print_text(h, n->string); @@ -835,32 +846,25 @@ mdoc_d1_pre(MDOC_ARGS) if (n->type != ROFFT_BLOCK) return 1; - print_otag(h, TAG_BLOCKQUOTE, "svtvb", 0, 0); + print_otag(h, TAG_DIV, "c", "D1"); - /* BLOCKQUOTE needs a block body. */ + if (n->tok == MDOC_Dl) + print_otag(h, TAG_CODE, "c", "Li"); - print_otag(h, TAG_DIV, "c", "display"); - - if (MDOC_Dl == n->tok) - print_otag(h, TAG_CODE, "c", "lit"); - return 1; } static int mdoc_sx_pre(MDOC_ARGS) { - bufinit(h); - bufcat(h, "#"); + char *id; - for (n = n->child; n; ) { - bufcat_id(h, n->string); - if (NULL != (n = n->next)) - bufcat_id(h, " "); - } + if ((id = make_id(n)) != NULL) { + print_otag(h, TAG_A, "chR", "Sx", id); + free(id); + } else + print_otag(h, TAG_A, "c", "Sx"); - print_otag(h, TAG_I, "c", "link-sec"); - print_otag(h, TAG_A, "ch", "link-sec", h->buf); return 1; } @@ -901,15 +905,15 @@ mdoc_bd_pre(MDOC_ARGS) offs = -1; if (offs == -1) - print_otag(h, TAG_DIV, "cswl", "display", n->norm->Bd.offs); + print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs); else - print_otag(h, TAG_DIV, "cshl", "display", offs); + print_otag(h, TAG_DIV, "cshl", "Bd", offs); if (n->norm->Bd.type != DISP_unfilled && n->norm->Bd.type != DISP_literal) return 1; - print_otag(h, TAG_PRE, "c", "lit"); + print_otag(h, TAG_PRE, "c", "Li"); /* This can be recursive: save & set our literal state. */ @@ -1051,9 +1055,8 @@ mdoc_fa_pre(MDOC_ARGS) static int mdoc_fd_pre(MDOC_ARGS) { - char buf[BUFSIZ]; - size_t sz; struct tag *t; + char *buf, *cp; synopsis_pre(h, n); @@ -1073,25 +1076,16 @@ mdoc_fd_pre(MDOC_ARGS) if (NULL != (n = n->next)) { assert(n->type == ROFFT_TEXT); - /* - * XXX This is broken and not easy to fix. - * When using -Oincludes, truncation may occur. - * Dynamic allocation wouldn't help because - * passing long strings to buffmt_includes() - * does not work either. - */ - - strlcpy(buf, '<' == *n->string || '"' == *n->string ? - n->string + 1 : n->string, BUFSIZ); - - sz = strlen(buf); - if (sz && ('>' == buf[sz - 1] || '"' == buf[sz - 1])) - buf[sz - 1] = '\0'; - if (h->base_includes) { - buffmt_includes(h, buf); - t = print_otag(h, TAG_A, "ch", "link-includes", - h->buf); + cp = n->string; + if (*cp == '<' || *cp == '"') + cp++; + buf = mandoc_strdup(cp); + cp = strchr(buf, '\0') - 1; + if (cp >= buf && (*cp == '>' || *cp == '"')) + *cp = '\0'; + t = print_otag(h, TAG_A, "chI", "link-includes", buf); + free(buf); } else t = print_otag(h, TAG_A, "c", "link-includes"); @@ -1279,16 +1273,16 @@ static int mdoc_mt_pre(MDOC_ARGS) { struct tag *t; + char *cp; for (n = n->child; n; n = n->next) { assert(n->type == ROFFT_TEXT); - bufinit(h); - bufcat(h, "mailto:"); - bufcat(h, n->string); - t = print_otag(h, TAG_A, "ch", "link-mail", h->buf); + mandoc_asprintf(&cp, "mailto:%s", n->string); + t = print_otag(h, TAG_A, "ch", "link-mail", cp); print_text(h, n->string); print_tagq(h, t); + free(cp); } return 0; @@ -1355,11 +1349,10 @@ mdoc_in_pre(MDOC_ARGS) if (NULL != (n = n->child)) { assert(n->type == ROFFT_TEXT); - if (h->base_includes) { - buffmt_includes(h, n->string); - t = print_otag(h, TAG_A, "ch", "link-includes", - h->buf); - } else + if (h->base_includes) + t = print_otag(h, TAG_A, "chI", "link-includes", + n->string); + else t = print_otag(h, TAG_A, "c", "link-includes"); print_text(h, n->string); print_tagq(h, t); @@ -1417,7 +1410,7 @@ mdoc_bf_pre(MDOC_ARGS) else if (FONT_Sy == n->norm->Bf.font) cattr = "symb"; else if (FONT_Li == n->norm->Bf.font) - cattr = "lit"; + cattr = "Li"; else cattr = "none"; @@ -1476,7 +1469,7 @@ mdoc_no_pre(MDOC_ARGS) static int mdoc_li_pre(MDOC_ARGS) { - print_otag(h, TAG_CODE, "c", "lit"); + print_otag(h, TAG_CODE, "c", "Li"); return 1; } @@ -1659,7 +1652,7 @@ mdoc_quote_pre(MDOC_ARGS) case MDOC_Ql: print_text(h, "\\(oq"); h->flags |= HTML_NOSPACE; - print_otag(h, TAG_CODE, "c", "lit"); + print_otag(h, TAG_CODE, "c", "Li"); break; case MDOC_So: case MDOC_Sq: