and warn about it; mdoclint(1) does so, and it makes sense.
-# $OpenBSD: Makefile,v 1.9 2017/03/08 22:53:35 schwarze Exp $
+# $OpenBSD: Makefile,v 1.10 2017/04/28 16:23:30 schwarze Exp $
REGRESS_TARGETS = badNAME before empty emptyNAME first nohead order
-REGRESS_TARGETS += orderNAME punctNAME subbefore
+REGRESS_TARGETS += orderNAME parbefore parborder punctNAME subbefore
LINT_TARGETS = badNAME before empty emptyNAME first nohead order
-LINT_TARGETS += orderNAME punctNAME subbefore
+LINT_TARGETS += orderNAME parbefore parborder punctNAME subbefore
-SKIP_GROFF = subbefore first empty
-SKIP_ASCII = first
+# groff-1.22.3 defects:
+# - .Pp before .Sh NAME causes a blank line before the header line
+# - .Ss before .Sh NAME puts the subsection header before the header line
+# - missing .Sh NAME causes loss of the header and footer lines
+# - .Sh DESCRIPTION Xo aborts the parser
+
+SKIP_GROFF = parbefore subbefore first empty
.include <bsd.regress.mk>
--- /dev/null
+SH-FIRST(1) General Commands Manual SH-FIRST(1)
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+ The first section is not a NAME section.
+
+OpenBSD July 1, 2014 OpenBSD
--- /dev/null
+.Dd April 28, 2017
+.Dt SH-PARBEFORE 1
+.Os OpenBSD
+.Pp
+.Sh NAME
+.Nm Sh-parbefore
+.Nd paragraph macro before the first section header
+.Sh DESCRIPTION
+some text
--- /dev/null
+SH-PARBEFORE(1) General Commands Manual SH-PARBEFORE(1)
+
+N\bNA\bAM\bME\bE
+ S\bSh\bh-\b-p\bpa\bar\brb\bbe\bef\bfo\bor\bre\be - paragraph macro before the first section header
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+ some text
+
+OpenBSD April 28, 2017 OpenBSD
--- /dev/null
+mandoc: parbefore.in:4:2: WARNING: skipping paragraph macro: Pp before Sh
--- /dev/null
+SH-PARBEFORE(1) - General Commands Manual
+
+# NAME
+
+**Sh-parbefore** - paragraph macro before the first section header
+
+# DESCRIPTION
+
+some text
+
+OpenBSD - April 28, 2017
--- /dev/null
+.Dd April 28, 2017
+.Dt SH-PARBORDER 1
+.Os OpenBSD
+.Sh NAME
+.Nm Sh-parborder
+.Nd paragraph macros at the beginning and end of sections
+.Sh DESCRIPTION
+.Pp
+descriptive text
+.Pp
+.Sh EXAMPLES
+.Pp
+example text
+.Pp
+.Ss Subsection
+.Pp
+subsection text
+.Pp
+.Ss Another subsection
+more subsection text
+.Pp
--- /dev/null
+SH-PARBORDER(1) General Commands Manual SH-PARBORDER(1)
+
+N\bNA\bAM\bME\bE
+ S\bSh\bh-\b-p\bpa\bar\brb\bbo\bor\brd\bde\ber\br - paragraph macros at the beginning and end of sections
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+ descriptive text
+
+E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
+ example text
+
+ S\bSu\bub\bbs\bse\bec\bct\bti\bio\bon\bn
+ subsection text
+
+ A\bAn\bno\bot\bth\bhe\ber\br s\bsu\bub\bbs\bse\bec\bct\bti\bio\bon\bn
+ more subsection text
+
+OpenBSD April 28, 2017 OpenBSD
--- /dev/null
+mandoc: parborder.in:8:2: WARNING: skipping paragraph macro: Pp after Sh
+mandoc: parborder.in:10:2: WARNING: skipping paragraph macro: Pp at the end of Sh
+mandoc: parborder.in:12:2: WARNING: skipping paragraph macro: Pp after Sh
+mandoc: parborder.in:16:2: WARNING: skipping paragraph macro: Pp after Ss
+mandoc: parborder.in:18:2: WARNING: skipping paragraph macro: Pp at the end of Ss
+mandoc: parborder.in:14:2: WARNING: skipping paragraph macro: Pp before Ss
+mandoc: parborder.in:21:2: WARNING: skipping paragraph macro: Pp at the end of Ss
--- /dev/null
+SH-PARBORDER(1) - General Commands Manual
+
+# NAME
+
+**Sh-parborder** - paragraph macros at the beginning and end of sections
+
+# DESCRIPTION
+
+descriptive text
+
+# EXAMPLES
+
+example text
+
+## Subsection
+
+subsection text
+
+## Another subsection
+
+more subsection text
+
+OpenBSD - April 28, 2017
-/* $OpenBSD: mdoc_validate.c,v 1.236 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: mdoc_validate.c,v 1.237 2017/04/28 16:23:30 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
struct roff_node *np;
switch (mdoc->last->type) {
+ case ROFFT_BLOCK:
+ post_prevpar(mdoc);
+ return;
case ROFFT_HEAD:
post_hyph(mdoc);
return;