diff options
-rw-r--r-- | TODO | 9 | ||||
-rw-r--r-- | html.c | 48 | ||||
-rw-r--r-- | html.h | 2 | ||||
-rw-r--r-- | man_html.c | 6 | ||||
-rw-r--r-- | mdoc_html.c | 21 |
5 files changed, 55 insertions, 31 deletions
@@ -379,12 +379,9 @@ are mere guesses, and some may be wrong. --- HTML issues -------------------------------------------------------- -- duplicate names generate duplicate href="#..." anchor attributes - possibly use "#..._<N>" suffixes? - Jakub Klinkovsky <j dot l dot k at gmx dot com> 3 Oct 2017 21:23:36 +0200 - see also the thread: gre(4): Rename duplicate sections - up to 20 Apr 2018 15:27:33 +0200 - loc * exist * algo * size * imp *** +- @media queries to reduce indentation on low-res displays + some mails in the Viewport for man.openbsd.org thread + e.g. Adam Thompson 24 May 2018 15:09:00 -0500 - wrap Sh and Ss content into <div> Laura Morales <lauretas at mail dot com> 21 Apr 2018 18:10:48 +0200 @@ -22,6 +22,7 @@ #include <assert.h> #include <ctype.h> #include <stdarg.h> +#include <stddef.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -29,6 +30,7 @@ #include <unistd.h> #include "mandoc_aux.h" +#include "mandoc_ohash.h" #include "mandoc.h" #include "roff.h" #include "out.h" @@ -117,6 +119,9 @@ static const char *const roffscales[SCALE_MAX] = { "ex", /* SCALE_FS */ }; +/* Avoid duplicate HTML id= attributes. */ +static struct ohash id_unique; + static void a2width(const char *, struct roffsu *); static void print_byte(struct html *, char); static void print_endword(struct html *); @@ -144,6 +149,8 @@ html_alloc(const struct manoutput *outopts) if (outopts->fragment) h->oflags |= HTML_FRAGMENT; + mandoc_ohash_init(&id_unique, 4, 0); + return h; } @@ -152,15 +159,22 @@ html_free(void *p) { struct tag *tag; struct html *h; + char *cp; + unsigned int slot; h = (struct html *)p; - while ((tag = h->tag) != NULL) { h->tag = tag->next; free(tag); } - free(h); + + cp = ohash_first(&id_unique, &slot); + while (cp != NULL) { + free(cp); + cp = ohash_next(&id_unique, &slot); + } + ohash_delete(&id_unique); } void @@ -257,10 +271,12 @@ print_metaf(struct html *h, enum mandoc_esc deco) } char * -html_make_id(const struct roff_node *n) +html_make_id(const struct roff_node *n, int unique) { const struct roff_node *nch; - char *buf, *cp; + char *buf, *bufs, *cp; + unsigned int slot; + int suffix; for (nch = n->child; nch != NULL; nch = nch->next) if (nch->type != ROFFT_TEXT) @@ -277,6 +293,30 @@ html_make_id(const struct roff_node *n) if (*cp == ' ') *cp = '_'; + if (unique == 0) + return buf; + + /* Avoid duplicate HTML id= attributes. */ + + bufs = NULL; + suffix = 1; + slot = ohash_qlookup(&id_unique, buf); + cp = ohash_find(&id_unique, slot); + if (cp != NULL) { + while (cp != NULL) { + free(bufs); + if (++suffix > 127) { + free(buf); + return NULL; + } + mandoc_asprintf(&bufs, "%s_%d", buf, suffix); + slot = ohash_qlookup(&id_unique, bufs); + cp = ohash_find(&id_unique, slot); + } + free(buf); + buf = bufs; + } + ohash_insert(&id_unique, slot, buf); return buf; } @@ -133,5 +133,5 @@ void print_eqn(struct html *, const struct eqn_box *); void print_paragraph(struct html *); void print_endline(struct html *); -char *html_make_id(const struct roff_node *); +char *html_make_id(const struct roff_node *, int); int html_strlen(const char *); @@ -428,11 +428,10 @@ man_SH_pre(MAN_ARGS) char *id; if (n->type == 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); } return 1; } @@ -498,11 +497,10 @@ man_SS_pre(MAN_ARGS) char *id; if (n->type == ROFFT_HEAD) { - 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; } diff --git a/mdoc_html.c b/mdoc_html.c index d509dceb..7e24fd68 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -502,7 +502,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 html_make_id(n); + return html_make_id(n, 1); return NULL; } @@ -513,11 +513,10 @@ mdoc_sh_pre(MDOC_ARGS) switch (n->type) { 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 +536,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 +551,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 +570,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; } @@ -882,7 +878,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; @@ -1030,7 +1026,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; } @@ -1042,7 +1037,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; } @@ -1055,12 +1049,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; } @@ -1411,7 +1404,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; } @@ -1464,7 +1456,6 @@ mdoc_ms_pre(MDOC_ARGS) if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_SPAN, "cTi", "Ms", id); - free(id); return 1; } @@ -1505,7 +1496,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; } @@ -1517,7 +1507,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; } |