=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.264 retrieving revision 1.268 diff -u -p -r1.264 -r1.268 --- mandoc/html.c 2020/03/13 15:32:28 1.264 +++ mandoc/html.c 2020/04/18 20:40:10 1.268 @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.264 2020/03/13 15:32:28 schwarze Exp $ */ +/* $Id: html.c,v 1.268 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons @@ -344,8 +344,8 @@ html_make_id(const struct roff_node *n, int unique) unsigned int slot; int suffix; - if (n->string != NULL) - buf = mandoc_strdup(n->string); + if (n->tag != NULL) + buf = mandoc_strdup(n->tag); else { switch (n->tok) { case MDOC_Sh: @@ -362,7 +362,7 @@ html_make_id(const struct roff_node *n, int unique) return NULL; break; default: - if (n->child->type != ROFFT_TEXT) + if (n->child == NULL || n->child->type != ROFFT_TEXT) return NULL; buf = mandoc_strdup(n->child->string); break; @@ -769,28 +769,43 @@ print_otag(struct html *h, enum htmltag tag, const cha /* * Print an element with an optional "id=" attribute. - * If there is an "id=" attribute, also add a permalink: - * outside if it's a phrasing element, or inside otherwise. + * If the element has phrasing content and an "id=" attribute, + * also add a permalink: outside if it can be in phrasing context, + * inside otherwise. */ struct tag * print_otag_id(struct html *h, enum htmltag elemtype, const char *cattr, struct roff_node *n) { + struct roff_node *nch; struct tag *ret, *t; - const char *id; + char *id, *href; ret = NULL; - id = NULL; + id = href = NULL; if (n->flags & NODE_ID) id = html_make_id(n, 1); - if (id != NULL && htmltags[elemtype].flags & HTML_INPHRASE) - ret = print_otag(h, TAG_A, "chR", "permalink", id); + if (n->flags & NODE_HREF) + href = id == NULL ? html_make_id(n, 0) : id; + if (href != NULL && htmltags[elemtype].flags & HTML_INPHRASE) + ret = print_otag(h, TAG_A, "chR", "permalink", href); t = print_otag(h, elemtype, "ci", cattr, id); if (ret == NULL) { ret = t; - if (id != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); + if (href != NULL && (nch = n->child) != NULL) { + /* man(7) is safe, it tags phrasing content only. */ + if (n->tok > MDOC_MAX || + htmltags[elemtype].flags & HTML_TOPHRASE) + nch = NULL; + else /* For mdoc(7), beware of nested blocks. */ + while (nch != NULL && nch->type == ROFFT_TEXT) + nch = nch->next; + if (nch == NULL) + print_otag(h, TAG_A, "chR", "permalink", href); + } } + if (id == NULL) + free(href); return ret; } @@ -863,6 +878,15 @@ print_gen_comment(struct html *h, struct roff_node *n) void print_text(struct html *h, const char *word) { + print_tagged_text(h, word, NULL); +} + +void +print_tagged_text(struct html *h, const char *word, struct roff_node *n) +{ + struct tag *t; + char *href; + /* * Always wrap text in a paragraph unless already contained in * some flow container; never put it directly into a section. @@ -883,13 +907,20 @@ print_text(struct html *h, const char *word) } /* - * Print the text, optionally surrounded by HTML whitespace, - * optionally manually switching fonts before and after. + * Optionally switch fonts, optionally write a permalink, then + * print the text, optionally surrounded by HTML whitespace. */ assert(h->metaf == NULL); print_metaf(h); print_indent(h); + + if (n != NULL && (href = html_make_id(n, 0)) != NULL) { + t = print_otag(h, TAG_A, "chR", "permalink", href); + free(href); + } else + t = NULL; + if ( ! print_encode(h, word, NULL, 0)) { if ( ! (h->flags & HTML_NONOSPACE)) h->flags &= ~HTML_NOSPACE; @@ -900,7 +931,8 @@ print_text(struct html *h, const char *word) if (h->metaf != NULL) { print_tagq(h, h->metaf); h->metaf = NULL; - } + } else if (t != NULL) + print_tagq(h, t); h->flags &= ~HTML_IGNDELIM; }