diff options
-rw-r--r-- | example.style.css | 1 | ||||
-rw-r--r-- | html.c | 9 | ||||
-rw-r--r-- | html.h | 2 | ||||
-rw-r--r-- | mandoc.1 | 20 | ||||
-rw-r--r-- | mdoc_html.c | 83 |
5 files changed, 89 insertions, 26 deletions
diff --git a/example.style.css b/example.style.css index 1867d4fe..cbb279cb 100644 --- a/example.style.css +++ b/example.style.css @@ -54,6 +54,7 @@ span.utility { font-weight: bold; } /* Name of utility (Ex). */ span.var { font-weight: bold; } /* Variables (Rv). */ a.link-ext { } /* Off-site link (Lk). */ +a.link-includes { } /* Include-file link (In). */ a.link-mail { } /* Mailto links (Mt). */ a.link-man { } /* Manual links (Xr). */ a.link-sec { } /* Section links (Sx). */ @@ -73,6 +73,7 @@ static const char *const htmlattrs[ATTR_MAX] = { "style", "width", "valign", + "target", }; #ifdef __linux__ @@ -87,7 +88,8 @@ html_alloc(char *outopts) toks[0] = "style"; toks[1] = "man"; - toks[2] = NULL; + toks[2] = "includes"; + toks[3] = NULL; if (NULL == (h = calloc(1, sizeof(struct html)))) return(NULL); @@ -100,8 +102,6 @@ html_alloc(char *outopts) return(NULL); } - h->base_man = "%N.%S.html"; - while (outopts && *outopts) switch (getsubopt(&outopts, toks, &v)) { case (0): @@ -110,6 +110,9 @@ html_alloc(char *outopts) case (1): h->base_man = v; break; + case (2): + h->base_includes = v; + break; default: break; } @@ -56,6 +56,7 @@ enum htmlattr { ATTR_STYLE, ATTR_WIDTH, ATTR_VALIGN, + ATTR_TARGET, ATTR_MAX }; @@ -88,6 +89,7 @@ struct html { void *symtab; char *base; char *base_man; + char *base_includes; char *style; char buf[BUFSIZ]; size_t buflen; @@ -260,6 +260,17 @@ The file .Ar style.css is used for an external style-sheet. This must be a valid absolute or relative URI. +.It Fl o Ns Ar includes=fmt +The string +.Ar fmt , +for example, +.Ar ../src/%I.html , +is used as a template for linked header files (usually via the +.Sq \&In +macro). Instances of +.Sq %I +are replaced with the include filename. The default is not to present a +hyperlink. .It Fl o Ns Ar man=fmt The string .Ar fmt , @@ -267,8 +278,13 @@ for example, .Ar ../html%S/%N.%S.html , is used as a template for linked manuals (usually via the .Sq \&Xr -macro). The default is -.Ar %N.%S.html . +macro). Instances of +.Sq %N +and +.Sq %S +are replaced with the linked manual's name and section, respectively. +If no section is included, section 1 is assumed. The default is not to +present a hyperlink. .El . .Sh EXAMPLES diff --git a/mdoc_html.c b/mdoc_html.c index 0a8bf129..5db4658e 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -56,6 +56,7 @@ static int a2list(const struct mdoc_node *); static void buffmt_man(struct html *, const char *, const char *); +static void buffmt_includes(struct html *, const char *); static void buffmt(struct html *, const char *, ...); static void bufcat(struct html *, const char *); static void bufncat(struct html *, const char *, size_t); @@ -326,15 +327,35 @@ bufncat(struct html *h, const char *p, size_t sz) static void +buffmt_includes(struct html *h, const char *name) +{ + const char *p, *pp; + + pp = h->base_includes; + while ((p = strchr(pp, '%'))) { + bufncat(h, pp, p - pp); + switch (*(p + 1)) { + case('I'): + bufcat(h, name); + break; + default: + bufncat(h, p, 2); + break; + } + pp = p + 2; + } + if (pp) + bufcat(h, pp); +} + + +static void buffmt_man(struct html *h, const char *name, const char *sec) { const char *p, *pp; pp = h->base_man; - - /* FIXME: URL-encode contents. */ - while ((p = strchr(pp, '%'))) { bufncat(h, pp, p - pp); switch (*(p + 1)) { @@ -829,16 +850,20 @@ mdoc_xr_pre(MDOC_ARGS) { struct htmlpair tag[2]; const struct mdoc_node *nn; + int i; - buffmt_man(h, n->child->string, - n->child->next ? - n->child->next->string : NULL); + i = 0; + tag[i].key = ATTR_CLASS; + tag[i++].val = "link-man"; + + if (h->base_man) { + buffmt_man(h, n->child->string, n->child->next ? + n->child->next->string : NULL); + tag[i].key = ATTR_HREF; + tag[i++].val = h->buf; + } - tag[0].key = ATTR_CLASS; - tag[0].val = "link-man"; - tag[1].key = ATTR_HREF; - tag[1].val = h->buf; - print_otag(h, TAG_A, 2, tag); + print_otag(h, TAG_A, i, tag); nn = n->child; print_text(h, nn->string); @@ -1350,7 +1375,7 @@ mdoc_d1_pre(MDOC_ARGS) static int mdoc_sx_pre(MDOC_ARGS) { - struct htmlpair tag[2]; + struct htmlpair tag[3]; const struct mdoc_node *nn; bufcat(h, "#"); @@ -1364,8 +1389,10 @@ mdoc_sx_pre(MDOC_ARGS) tag[0].val = h->buf; tag[1].key = ATTR_CLASS; tag[1].val = "link-sec"; + tag[2].key = ATTR_TARGET; + tag[2].val = "_self"; - print_otag(h, TAG_A, 2, tag); + print_otag(h, TAG_A, 3, tag); return(1); } @@ -1896,21 +1923,23 @@ static int mdoc_in_pre(MDOC_ARGS) { const struct mdoc_node *nn; - struct htmlpair tag; + struct htmlpair tag[2]; + struct tag *t; + int i; if (SEC_SYNOPSIS == n->sec) { if (n->next && MDOC_In != n->next->tok) { - tag.key = ATTR_STYLE; - tag.val = "margin-bottom: 1em;"; - print_otag(h, TAG_DIV, 1, &tag); + tag[0].key = ATTR_STYLE; + tag[0].val = "margin-bottom: 1em;"; + print_otag(h, TAG_DIV, 1, tag); } else print_otag(h, TAG_DIV, 0, NULL); } - tag.key = ATTR_CLASS; - tag.val = "includes"; + tag[0].key = ATTR_CLASS; + tag[0].val = "includes"; - print_otag(h, TAG_SPAN, 1, &tag); + print_otag(h, TAG_SPAN, 1, tag); if (SEC_SYNOPSIS == n->sec) print_text(h, "#include"); @@ -1920,8 +1949,20 @@ mdoc_in_pre(MDOC_ARGS) /* XXX -- see warning in termp_in_post(). */ - for (nn = n->child; nn; nn = nn->next) + for (nn = n->child; nn; nn = nn->next) { + assert(MDOC_TEXT == nn->type); + i = 0; + tag[i].key = ATTR_CLASS; + tag[i++].val = "link-includes"; + if (h->base_includes) { + buffmt_includes(h, nn->string); + tag[i].key = ATTR_HREF; + tag[i++].val = h->buf; + } + t = print_otag(h, TAG_A, i, tag); print_mdoc_node(m, nn, h); + print_tagq(h, t); + } h->flags |= HTML_NOSPACE; print_text(h, ">"); |