diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2020-04-06 09:55:51 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2020-04-06 09:55:51 +0000 |
commit | 8b440b4adf0207c9d0637b16817fda9700a8a0e9 (patch) | |
tree | 32ef9dde1ac1a79fc25501c9f0d7b80395e0a540 /usr.bin/mandoc | |
parent | cd810fb4ab3cd85588a2f3e795b5c12ca43b1b28 (diff) |
Support manual tagging of .Pp, .Bd, .D1, .Dl, .Bl, and .It.
In HTML output, improve the logic for writing inside permalinks:
skip them when there is no child content or when there is a risk
that the children might contain flow content.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r-- | usr.bin/mandoc/html.c | 23 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc.c | 13 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_html.c | 35 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_term.c | 23 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_validate.c | 48 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 10 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.h | 5 |
7 files changed, 113 insertions, 44 deletions
diff --git a/usr.bin/mandoc/html.c b/usr.bin/mandoc/html.c index c7c87c67a4e..e15c680b296 100644 --- a/usr.bin/mandoc/html.c +++ b/usr.bin/mandoc/html.c @@ -1,4 +1,4 @@ -/* $OpenBSD: html.c,v 1.135 2020/03/13 00:31:04 schwarze Exp $ */ +/* $OpenBSD: html.c,v 1.136 2020/04/06 09:55:49 schwarze Exp $ */ /* * Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> @@ -360,7 +360,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; @@ -767,13 +767,15 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) /* * 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; @@ -786,8 +788,17 @@ print_otag_id(struct html *h, enum htmltag elemtype, const char *cattr, 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 (id != 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", id); + } } return ret; } diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c index a24da770c1a..7920985e33a 100644 --- a/usr.bin/mandoc/mdoc.c +++ b/usr.bin/mandoc/mdoc.c @@ -1,7 +1,7 @@ -/* $OpenBSD: mdoc.c,v 1.163 2018/12/31 07:45:42 schwarze Exp $ */ +/* $OpenBSD: mdoc.c,v 1.164 2020/04/06 09:55:49 schwarze Exp $ */ /* + * Copyright (c) 2010, 2012-2018, 2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Top level and utility functions of the mdoc(7) parser for mandoc(1). */ #include <sys/types.h> @@ -350,12 +352,13 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs) mandoc_msg(MANDOCERR_SPACE_EOL, ln, offs - 1, NULL); /* - * If an initial macro or a list invocation, divert directly - * into macro processing. + * If an initial or transparent macro or a list invocation, + * divert directly into macro processing. */ n = mdoc->last; - if (n == NULL || tok == MDOC_It || tok == MDOC_El) { + if (n == NULL || tok == MDOC_It || tok == MDOC_El || + roff_tok_transparent(tok)) { (*mdoc_macro(tok)->fp)(mdoc, tok, ln, sv, &offs, buf); return 1; } diff --git a/usr.bin/mandoc/mdoc_html.c b/usr.bin/mandoc/mdoc_html.c index 5bf9519941f..d55cb75d0ca 100644 --- a/usr.bin/mandoc/mdoc_html.c +++ b/usr.bin/mandoc/mdoc_html.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_html.c,v 1.212 2020/04/01 20:10:17 schwarze Exp $ */ +/* $OpenBSD: mdoc_html.c,v 1.213 2020/04/06 09:55:49 schwarze Exp $ */ /* * Copyright (c) 2014-2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> @@ -739,7 +739,7 @@ mdoc_it_pre(MDOC_ARGS) case ROFFT_HEAD: return 0; case ROFFT_BODY: - print_otag(h, TAG_LI, ""); + print_otag_id(h, TAG_LI, NULL, n); break; default: break; @@ -751,7 +751,7 @@ mdoc_it_pre(MDOC_ARGS) case LIST_ohang: switch (n->type) { case ROFFT_HEAD: - print_otag(h, TAG_DT, ""); + print_otag_id(h, TAG_DT, NULL, n); break; case ROFFT_BODY: print_otag(h, TAG_DD, ""); @@ -763,7 +763,7 @@ mdoc_it_pre(MDOC_ARGS) case LIST_tag: switch (n->type) { case ROFFT_HEAD: - print_otag(h, TAG_DT, ""); + print_otag_id(h, TAG_DT, NULL, n); break; case ROFFT_BODY: if (n->child == NULL) { @@ -784,7 +784,7 @@ mdoc_it_pre(MDOC_ARGS) print_otag(h, TAG_TD, ""); break; default: - print_otag(h, TAG_TR, ""); + print_otag_id(h, TAG_TR, NULL, n); } default: break; @@ -850,8 +850,8 @@ mdoc_bl_pre(MDOC_ARGS) case LIST_tag: if (bl->offs) print_otag(h, TAG_DIV, "c", "Bd-indent"); - print_otag(h, TAG_DL, "c", bl->comp ? - "Bl-tag Bl-compact" : "Bl-tag"); + print_otag_id(h, TAG_DL, + bl->comp ? "Bl-tag Bl-compact" : "Bl-tag", n->body); return 1; case LIST_column: elemtype = TAG_TABLE; @@ -864,7 +864,7 @@ mdoc_bl_pre(MDOC_ARGS) (void)strlcat(cattr, " Bd-indent", sizeof(cattr)); if (bl->comp) (void)strlcat(cattr, " Bl-compact", sizeof(cattr)); - print_otag(h, elemtype, "c", cattr); + print_otag_id(h, elemtype, cattr, n->body); return 1; } @@ -896,15 +896,15 @@ mdoc_d1_pre(MDOC_ARGS) switch (n->type) { case ROFFT_BLOCK: html_close_paragraph(h); - break; + return 1; case ROFFT_HEAD: return 0; case ROFFT_BODY: - return 1; + break; default: abort(); } - print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); + print_otag_id(h, TAG_DIV, "Bd Bd-indent", n); if (n->tok == MDOC_Dl) print_otag(h, TAG_CODE, "c", "Li"); return 1; @@ -961,7 +961,7 @@ mdoc_bd_pre(MDOC_ARGS) strcmp(n->norm->Bd.offs, "left") != 0) (void)strlcat(buf, " Bd-indent", sizeof(buf)); - print_otag(h, TAG_DIV, "c", buf); + print_otag_id(h, TAG_DIV, buf, n); return 1; } @@ -1208,11 +1208,16 @@ mdoc_pp_pre(MDOC_ARGS) { if (n->flags & NODE_NOFILL) { print_endline(h); - h->col = 1; - print_endline(h); + if (n->flags & NODE_ID) + mdoc_tg_pre(meta, n, h); + else { + h->col = 1; + print_endline(h); + } } else { html_close_paragraph(h); - print_otag(h, TAG_P, "c", "Pp"); + print_otag(h, TAG_P, "ci", "Pp", + n->flags & NODE_ID ? html_make_id(n, 1) : NULL); } return 0; } diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c index edbbec08797..6362a214a22 100644 --- a/usr.bin/mandoc/mdoc_term.c +++ b/usr.bin/mandoc/mdoc_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_term.c,v 1.278 2020/03/13 00:31:05 schwarze Exp $ */ +/* $OpenBSD: mdoc_term.c,v 1.279 2020/04/06 09:55:49 schwarze Exp $ */ /* * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> @@ -333,7 +333,8 @@ print_mdoc_node(DECL_ARGS) memset(&npair, 0, sizeof(struct termpair)); npair.ppair = pair; - if (n->flags & NODE_ID) + if (n->flags & NODE_ID && n->tok != MDOC_Pp && + (n->tok != MDOC_It || n->type != ROFFT_BLOCK)) term_tag_write(n, p->line); /* @@ -628,6 +629,8 @@ termp_it_pre(DECL_ARGS) if (n->type == ROFFT_BLOCK) { print_bvspace(p, n->parent->parent, n); + if (n->flags & NODE_ID) + term_tag_write(n, p->line); return 1; } @@ -1108,7 +1111,6 @@ termp_ex_pre(DECL_ARGS) static int termp_nd_pre(DECL_ARGS) { - if (n->type == ROFFT_BODY) term_word(p, "\\(en"); return 1; @@ -1117,14 +1119,20 @@ termp_nd_pre(DECL_ARGS) static int termp_bl_pre(DECL_ARGS) { - - return n->type != ROFFT_HEAD; + switch (n->type) { + case ROFFT_BLOCK: + term_newln(p); + return 1; + case ROFFT_HEAD: + return 0; + default: + return 1; + } } static void termp_bl_post(DECL_ARGS) { - if (n->type != ROFFT_BLOCK) return; term_newln(p); @@ -1138,7 +1146,6 @@ termp_bl_post(DECL_ARGS) static int termp_xr_pre(DECL_ARGS) { - if (NULL == (n = n->child)) return 0; @@ -1553,6 +1560,8 @@ static int termp_pp_pre(DECL_ARGS) { term_vspace(p); + if (n->flags & NODE_ID) + term_tag_write(n, p->line); return 0; } diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index 4b22e617e22..b50a92a811b 100644 --- a/usr.bin/mandoc/mdoc_validate.c +++ b/usr.bin/mandoc/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_validate.c,v 1.297 2020/04/02 14:55:29 schwarze Exp $ */ +/* $OpenBSD: mdoc_validate.c,v 1.298 2020/04/06 09:55:49 schwarze Exp $ */ /* * Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> @@ -1090,6 +1090,7 @@ post_tg(POST_ARGS) struct roff_node *n; /* The .Tg node. */ struct roff_node *nch; /* The first child of the .Tg node. */ struct roff_node *nn; /* The next node after the .Tg node. */ + struct roff_node *np; /* The parent of the next node. */ struct roff_node *nt; /* The TEXT node containing the tag. */ size_t len; /* The number of bytes in the tag. */ @@ -1135,7 +1136,7 @@ post_tg(POST_ARGS) } /* By default, tag the .Tg node itself. */ - if (nn == NULL) + if (nn == NULL || nn->flags & NODE_ID) nn = n; /* Explicit tagging of specific macros. */ @@ -1143,8 +1144,41 @@ post_tg(POST_ARGS) case MDOC_Sh: case MDOC_Ss: case MDOC_Fo: - nn = nn->head; - /* FALLTHROUGH */ + nn = nn->head->child == NULL ? n : nn->head; + break; + case MDOC_It: + np = nn->parent; + while (np->tok != MDOC_Bl) + np = np->parent; + switch (np->norm->Bl.type) { + case LIST_column: + break; + case LIST_diag: + case LIST_hang: + case LIST_inset: + case LIST_ohang: + case LIST_tag: + nn = nn->head; + break; + case LIST_bullet: + case LIST_dash: + case LIST_enum: + case LIST_hyphen: + case LIST_item: + nn = nn->body->child == NULL ? n : nn->body; + break; + default: + abort(); + } + break; + case MDOC_Bd: + case MDOC_Bl: + case MDOC_D1: + case MDOC_Dl: + nn = nn->body->child == NULL ? n : nn->body; + break; + case MDOC_Pp: + break; case MDOC_Cm: case MDOC_Dv: case MDOC_Em: @@ -1157,9 +1191,9 @@ post_tg(POST_ARGS) case MDOC_Ms: case MDOC_No: case MDOC_Sy: - if (nn->child != NULL && (nn->flags & NODE_ID) == 0) - break; - /* FALLTHROUGH */ + if (nn->child == NULL) + nn = n; + break; default: nn = n; break; diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index a69f632a6cb..035f53ac62f 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.244 2020/04/03 11:34:19 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.245 2020/04/06 09:55:49 schwarze Exp $ */ /* * Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> @@ -1121,7 +1121,13 @@ roff_node_transparent(struct roff_node *n) return 0; if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return 1; - switch (n->tok) { + return roff_tok_transparent(n->tok); +} + +int +roff_tok_transparent(enum roff_tok tok) +{ + switch (tok) { case ROFF_ft: case ROFF_ll: case ROFF_mc: diff --git a/usr.bin/mandoc/roff.h b/usr.bin/mandoc/roff.h index aeb5c68e08a..2f010f1edbf 100644 --- a/usr.bin/mandoc/roff.h +++ b/usr.bin/mandoc/roff.h @@ -1,7 +1,7 @@ -/* $OpenBSD: roff.h,v 1.54 2020/02/27 21:38:27 schwarze Exp $ */ +/* $OpenBSD: roff.h,v 1.55 2020/04/06 09:55:49 schwarze Exp $ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -557,3 +557,4 @@ struct roff_node *roff_node_child(struct roff_node *); struct roff_node *roff_node_next(struct roff_node *); struct roff_node *roff_node_prev(struct roff_node *); int roff_node_transparent(struct roff_node *); +int roff_tok_transparent(enum roff_tok); |