summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--regress/usr.bin/mandoc/mdoc/Sh/Makefile6
-rw-r--r--regress/usr.bin/mandoc/mdoc/Sh/tag.in21
-rw-r--r--regress/usr.bin/mandoc/mdoc/Sh/tag.out_ascii22
-rw-r--r--regress/usr.bin/mandoc/mdoc/Sh/tag.out_html9
-rw-r--r--regress/usr.bin/mandoc/mdoc/Sh/tag.out_markdown27
-rw-r--r--usr.bin/mandoc/mdoc_term.c16
-rw-r--r--usr.bin/mandoc/mdoc_validate.c51
-rw-r--r--usr.bin/mandoc/roff.c4
-rw-r--r--usr.bin/mandoc/roff.h4
-rw-r--r--usr.bin/mandoc/tree.c9
10 files changed, 146 insertions, 23 deletions
diff --git a/regress/usr.bin/mandoc/mdoc/Sh/Makefile b/regress/usr.bin/mandoc/mdoc/Sh/Makefile
index 213664ec7b4..4b37bb2abe0 100644
--- a/regress/usr.bin/mandoc/mdoc/Sh/Makefile
+++ b/regress/usr.bin/mandoc/mdoc/Sh/Makefile
@@ -1,11 +1,11 @@
-# $OpenBSD: Makefile,v 1.12 2020/02/27 01:25:58 schwarze Exp $
+# $OpenBSD: Makefile,v 1.13 2020/02/27 21:38:27 schwarze Exp $
REGRESS_TARGETS = badNAME before empty emptyNAME first nohead order
REGRESS_TARGETS += orderNAME paragraph parbefore parborder punctNAME
-REGRESS_TARGETS += subbefore transp
+REGRESS_TARGETS += subbefore tag transp
LINT_TARGETS = badNAME before empty emptyNAME first nohead order
LINT_TARGETS += orderNAME parbefore parborder punctNAME subbefore
-HTML_TARGETS = paragraph
+HTML_TARGETS = paragraph tag
# groff-1.22.3 defects:
# - .Pp before .Sh NAME causes a blank line before the header line
diff --git a/regress/usr.bin/mandoc/mdoc/Sh/tag.in b/regress/usr.bin/mandoc/mdoc/Sh/tag.in
new file mode 100644
index 00000000000..0e0e5fef16e
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Sh/tag.in
@@ -0,0 +1,21 @@
+.\" $OpenBSD: tag.in,v 1.1 2020/02/27 21:38:27 schwarze Exp $
+.Dd $Mdocdate: February 27 2020 $
+.Dt SH-TAG 1
+.Os
+.Sh NAME
+.Nm Sh-tag
+.Nd tagging section headers
+.Sh DESCRIPTION
+Text in the description.
+.Ss Subsection
+BEGINTEST
+.Pp
+Text in the subsection.
+.Tg examples
+.Sh EXAMPLES
+Text introducing examples.
+.Tg example
+.Ss Subsection
+Example text.
+.Pp
+ENDTEST
diff --git a/regress/usr.bin/mandoc/mdoc/Sh/tag.out_ascii b/regress/usr.bin/mandoc/mdoc/Sh/tag.out_ascii
new file mode 100644
index 00000000000..df0ab050a1e
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Sh/tag.out_ascii
@@ -0,0 +1,22 @@
+SH-TAG(1) General Commands Manual SH-TAG(1)
+
+NNAAMMEE
+ SShh--ttaagg - tagging section headers
+
+DDEESSCCRRIIPPTTIIOONN
+ Text in the description.
+
+ SSuubbsseeccttiioonn
+ BEGINTEST
+
+ Text in the subsection.
+
+EEXXAAMMPPLLEESS
+ Text introducing examples.
+
+ SSuubbsseeccttiioonn
+ Example text.
+
+ ENDTEST
+
+OpenBSD February 27, 2020 OpenBSD
diff --git a/regress/usr.bin/mandoc/mdoc/Sh/tag.out_html b/regress/usr.bin/mandoc/mdoc/Sh/tag.out_html
new file mode 100644
index 00000000000..9722aa8c3c5
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Sh/tag.out_html
@@ -0,0 +1,9 @@
+<p class="Pp">Text in the subsection.</p>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="examples"><a class="permalink" href="#examples">EXAMPLES</a></h1>
+<p class="Pp">Text introducing examples.</p>
+<section class="Ss">
+<h2 class="Ss" id="example"><a class="permalink" href="#example">Subsection</a></h2>
+<p class="Pp">Example text.</p>
diff --git a/regress/usr.bin/mandoc/mdoc/Sh/tag.out_markdown b/regress/usr.bin/mandoc/mdoc/Sh/tag.out_markdown
new file mode 100644
index 00000000000..2813f8f0d28
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Sh/tag.out_markdown
@@ -0,0 +1,27 @@
+SH-TAG(1) - General Commands Manual
+
+# NAME
+
+**Sh-tag** - tagging section headers
+
+# DESCRIPTION
+
+Text in the description.
+
+## Subsection
+
+BEGINTEST
+
+Text in the subsection.
+
+# EXAMPLES
+
+Text introducing examples.
+
+## Subsection
+
+Example text.
+
+ENDTEST
+
+OpenBSD - February 27, 2020
diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c
index dab449d9da4..54252473702 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.276 2020/02/27 01:25:57 schwarze Exp $ */
+/* $OpenBSD: mdoc_term.c,v 1.277 2020/02/27 21:38:27 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -115,7 +115,6 @@ static int termp_pp_pre(DECL_ARGS);
static int termp_ss_pre(DECL_ARGS);
static int termp_sy_pre(DECL_ARGS);
static int termp_tag_pre(DECL_ARGS);
-static int termp_tg_pre(DECL_ARGS);
static int termp_under_pre(DECL_ARGS);
static int termp_vt_pre(DECL_ARGS);
static int termp_xr_pre(DECL_ARGS);
@@ -242,7 +241,7 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = {
{ NULL, termp____post }, /* %Q */
{ NULL, termp____post }, /* %U */
{ NULL, NULL }, /* Ta */
- { termp_tg_pre, NULL }, /* Tg */
+ { termp_skip_pre, NULL }, /* Tg */
};
static int fn_prio = TAG_STRONG;
@@ -339,6 +338,10 @@ print_mdoc_node(DECL_ARGS)
memset(&npair, 0, sizeof(struct termpair));
npair.ppair = pair;
+ if (n->flags & NODE_ID)
+ tag_put(n->string == NULL ? n->child->string : n->string,
+ TAG_MANUAL, p->line);
+
/*
* Keeps only work until the end of a line. If a keep was
* invoked in a prior line, revert it to PREKEEP.
@@ -2064,13 +2067,6 @@ termp_tag_pre(DECL_ARGS)
}
static int
-termp_tg_pre(DECL_ARGS)
-{
- tag_put(n->child->string, TAG_MANUAL, p->line);
- return 0;
-}
-
-static int
termp_abort_pre(DECL_ARGS)
{
abort();
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index 902294e8d79..033a368cd75 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.293 2020/02/27 01:25:58 schwarze Exp $ */
+/* $OpenBSD: mdoc_validate.c,v 1.294 2020/02/27 21:38:27 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -1079,21 +1079,32 @@ post_st(POST_ARGS)
static void
post_tg(POST_ARGS)
{
- struct roff_node *n, *nch;
+ struct roff_node *n, *nch, *nn;
size_t len;
+ /* Find the next node. */
n = mdoc->last;
+ for (nn = n; nn != NULL; nn = nn->parent) {
+ if (nn->next != NULL) {
+ nn = nn->next;
+ break;
+ }
+ }
+
+ /* Add the default argument, if needed. */
nch = n->child;
- if (nch == NULL && n->next != NULL &&
- n->next->child->type == ROFFT_TEXT) {
+ if (nch == NULL && nn != NULL && nn->child->type == ROFFT_TEXT) {
mdoc->next = ROFF_NEXT_CHILD;
roff_word_alloc(mdoc, n->line, n->pos, n->next->child->string);
nch = mdoc->last;
nch->flags |= NODE_NOSRC;
mdoc->last = n;
}
- if (nch == NULL || *nch->string == '\0') {
+
+ /* Validate the first argument. */
+ if (nch == NULL || *nch->string == '\0')
mandoc_msg(MANDOCERR_MACRO_EMPTY, n->line, n->pos, "Tg");
+ if (nch == NULL) {
roff_node_delete(mdoc, n);
return;
}
@@ -1101,14 +1112,42 @@ post_tg(POST_ARGS)
if (nch->string[len] != '\0')
mandoc_msg(MANDOCERR_TG_SPC, nch->line, nch->pos + len + 1,
"Tg %s", nch->string);
+
+ /* Keep only the first argument. */
if (nch->next != NULL) {
mandoc_msg(MANDOCERR_ARG_EXCESS, nch->next->line,
nch->next->pos, "Tg ... %s", nch->next->string);
while (nch->next != NULL)
roff_node_delete(mdoc, nch->next);
}
- if (nch->string[len] != '\0')
+
+ /* Drop the macro if the first argument is invalid. */
+ if (len == 0 || nch->string[len] != '\0') {
roff_node_delete(mdoc, n);
+ return;
+ }
+
+ /* By default, write a <mark> element. */
+ n->flags |= NODE_ID;
+ if (nn == NULL)
+ return;
+
+ /* Explicit tagging of specific macros. */
+ switch (nn->tok) {
+ case MDOC_Sh:
+ case MDOC_Ss:
+ if (nn->head->flags & NODE_ID || nn->head->child == NULL)
+ break;
+ n->flags |= NODE_NOPRT;
+ nn->head->flags |= NODE_ID | NODE_HREF;
+ assert(nn->head->string == NULL);
+ nn->head->string = mandoc_strdup(nch->string);
+ break;
+ default:
+ break;
+ }
+ if (n->flags & NODE_NOPRT)
+ n->flags &= ~NODE_ID;
}
static void
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 9a8e77a9893..31670fc500d 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.242 2020/02/27 01:25:58 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.243 2020/02/27 21:38:27 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -1171,7 +1171,7 @@ deroff(char **dest, const struct roff_node *n)
char *cp;
size_t sz;
- if (n->type != ROFFT_TEXT) {
+ if (n->string == NULL) {
for (n = n->child; n != NULL; n = n->next)
deroff(dest, n);
return;
diff --git a/usr.bin/mandoc/roff.h b/usr.bin/mandoc/roff.h
index 24c0e39bc1f..aeb5c68e08a 100644
--- a/usr.bin/mandoc/roff.h
+++ b/usr.bin/mandoc/roff.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.h,v 1.53 2020/02/27 01:25:58 schwarze Exp $ */
+/* $OpenBSD: roff.h,v 1.54 2020/02/27 21:38:27 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -522,6 +522,8 @@ struct roff_node {
#define NODE_NOFILL (1 << 8) /* Fill mode switched off. */
#define NODE_NOSRC (1 << 9) /* Generated node, not in input file. */
#define NODE_NOPRT (1 << 10) /* Shall not print anything. */
+#define NODE_ID (1 << 11) /* Target for deep linking. */
+#define NODE_HREF (1 << 12) /* Link to another place in this page. */
int prev_font; /* Before entering this node. */
int aux; /* Decoded node data, type-dependent. */
enum roff_tok tok; /* Request or macro ID. */
diff --git a/usr.bin/mandoc/tree.c b/usr.bin/mandoc/tree.c
index 17ea0f60c91..cc123ccf308 100644
--- a/usr.bin/mandoc/tree.c
+++ b/usr.bin/mandoc/tree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tree.c,v 1.52 2020/01/11 16:02:48 schwarze Exp $ */
+/* $OpenBSD: tree.c,v 1.53 2020/02/27 21:38:27 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -197,6 +197,13 @@ print_mdoc(const struct roff_node *n, int indent)
putchar(')');
if (n->flags & NODE_EOS)
putchar('.');
+ if (n->flags & NODE_ID) {
+ printf(" ID");
+ if (n->string != NULL)
+ printf("=%s", n->string);
+ }
+ if (n->flags & NODE_HREF)
+ printf(" HREF");
if (n->flags & NODE_BROKEN)
printf(" BROKEN");
if (n->flags & NODE_NOFILL)