=================================================================== RCS file: /cvs/mandoc/mdoc_html.c,v retrieving revision 1.276 retrieving revision 1.284 diff -u -p -r1.276 -r1.284 --- mandoc/mdoc_html.c 2017/03/14 01:35:15 1.276 +++ mandoc/mdoc_html.c 2017/05/05 13:17:55 1.284 @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.276 2017/03/14 01:35:15 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.284 2017/05/05 13:17:55 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze @@ -49,7 +49,6 @@ struct htmlmdoc { }; static char *cond_id(const struct roff_node *); -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); @@ -119,8 +118,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_ap_pre, NULL}, /* Ap */ +static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_Dd] = { {NULL, NULL}, /* Dd */ {NULL, NULL}, /* Dt */ {NULL, NULL}, /* Os */ @@ -136,6 +134,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {mdoc_it_pre, NULL}, /* It */ {mdoc_ad_pre, NULL}, /* Ad */ {mdoc_an_pre, NULL}, /* An */ + {mdoc_ap_pre, NULL}, /* Ap */ {mdoc_ar_pre, NULL}, /* Ar */ {mdoc_cd_pre, NULL}, /* Cd */ {mdoc_cm_pre, NULL}, /* Cm */ @@ -238,12 +237,11 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = { {mdoc_quote_pre, mdoc_quote_post}, /* En */ {mdoc_xx_pre, NULL}, /* Dx */ {mdoc__x_pre, mdoc__x_post}, /* %Q */ - {mdoc_sp_pre, NULL}, /* br */ {mdoc_sp_pre, NULL}, /* sp */ {mdoc__x_pre, mdoc__x_post}, /* %U */ {NULL, NULL}, /* Ta */ - {mdoc_skip_pre, NULL}, /* ll */ }; +static const struct htmlmdoc *const mdocs = __mdocs - MDOC_Dd; /* @@ -394,7 +392,14 @@ print_mdoc_node(MDOC_ARGS) t = h->tag; } assert(h->tblt == NULL); - if (mdocs[n->tok].pre && (n->end == ENDBODY_NOT || n->child)) + if (n->tok < ROFF_MAX) { + roff_html_pre(h, n); + child = 0; + break; + } + assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); + if (mdocs[n->tok].pre != NULL && + (n->end == ENDBODY_NOT || n->child != NULL)) child = (*mdocs[n->tok].pre)(meta, n, h); break; } @@ -413,7 +418,9 @@ print_mdoc_node(MDOC_ARGS) case ROFFT_EQN: break; default: - if ( ! mdocs[n->tok].post || n->flags & NODE_ENDED) + if (n->tok < ROFF_MAX || + mdocs[n->tok].post == NULL || + n->flags & NODE_ENDED) break; (*mdocs[n->tok].post)(meta, n, h); if (n->end != ENDBODY_NOT) @@ -478,28 +485,6 @@ mdoc_root_pre(MDOC_ARGS) } 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 char * cond_id(const struct roff_node *n) { if (n->child != NULL && @@ -511,7 +496,7 @@ 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 make_id(n); + return html_make_id(n); return NULL; } @@ -522,9 +507,10 @@ mdoc_sh_pre(MDOC_ARGS) switch (n->type) { case ROFFT_HEAD: - id = make_id(n); + id = html_make_id(n); print_otag(h, TAG_H1, "cTi", "Sh", id); - print_otag(h, TAG_A, "chR", "selflink", id); + if (id != NULL) + print_otag(h, TAG_A, "chR", "selflink", id); free(id); break; case ROFFT_BODY: @@ -545,9 +531,10 @@ mdoc_ss_pre(MDOC_ARGS) if (n->type != ROFFT_HEAD) return 1; - id = make_id(n); + id = html_make_id(n); print_otag(h, TAG_H2, "cTi", "Ss", id); - print_otag(h, TAG_A, "chR", "selflink", id); + if (id != NULL) + print_otag(h, TAG_A, "chR", "selflink", id); free(id); return 1; } @@ -955,7 +942,7 @@ mdoc_sx_pre(MDOC_ARGS) { char *id; - id = make_id(n); + id = html_make_id(n); print_otag(h, TAG_A, "cThR", "Sx", id); free(id); return 1; @@ -1023,7 +1010,7 @@ mdoc_bd_pre(MDOC_ARGS) */ switch (nn->tok) { case MDOC_Sm: - case MDOC_br: + case ROFF_br: case MDOC_sp: case MDOC_Bl: case MDOC_D1: @@ -1128,7 +1115,7 @@ mdoc_er_pre(MDOC_ARGS) (n->parent->tok == MDOC_It || (n->parent->tok == MDOC_Bq && n->parent->parent->parent->tok == MDOC_It)) ? - make_id(n) : NULL; + html_make_id(n) : NULL; if (id != NULL) print_otag(h, TAG_A, "chR", "selflink", id); @@ -1344,17 +1331,13 @@ mdoc_sp_pre(MDOC_ARGS) struct roffsu su; SCALE_VS_INIT(&su, 1); + if (NULL != (n = n->child)) { + if ( ! a2roffsu(n->string, &su, SCALE_VS)) + su.scale = 1.0; + else if (su.scale < 0.0) + su.scale = 0.0; + } - if (MDOC_sp == n->tok) { - if (NULL != (n = n->child)) { - if ( ! a2roffsu(n->string, &su, SCALE_VS)) - su.scale = 1.0; - else if (su.scale < 0.0) - su.scale = 0.0; - } - } else - su.scale = 0.0; - print_otag(h, TAG_DIV, "suh", &su); /* So the div isn't empty: */ @@ -1367,19 +1350,25 @@ mdoc_sp_pre(MDOC_ARGS) static int mdoc_lk_pre(MDOC_ARGS) { - if (NULL == (n = n->child)) + struct tag *t; + + if ((n = n->child) == NULL) return 0; - assert(n->type == ROFFT_TEXT); - - print_otag(h, TAG_A, "cTh", "Lk", n->string); - - if (NULL == n->next) + /* Link target and link text. */ + t = print_otag(h, TAG_A, "cTh", "Lk", n->string); + if (n->next == NULL || n->next->flags & NODE_DELIMC) print_text(h, n->string); - - for (n = n->next; n; n = n->next) + for (n = n->next; n != NULL && !(n->flags & NODE_DELIMC); n = n->next) print_text(h, n->string); + print_tagq(h, t); + /* Trailing punctuation. */ + while (n != NULL) { + h->flags |= HTML_NOSPACE; + print_text(h, n->string); + n = n->next; + } return 0; }