summaryrefslogtreecommitdiffstats
path: root/mdoc_state.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2022-08-19 12:59:26 +0000
committerIngo Schwarze <schwarze@openbsd.org>2022-08-19 12:59:26 +0000
commit8ab16425f033eb7746389e5b15f332b1d2f7e1a8 (patch)
tree34b1d6fda35bfecae161501db8cb3b7625e275ae /mdoc_state.c
parent1dca33b2df29acbdabc2665070c4b99605298bcb (diff)
downloadmandoc-8ab16425f033eb7746389e5b15f332b1d2f7e1a8.tar.gz
Up to version 1.22.4, groff_mdoc(7) only considered the first word
when comparing section headers. For example, ".Sh SEE ELSEWHERE" and ".Sh SEE Em ALSO" were considered instances of a SEE ALSO section. In groff-current, exact matches with no sub-macros are required. Adjust mandoc behaviour. While here, also fix a very minor mandoc bug, even though no detrimental effect of the bug on formatting is known. While using sub-macros in the .Sh HEAD is bad style, the parsers accept it, so setting the section attribute on the HEAD needs to act recursively.
Diffstat (limited to 'mdoc_state.c')
-rw-r--r--mdoc_state.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/mdoc_state.c b/mdoc_state.c
index eca7a0d4..81e76334 100644
--- a/mdoc_state.c
+++ b/mdoc_state.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2014, 2015, 2017, 2021 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014,2015,2017,2018,2022 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
@@ -37,6 +37,7 @@
typedef void (*state_handler)(STATE_ARGS);
+static void setsec(struct roff_node *, enum roff_sec);
static void state_bl(STATE_ARGS);
static void state_sh(STATE_ARGS);
static void state_sm(STATE_ARGS);
@@ -208,35 +209,36 @@ state_bl(STATE_ARGS)
}
static void
-state_sh(STATE_ARGS)
+setsec(struct roff_node *n, enum roff_sec sec)
{
struct roff_node *nch;
- char *secname;
- if (n->type != ROFFT_HEAD)
- return;
+ n->sec = sec;
+ for (nch = n->child; nch != NULL; nch = nch->next)
+ setsec(nch, sec);
+}
- if ( ! (n->flags & NODE_VALID)) {
- secname = NULL;
- deroff(&secname, n);
+/*
+ * Set the section attribute for the BLOCK, HEAD, and HEAD children.
+ * For other nodes, including the .Sh BODY, this is done when allocating
+ * the node data structures, but for .Sh BLOCK and HEAD, the section is
+ * still unknown at that time.
+ */
+static void
+state_sh(STATE_ARGS)
+{
+ enum roff_sec sec;
- /*
- * Set the section attribute for the BLOCK, HEAD,
- * and HEAD children; the latter can only be TEXT
- * nodes, so no recursion is needed. For other
- * nodes, including the .Sh BODY, this is done
- * when allocating the node data structures, but
- * for .Sh BLOCK and HEAD, the section is still
- * unknown at that time.
- */
+ if (n->type != ROFFT_HEAD)
+ return;
- n->sec = n->parent->sec = secname == NULL ?
- SEC_CUSTOM : mdoc_a2sec(secname);
- for (nch = n->child; nch != NULL; nch = nch->next)
- nch->sec = n->sec;
- free(secname);
+ if ((n->flags & NODE_VALID) == 0) {
+ sec = n->child != NULL && n->child->type == ROFFT_TEXT &&
+ n->child->next == NULL ? mdoc_a2sec(n->child->string) :
+ SEC_CUSTOM;
+ n->parent->sec = sec;
+ setsec(n, sec);
}
-
if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
roff_setreg(mdoc->roff, "nS", 1, '=');
mdoc->flags |= MDOC_SYNOPSIS;