From fcd488027f8d6316b641cffa970d451df8a92c76 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Sat, 18 Apr 2020 20:40:10 +0000 Subject: When a .Tg is attached to a paragraph, attach the permalink to the first word, or the first few words if they are short. --- Makefile.depend | 10 +++++----- html.c | 25 +++++++++++++++++++++---- html.h | 4 +++- man_validate.c | 4 ++-- mdoc_html.c | 11 +++++++---- mdoc_validate.c | 4 ++-- read.c | 8 ++++---- regress/mdoc/Bd/paragraph.out_html | 8 +++++--- regress/mdoc/Pp/Makefile | 3 ++- regress/mdoc/Pp/arg.in | 8 ++++++-- regress/mdoc/Pp/arg.out_ascii | 6 +++++- regress/mdoc/Pp/arg.out_html | 6 ++++++ regress/mdoc/Pp/arg.out_lint | 6 +++--- regress/mdoc/Pp/arg.out_markdown | 9 +++++++-- regress/mdoc/Pp/arg.out_tag | 4 ++-- regress/mdoc/blank/transp.out_markdown | 3 ++- tag.c | 33 +++++++++++++++++++++++++++++---- tag.h | 4 ++-- term_tag.c | 3 ++- 19 files changed, 115 insertions(+), 44 deletions(-) create mode 100644 regress/mdoc/Pp/arg.out_html diff --git a/Makefile.depend b/Makefile.depend index 5ac54712..147f9daf 100644 --- a/Makefile.depend +++ b/Makefile.depend @@ -38,7 +38,7 @@ man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h man_html.o: man_html.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h html.h main.h man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h term_tag.h main.h -man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h tag.h man.h libmandoc.h roff_int.h libman.h +man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h tag.h mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h roff_int.h mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h mandoc_msg.o: mandoc_msg.c config.h mandoc.h @@ -56,18 +56,18 @@ mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h mdoc_markdown.o: mdoc_markdown.c mandoc_aux.h mandoc.h roff.h mdoc.h main.h mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h mdoc_term.o: mdoc_term.c config.h mandoc_aux.h roff.h mdoc.h out.h term.h term_tag.h main.h -mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h tag.h mdoc.h libmandoc.h roff_int.h libmdoc.h +mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h tag.h msec.o: msec.c config.h mandoc.h libmandoc.h msec.in out.o: out.c config.h mandoc_aux.h tbl.h out.h preconv.o: preconv.c config.h mandoc.h roff.h mandoc_parse.h libmandoc.h -read.o: read.c config.h mandoc_aux.h mandoc.h roff.h tag.h mdoc.h man.h mandoc_parse.h libmandoc.h roff_int.h +read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h libmandoc.h roff_int.h tag.h roff.o: roff.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mandoc_parse.h libmandoc.h roff_int.h tbl_parse.h eqn_parse.h predefs.in roff_html.o: roff_html.c mandoc.h roff.h out.h html.h roff_term.o: roff_term.c mandoc.h roff.h out.h term.h roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h soelim.o: soelim.c config.h compat_stringlist.h st.o: st.c config.h mandoc.h roff.h libmdoc.h -tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h mdoc.h tag.h +tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h mdoc.h roff_int.h tag.h tbl.o: tbl.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_parse.h tbl_int.h tbl_data.o: tbl_data.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h tbl_html.o: tbl_html.c config.h mandoc.h roff.h tbl.h out.h html.h @@ -78,5 +78,5 @@ term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h manconf.h main.h term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h manconf.h main.h term_tab.o: term_tab.c mandoc_aux.h out.h term.h -term_tag.o: term_tag.c config.h mandoc.h roff.h tag.h term_tag.h +term_tag.o: term_tag.c config.h mandoc.h roff.h roff_int.h tag.h term_tag.h tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h tbl.h eqn.h main.h diff --git a/html.c b/html.c index e7adea02..3aef282a 100644 --- a/html.c +++ b/html.c @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.267 2020/04/08 11:56:03 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 @@ -878,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. @@ -898,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; @@ -915,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; } diff --git a/html.h b/html.h index d9e65912..07a42a0c 100644 --- a/html.h +++ b/html.h @@ -1,4 +1,4 @@ -/* $Id: html.h,v 1.107 2020/03/13 15:32:28 schwarze Exp $ */ +/* $Id: html.h,v 1.108 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons @@ -127,6 +127,8 @@ struct tag *print_otag_id(struct html *, enum htmltag, const char *, struct roff_node *); void print_tagq(struct html *, const struct tag *); void print_stagq(struct html *, const struct tag *); +void print_tagged_text(struct html *, const char *, + struct roff_node *); void print_text(struct html *, const char *); void print_tblclose(struct html *); void print_tbl(struct html *, const struct tbl_span *); diff --git a/man_validate.c b/man_validate.c index ee634f50..84fc4424 100644 --- a/man_validate.c +++ b/man_validate.c @@ -1,4 +1,4 @@ -/* $Id: man_validate.c,v 1.152 2020/04/04 20:33:33 schwarze Exp $ */ +/* $Id: man_validate.c,v 1.153 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2010, 2012-2020 Ingo Schwarze * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons @@ -34,11 +34,11 @@ #include "mandoc_aux.h" #include "mandoc.h" #include "roff.h" -#include "tag.h" #include "man.h" #include "libmandoc.h" #include "roff_int.h" #include "libman.h" +#include "tag.h" #define CHKARGS struct roff_man *man, struct roff_node *n diff --git a/mdoc_html.c b/mdoc_html.c index dd0f1235..bff4757f 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.338 2020/04/06 10:16:17 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.339 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2014-2020 Ingo Schwarze * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons @@ -377,10 +377,13 @@ print_mdoc_node(MDOC_ARGS) } t = h->tag; t->refcnt++; - if (NODE_DELIMC & n->flags) + if (n->flags & NODE_DELIMC) h->flags |= HTML_NOSPACE; - print_text(h, n->string); - if (NODE_DELIMO & n->flags) + if (n->flags & NODE_HREF) + print_tagged_text(h, n->string, n); + else + print_text(h, n->string); + if (n->flags & NODE_DELIMO) h->flags |= HTML_NOSPACE; break; case ROFFT_EQN: diff --git a/mdoc_validate.c b/mdoc_validate.c index 82c5e43c..129e4730 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.384 2020/04/08 11:56:03 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.385 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2010-2020 Ingo Schwarze * Copyright (c) 2008-2012 Kristaps Dzonsons @@ -37,11 +37,11 @@ #include "mandoc.h" #include "mandoc_xr.h" #include "roff.h" -#include "tag.h" #include "mdoc.h" #include "libmandoc.h" #include "roff_int.h" #include "libmdoc.h" +#include "tag.h" /* FIXME: .Bl -diag can't have non-text children in HEAD. */ diff --git a/read.c b/read.c index a47240c4..92045964 100644 --- a/read.c +++ b/read.c @@ -1,6 +1,6 @@ -/* $Id: read.c,v 1.217 2020/04/07 22:56:02 schwarze Exp $ */ +/* $Id: read.c,v 1.218 2020/04/18 20:40:10 schwarze Exp $ */ /* - * Copyright (c) 2010-2019 Ingo Schwarze + * Copyright (c) 2010-2020 Ingo Schwarze * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012 Joerg Sonnenberger * @@ -42,12 +42,12 @@ #include "mandoc_aux.h" #include "mandoc.h" #include "roff.h" -#include "tag.h" #include "mdoc.h" #include "man.h" #include "mandoc_parse.h" #include "libmandoc.h" #include "roff_int.h" +#include "tag.h" #define REPARSE_LIMIT 1000 @@ -708,7 +708,7 @@ mparse_result(struct mparse *curp) mdoc_validate(curp->man); else man_validate(curp->man); - tag_postprocess(curp->man->meta.first); + tag_postprocess(curp->man, curp->man->meta.first); } return &curp->man->meta; } diff --git a/regress/mdoc/Bd/paragraph.out_html b/regress/mdoc/Bd/paragraph.out_html index f537335e..07a02769 100644 --- a/regress/mdoc/Bd/paragraph.out_html +++ b/regress/mdoc/Bd/paragraph.out_html @@ -1,6 +1,8 @@ -

normal paragraph

+

+ paragraph

filled display -

paragraph in display

+

in + display

back to normal

another paragraph

@@ -9,7 +11,7 @@ back to normal unfilled display -unfilled + paragraph diff --git a/regress/mdoc/Pp/Makefile b/regress/mdoc/Pp/Makefile index 03d32774..d13a1f3e 100644 --- a/regress/mdoc/Pp/Makefile +++ b/regress/mdoc/Pp/Makefile @@ -1,7 +1,8 @@ -# $OpenBSD: Makefile,v 1.7 2020/04/06 09:55:50 schwarze Exp $ +# $OpenBSD: Makefile,v 1.8 2020/04/18 20:28:46 schwarze Exp $ REGRESS_TARGETS = arg TAG_TARGETS = arg LINT_TARGETS = arg +HTML_TARGETS = arg .include diff --git a/regress/mdoc/Pp/arg.in b/regress/mdoc/Pp/arg.in index 1e62c80c..542cb759 100644 --- a/regress/mdoc/Pp/arg.in +++ b/regress/mdoc/Pp/arg.in @@ -1,11 +1,13 @@ -.\" $OpenBSD: arg.in,v 1.5 2020/04/06 09:55:50 schwarze Exp $ -.Dd $Mdocdate: April 6 2020 $ +.\" $OpenBSD: arg.in,v 1.6 2020/04/18 20:28:46 schwarze Exp $ +.Dd $Mdocdate: April 18 2020 $ .Dt PP-ARG 1 .Os .Sh NAME .Nm Pp-arg .Nd paragraph macro with arguments .Sh DESCRIPTION +BEGINTEST +.Pp line 1 .Tg first .Pp drop this @@ -17,3 +19,5 @@ line 4 .Tg last .Pp final text +.Pp +ENDTEST diff --git a/regress/mdoc/Pp/arg.out_ascii b/regress/mdoc/Pp/arg.out_ascii index 70eebb4d..86ebee94 100644 --- a/regress/mdoc/Pp/arg.out_ascii +++ b/regress/mdoc/Pp/arg.out_ascii @@ -4,6 +4,8 @@ NNAAMMEE PPpp--aarrgg - paragraph macro with arguments DDEESSCCRRIIPPTTIIOONN + BEGINTEST + line 1 line 2 @@ -13,4 +15,6 @@ DDEESSCCRRIIPPTTIIOONN final text -OpenBSD April 6, 2020 OpenBSD + ENDTEST + +OpenBSD April 18, 2020 OpenBSD diff --git a/regress/mdoc/Pp/arg.out_html b/regress/mdoc/Pp/arg.out_html new file mode 100644 index 00000000..c601661c --- /dev/null +++ b/regress/mdoc/Pp/arg.out_html @@ -0,0 +1,6 @@ +

line 1

+

+
+ line 3

+

line 4

+

text

diff --git a/regress/mdoc/Pp/arg.out_lint b/regress/mdoc/Pp/arg.out_lint index 40d77064..79cf10cb 100644 --- a/regress/mdoc/Pp/arg.out_lint +++ b/regress/mdoc/Pp/arg.out_lint @@ -1,3 +1,3 @@ -mandoc: arg.in:13:5: ERROR: skipping all arguments: br drop this -mandoc: arg.in:15:8: ERROR: skipping excess arguments: sp ... drop this -mandoc: arg.in:11:2: ERROR: skipping all arguments: Pp drop +mandoc: arg.in:15:5: ERROR: skipping all arguments: br drop this +mandoc: arg.in:17:8: ERROR: skipping excess arguments: sp ... drop this +mandoc: arg.in:13:2: ERROR: skipping all arguments: Pp drop diff --git a/regress/mdoc/Pp/arg.out_markdown b/regress/mdoc/Pp/arg.out_markdown index 0b06ac9e..a793f5a1 100644 --- a/regress/mdoc/Pp/arg.out_markdown +++ b/regress/mdoc/Pp/arg.out_markdown @@ -6,6 +6,8 @@ PP-ARG(1) - General Commands Manual # DESCRIPTION +BEGINTEST + line 1 line 2 @@ -13,6 +15,9 @@ line 3 line 4 -final text +final +text + +ENDTEST -OpenBSD - April 6, 2020 +OpenBSD - April 18, 2020 diff --git a/regress/mdoc/Pp/arg.out_tag b/regress/mdoc/Pp/arg.out_tag index 443b1be2..c58db368 100644 --- a/regress/mdoc/Pp/arg.out_tag +++ b/regress/mdoc/Pp/arg.out_tag @@ -1,4 +1,4 @@ NAME 3 DESCRIPTION 6 -first 9 -last 14 +first 11 +last 16 diff --git a/regress/mdoc/blank/transp.out_markdown b/regress/mdoc/blank/transp.out_markdown index 9c8ac825..6c317e46 100644 --- a/regress/mdoc/blank/transp.out_markdown +++ b/regress/mdoc/blank/transp.out_markdown @@ -23,7 +23,8 @@ Pp sp 2v: sp Pp: -Double sp: +Double +sp: br blank: diff --git a/tag.c b/tag.c index 0c330f46..105f19e1 100644 --- a/tag.c +++ b/tag.c @@ -1,4 +1,4 @@ -/* $Id: tag.c,v 1.34 2020/04/08 11:56:04 schwarze Exp $ */ +/* $Id: tag.c,v 1.35 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze * @@ -32,6 +32,7 @@ #include "mandoc_ohash.h" #include "roff.h" #include "mdoc.h" +#include "roff_int.h" #include "tag.h" struct tag_entry { @@ -258,13 +259,37 @@ tag_move_id(struct roff_node *n) * to the beginning of the respective paragraphs. */ void -tag_postprocess(struct roff_node *n) +tag_postprocess(struct roff_man *man, struct roff_node *n) { + struct roff_node *nn; + char *cp; + if (n->flags & NODE_ID) { switch (n->tok) { + case MDOC_Pp: + nn = n->next; + if (nn == NULL || nn->type != ROFFT_TEXT || + *nn->string == '\0' || *nn->string == ' ') + break; + /* Use the first few letters for the permalink. */ + cp = nn->string; + while (cp != NULL && cp - nn->string < 5) + cp = strchr(cp + 1, ' '); + if (cp != NULL && cp[1] != '\0') { + /* Split a longer text node. */ + man->last = nn; + man->next = ROFF_NEXT_SIBLING; + roff_word_alloc(man, nn->line, + nn->pos + (cp - nn->string), cp + 1); + man->last->flags = nn->flags; + *cp = '\0'; + } + assert(nn->tag == NULL); + nn->tag = mandoc_strdup(n->tag); + nn->flags |= NODE_HREF; + break; case MDOC_Bd: case MDOC_Bl: - case MDOC_Pp: /* XXX No permalink for now. */ break; default: @@ -281,5 +306,5 @@ tag_postprocess(struct roff_node *n) } } for (n = n->child; n != NULL; n = n->next) - tag_postprocess(n); + tag_postprocess(man, n); } diff --git a/tag.h b/tag.h index c6b6028b..1eace6fd 100644 --- a/tag.h +++ b/tag.h @@ -1,4 +1,4 @@ -/* $Id: tag.h,v 1.13 2020/04/07 22:56:02 schwarze Exp $ */ +/* $Id: tag.h,v 1.14 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2015, 2018, 2019, 2020 Ingo Schwarze * @@ -31,5 +31,5 @@ void tag_alloc(void); int tag_exists(const char *); void tag_put(const char *, int, struct roff_node *); -void tag_postprocess(struct roff_node *); +void tag_postprocess(struct roff_man *, struct roff_node *); void tag_free(void); diff --git a/term_tag.c b/term_tag.c index 201471c5..7895d872 100644 --- a/term_tag.c +++ b/term_tag.c @@ -1,4 +1,4 @@ -/* $Id: term_tag.c,v 1.3 2020/04/08 11:56:04 schwarze Exp $ */ +/* $Id: term_tag.c,v 1.4 2020/04/18 20:40:10 schwarze Exp $ */ /* * Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze * @@ -31,6 +31,7 @@ #include "mandoc.h" #include "roff.h" +#include "roff_int.h" #include "tag.h" #include "term_tag.h" -- cgit v1.2.3-56-ge451