=================================================================== RCS file: /cvs/mandoc/mdoc_html.c,v retrieving revision 1.299 retrieving revision 1.316 diff -u -p -r1.299 -r1.316 --- mandoc/mdoc_html.c 2018/05/08 21:42:34 1.299 +++ mandoc/mdoc_html.c 2018/12/03 21:00:10 1.316 @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.299 2018/05/08 21:42:34 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.316 2018/12/03 21:00:10 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze @@ -34,8 +34,6 @@ #include "html.h" #include "main.h" -#define INDENT 5 - #define MDOC_ARGS const struct roff_meta *meta, \ struct roff_node *n, \ struct html *h @@ -44,7 +42,7 @@ #define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b)) #endif -struct htmlmdoc { +struct mdoc_html_act { int (*pre)(MDOC_ARGS); void (*post)(MDOC_ARGS); }; @@ -64,6 +62,7 @@ static int mdoc_root_pre(const struct roff_meta *, static void mdoc__x_post(MDOC_ARGS); static int mdoc__x_pre(MDOC_ARGS); +static int mdoc_abort_pre(MDOC_ARGS); static int mdoc_ad_pre(MDOC_ARGS); static int mdoc_an_pre(MDOC_ARGS); static int mdoc_ap_pre(MDOC_ARGS); @@ -121,7 +120,7 @@ static int mdoc_vt_pre(MDOC_ARGS); static int mdoc_xr_pre(MDOC_ARGS); static int mdoc_xx_pre(MDOC_ARGS); -static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_Dd] = { +static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = { {NULL, NULL}, /* Dd */ {NULL, NULL}, /* Dt */ {NULL, NULL}, /* Os */ @@ -156,7 +155,7 @@ static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_D {mdoc_nd_pre, NULL}, /* Nd */ {mdoc_nm_pre, NULL}, /* Nm */ {mdoc_quote_pre, mdoc_quote_post}, /* Op */ - {mdoc_ft_pre, NULL}, /* Ot */ + {mdoc_abort_pre, NULL}, /* Ot */ {mdoc_pa_pre, NULL}, /* Pa */ {mdoc_ex_pre, NULL}, /* Rv */ {mdoc_st_pre, NULL}, /* St */ @@ -229,7 +228,7 @@ static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_D {mdoc_em_pre, NULL}, /* Fr */ {NULL, NULL}, /* Ud */ {mdoc_lb_pre, NULL}, /* Lb */ - {mdoc_pp_pre, NULL}, /* Lp */ + {mdoc_abort_pre, NULL}, /* Lp */ {mdoc_lk_pre, NULL}, /* Lk */ {mdoc_mt_pre, NULL}, /* Mt */ {mdoc_quote_pre, mdoc_quote_post}, /* Brq */ @@ -243,7 +242,6 @@ static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_D {mdoc__x_pre, mdoc__x_post}, /* %U */ {NULL, NULL}, /* Ta */ }; -static const struct htmlmdoc *const mdocs = __mdocs - MDOC_Dd; /* @@ -404,9 +402,10 @@ print_mdoc_node(MDOC_ARGS) break; } assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); - if (mdocs[n->tok].pre != NULL && + if (mdoc_html_acts[n->tok - MDOC_Dd].pre != NULL && (n->end == ENDBODY_NOT || n->child != NULL)) - child = (*mdocs[n->tok].pre)(meta, n, h); + child = (*mdoc_html_acts[n->tok - MDOC_Dd].pre)(meta, + n, h); break; } @@ -425,10 +424,10 @@ print_mdoc_node(MDOC_ARGS) break; default: if (n->tok < ROFF_MAX || - mdocs[n->tok].post == NULL || + mdoc_html_acts[n->tok - MDOC_Dd].post == NULL || n->flags & NODE_ENDED) break; - (*mdocs[n->tok].post)(meta, n, h); + (*mdoc_html_acts[n->tok - MDOC_Dd].post)(meta, n, h); if (n->end != ENDBODY_NOT) n->body->flags |= NODE_ENDED; break; @@ -502,22 +501,69 @@ cond_id(const struct roff_node *n) (n->parent->tok == MDOC_Xo && n->parent->parent->prev == NULL && n->parent->parent->parent->tok == MDOC_It))) - return html_make_id(n); + return html_make_id(n, 1); return NULL; } static int mdoc_sh_pre(MDOC_ARGS) { - char *id; + struct roff_node *sn, *subn; + struct tag *t, *tsec, *tsub; + char *id; + int sc; switch (n->type) { + case ROFFT_BLOCK: + if ((h->oflags & HTML_TOC) == 0 || + h->flags & HTML_TOCDONE || + n->sec <= SEC_SYNOPSIS) + break; + h->flags |= HTML_TOCDONE; + sc = 0; + for (sn = n->next; sn != NULL; sn = sn->next) + if (sn->sec == SEC_CUSTOM) + if (++sc == 2) + break; + if (sc < 2) + break; + t = print_otag(h, TAG_H1, "c", "Sh"); + print_text(h, "TABLE OF CONTENTS"); + print_tagq(h, t); + t = print_otag(h, TAG_UL, "c", "Bl-compact"); + for (sn = n; sn != NULL; sn = sn->next) { + tsec = print_otag(h, TAG_LI, ""); + id = html_make_id(sn->head, 0); + print_otag(h, TAG_A, "hR", id); + free(id); + print_mdoc_nodelist(meta, sn->head->child, h); + tsub = NULL; + for (subn = sn->body->child; subn != NULL; + subn = subn->next) { + if (subn->tok != MDOC_Ss) + continue; + id = html_make_id(subn->head, 0); + if (id == NULL) + continue; + if (tsub == NULL) + print_otag(h, TAG_UL, + "c", "Bl-compact"); + tsub = print_otag(h, TAG_LI, ""); + print_otag(h, TAG_A, "hR", id); + free(id); + print_mdoc_nodelist(meta, + subn->head->child, h); + print_tagq(h, tsub); + } + print_tagq(h, tsec); + } + print_tagq(h, t); + break; case ROFFT_HEAD: - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H1, "cTi", "Sh", id); if (id != NULL) print_otag(h, TAG_A, "chR", "permalink", id); - free(id); break; case ROFFT_BODY: if (n->sec == SEC_AUTHORS) @@ -537,11 +583,10 @@ mdoc_ss_pre(MDOC_ARGS) if (n->type != ROFFT_HEAD) return 1; - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H2, "cTi", "Ss", id); if (id != NULL) print_otag(h, TAG_A, "chR", "permalink", id); - free(id); return 1; } @@ -553,7 +598,6 @@ mdoc_fl_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Fl", id); - free(id); print_text(h, "\\-"); if (!(n->child == NULL && @@ -573,7 +617,6 @@ mdoc_cm_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Cm", id); - free(id); return 1; } @@ -583,10 +626,9 @@ mdoc_nd_pre(MDOC_ARGS) if (n->type != ROFFT_BODY) return 1; - /* XXX: this tag in theory can contain block elements. */ - print_text(h, "\\(em"); - print_otag(h, TAG_SPAN, "cT", "Nd"); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_DIV, "cT", "Nd"); return 1; } @@ -618,7 +660,7 @@ mdoc_xr_pre(MDOC_ARGS) if (NULL == n->child) return 0; - if (h->base_man) + if (h->base_man1) print_otag(h, TAG_A, "cThM", "Xr", n->child->string, n->child->next == NULL ? NULL : n->child->next->string); @@ -700,7 +742,7 @@ mdoc_it_pre(MDOC_ARGS) print_otag(h, TAG_DT, ""); break; case ROFFT_BODY: - print_otag(h, TAG_DD, "sw*+l", bl->norm->Bl.width); + print_otag(h, TAG_DD, ""); break; default: break; @@ -713,20 +755,18 @@ mdoc_it_pre(MDOC_ARGS) (n->parent->prev == NULL || n->parent->prev->body == NULL || n->parent->prev->body->child != NULL)) { - t = print_otag(h, TAG_DT, "sw*+-l", - bl->norm->Bl.width); + t = print_otag(h, TAG_DT, ""); print_text(h, "\\ "); print_tagq(h, t); t = print_otag(h, TAG_DD, ""); print_text(h, "\\ "); print_tagq(h, t); } - print_otag(h, TAG_DT, "sw*+-l", bl->norm->Bl.width); + print_otag(h, TAG_DT, ""); break; case ROFFT_BODY: if (n->child == NULL) { - print_otag(h, TAG_DD, "ss?", - "width", "auto"); + print_otag(h, TAG_DD, "s", "width", "auto"); print_text(h, "\\ "); } else print_otag(h, TAG_DD, ""); @@ -755,40 +795,20 @@ mdoc_it_pre(MDOC_ARGS) static int mdoc_bl_pre(MDOC_ARGS) { - char cattr[21]; - struct tag *t; + char cattr[28]; struct mdoc_bl *bl; - size_t i; enum htmltag elemtype; - bl = &n->norm->Bl; - switch (n->type) { case ROFFT_BODY: return 1; - case ROFFT_HEAD: - if (bl->type != LIST_column || bl->ncols == 0) - return 0; - - /* - * For each column, print out the tag with our - * suggested width. The last column gets min-width, as - * in terminal mode it auto-sizes to the width of the - * screen and we want to preserve that behaviour. - */ - - t = print_otag(h, TAG_COLGROUP, ""); - for (i = 0; i < bl->ncols - 1; i++) - print_otag(h, TAG_COL, "sw+w", bl->cols[i]); - print_otag(h, TAG_COL, "swW", bl->cols[i]); - print_tagq(h, t); return 0; - default: break; } + bl = &n->norm->Bl; switch (bl->type) { case LIST_bullet: elemtype = TAG_UL; @@ -825,9 +845,9 @@ mdoc_bl_pre(MDOC_ARGS) break; case LIST_tag: if (bl->offs) - print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs); - print_otag(h, TAG_DL, "csw*+l", bl->comp ? - "Bl-tag Bl-compact" : "Bl-tag", bl->width); + print_otag(h, TAG_DIV, "c", "Bd-indent"); + print_otag(h, TAG_DL, "c", bl->comp ? + "Bl-tag Bl-compact" : "Bl-tag"); return 1; case LIST_column: elemtype = TAG_TABLE; @@ -836,9 +856,11 @@ mdoc_bl_pre(MDOC_ARGS) default: abort(); } + if (bl->offs != NULL) + (void)strlcat(cattr, " Bd-indent", sizeof(cattr)); if (bl->comp) (void)strlcat(cattr, " Bl-compact", sizeof(cattr)); - print_otag(h, elemtype, "cswl", cattr, bl->offs); + print_otag(h, elemtype, "c", cattr); return 1; } @@ -870,7 +892,7 @@ mdoc_d1_pre(MDOC_ARGS) if (n->type != ROFFT_BLOCK) return 1; - print_otag(h, TAG_DIV, "c", "D1"); + print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); if (n->tok == MDOC_Dl) print_otag(h, TAG_CODE, "c", "Li"); @@ -883,7 +905,7 @@ mdoc_sx_pre(MDOC_ARGS) { char *id; - id = html_make_id(n); + id = html_make_id(n, 0); print_otag(h, TAG_A, "cThR", "Sx", id); free(id); return 1; @@ -892,7 +914,7 @@ mdoc_sx_pre(MDOC_ARGS) static int mdoc_bd_pre(MDOC_ARGS) { - int comp, offs, sv; + int comp, sv; struct roff_node *nn; if (n->type == ROFFT_HEAD) @@ -917,19 +939,10 @@ mdoc_bd_pre(MDOC_ARGS) if (n->norm->Bd.offs == NULL || ! strcmp(n->norm->Bd.offs, "left")) - offs = 0; - else if ( ! strcmp(n->norm->Bd.offs, "indent")) - offs = INDENT; - else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) - offs = INDENT * 2; + print_otag(h, TAG_DIV, "c", "Bd"); else - offs = -1; + print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); - if (offs == -1) - print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs); - else - print_otag(h, TAG_DIV, "cshl", "Bd", offs); - if (n->norm->Bd.type != DISP_unfilled && n->norm->Bd.type != DISP_literal) return 1; @@ -956,7 +969,6 @@ mdoc_bd_pre(MDOC_ARGS) case MDOC_Bl: case MDOC_D1: case MDOC_Dl: - case MDOC_Lp: case MDOC_Pp: continue; default: @@ -980,14 +992,14 @@ mdoc_bd_pre(MDOC_ARGS) static int mdoc_pa_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "cT", "Pa"); + print_otag(h, TAG_SPAN, "cT", "Pa"); return 1; } static int mdoc_ad_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "c", "Ad"); + print_otag(h, TAG_SPAN, "c", "Ad"); return 1; } @@ -1031,7 +1043,6 @@ mdoc_dv_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Dv", id); - free(id); return 1; } @@ -1043,7 +1054,6 @@ mdoc_ev_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Ev", id); - free(id); return 1; } @@ -1056,12 +1066,11 @@ mdoc_er_pre(MDOC_ARGS) (n->parent->tok == MDOC_It || (n->parent->tok == MDOC_Bq && n->parent->parent->parent->tok == MDOC_It)) ? - html_make_id(n) : NULL; + html_make_id(n, 1) : NULL; if (id != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Er", id); - free(id); return 1; } @@ -1211,7 +1220,7 @@ mdoc_fn_pre(MDOC_ARGS) for (n = n->child->next; n; n = n->next) { if (NODE_SYNPRETTY & n->flags) - t = print_otag(h, TAG_VAR, "cTss?", "Fa", + t = print_otag(h, TAG_VAR, "cTs", "Fa", "white-space", "nowrap"); else t = print_otag(h, TAG_VAR, "cT", "Fa"); @@ -1412,7 +1421,6 @@ mdoc_ic_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Ic", id); - free(id); return 1; } @@ -1444,20 +1452,16 @@ mdoc_bf_pre(MDOC_ARGS) return 1; if (FONT_Em == n->norm->Bf.font) - cattr = "Em"; + cattr = "Bf Em"; else if (FONT_Sy == n->norm->Bf.font) - cattr = "Sy"; + cattr = "Bf Sy"; else if (FONT_Li == n->norm->Bf.font) - cattr = "Li"; + cattr = "Bf Li"; else - cattr = "No"; + cattr = "Bf No"; - /* - * We want this to be inline-formatted, but needs to be div to - * accept block children. - */ - - print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_DIV, "c", cattr); return 1; } @@ -1468,8 +1472,7 @@ mdoc_ms_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_B, "cTi", "Ms", id); - free(id); + print_otag(h, TAG_SPAN, "cTi", "Ms", id); return 1; } @@ -1510,7 +1513,6 @@ mdoc_no_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_SPAN, "ci", "No", id); - free(id); return 1; } @@ -1522,7 +1524,6 @@ mdoc_li_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "ci", "Li", id); - free(id); return 1; } @@ -1678,7 +1679,8 @@ mdoc_quote_pre(MDOC_ARGS) case MDOC_Op: print_text(h, "\\(lB"); h->flags |= HTML_NOSPACE; - print_otag(h, TAG_SPAN, "c", "Op"); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_IDIV, "c", "Op"); break; case MDOC_En: if (NULL == n->norm->Es || @@ -1805,4 +1807,10 @@ mdoc_eo_post(MDOC_ARGS) h->flags |= HTML_NOSPACE; else if ( ! tail) h->flags &= ~HTML_NOSPACE; +} + +static int +mdoc_abort_pre(MDOC_ARGS) +{ + abort(); }