+/*
+ * Print an element with an optional "id=" attribute.
+ * 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;
+ char *id, *href;
+
+ ret = NULL;
+ id = href = NULL;
+ if (n->flags & NODE_ID)
+ id = html_make_id(n, 1);
+ if (n->flags & NODE_HREF)
+ href = id == NULL ? html_make_id(n, 2) : 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 (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);
+ }
+ }
+ free(id);
+ if (id == NULL)
+ free(href);
+ return ret;
+}
+