Hi Branden,

On Mon, Aug 11, 2025 at 08:17:35PM -0500, G. Branden Robinson wrote:
> At 2025-08-07T13:04:21+0200, Alejandro Colomar wrote:
> > Do we want to diagnose blank lines in input before TH?
> > 
> >     alx@debian:~/tmp$ cat blank.man | nl -ba
> >          1  
> >          2  .TH a 2 d f
> >          3  .SH foo
> >          4  
> >          5  foo
> >     alx@debian:~/tmp$ groff -man -Tutf8 -wbreak -rCHECKSTYLE=3 blank.man 
> >     an.tmac:blank.man:4: style: blank line in input
> > 
> >     a(2)                          System Calls Manual                       
> >   a(2)
> > 
> >     foo
> >            foo
> > 
> >     f                                      d                                
> >   a(2)
> > 
> > It seems inconsistent to not diagnose that.
> 
> At the time that blank line is read, we don't know whether a man(7) or
> an mdoc(7) document is being read (and thus whether `CHECKSTYLE` is
> meaningful at all).  While you've presumed that with the `-man`
> argument, the preponderant mode of usage of the man(7) macro package is
> via `nroff -mandoc`, and that via man(1).  So in that preponderant case,
> we _don't_ actually know that.
> 
> This _could_ be resolved by having the man(7) package invoke `blm` and
> `lsm` at initialization as well as within the `TH` macro definition.
> "andoc.tmac" already cleans up the traps when changing macro packages so
> this probably wouldn't be a difficult to do.
> 
> There would remain the risk of the _man_ macro package diagnosing blank
> lines at the top of an mdoc(7) document, which could be confusing.

If you run groff -man on an mdoc(7) document, I would find it
reasonable, actually.  Wouldn't you?

If you run -mandoc, then yes, we should not diagnose yet.

> Recall that when multiple pages are formatted, we don't know which macro
> package is in use until we see either a `TH` or a `Dd` macro call.

But when multiple pages are formatted, you'll specify -mandoc, not -man.
(Or if you specify -man, you get what you asked for, so nothing new
 under the sun.)

> In principle, we could parse the contents of the `.F` register.  But
> string parsing in *roff is hard because we don't have a
> string/macro/diversion iterator.[1]  And if GNU troff is reading
> standard input, `\n[.F]` will tell us nothing useful.
> 
> It's also not difficult for a man(7) document maintainer to add a "grep
> '^$' *.man" command to some sort of linter target in a Makefile.  ;-)

Heh!  That wouldn't be too difficult, indeed.  :-)

        commit 4a4fc81908a59bd82e33b7fbe1ad7ed9926f6b37
        Author: Alejandro Colomar <a...@kernel.org>
        Date:   Tue Aug 12 11:09:48 2025 +0200

            share/mk/: lint-man-blank: Add target to lint about blank lines
            
            groff's CHECKSTYLE already warns about this, but it's imperfect,
            and it doesn't work with mdoc(7).  This linter is simpler, and
            works better.
            
            Suggested-by: "Branden G. Robinson" <bran...@debian.org>"
            Signed-off-by: Alejandro Colomar <a...@kernel.org>

        diff --git a/share/mk/lint/man/_.mk b/share/mk/lint/man/_.mk
        index 3d641535c..e17ee9a5a 100644
        --- a/share/mk/lint/man/_.mk
        +++ b/share/mk/lint/man/_.mk
        @@ -7,7 +7,7 @@ MAKEFILE_LINT_MAN_INCLUDED := 1
         
         
         .PHONY: lint-man
        -lint-man: lint-man-mandoc lint-man-tbl lint-man-so;
        +lint-man: lint-man-blank lint-man-mandoc lint-man-tbl lint-man-so;
         
         
         endif  # include guard
        diff --git a/share/mk/lint/man/blank.mk b/share/mk/lint/man/blank.mk
        new file mode 100644
        index 000000000..96fd4b37b
        --- /dev/null
        +++ b/share/mk/lint/man/blank.mk
        @@ -0,0 +1,35 @@
        +# Copyright, the authors of the Linux man-pages project
        +# SPDX-License-Identifier: LGPL-3.0-only WITH 
LGPL-3.0-linking-exception
        +
        +
        +ifndef MAKEFILE_LINT_MAN_BLANK_INCLUDED
        +MAKEFILE_LINT_MAN_BLANK_INCLUDED := 1
        +
        +
        +include $(MAKEFILEDIR)/build/man/man.mk
        +include $(MAKEFILEDIR)/build/man/mdoc.mk
        +include $(MAKEFILEDIR)/configure/build-depends/coreutils/cat.mk
        +include $(MAKEFILEDIR)/configure/build-depends/coreutils/echo.mk
        +include $(MAKEFILEDIR)/configure/build-depends/coreutils/touch.mk
        +include $(MAKEFILEDIR)/configure/build-depends/grep/grep.mk
        +
        +
        +_LINT_man_blank := $(patsubst %, %.lint-man.blank.touch, $(_NONSO_MAN) 
$(_NONSO_MDOC))
        +
        +
        +$(_LINT_man_blank): %.lint-man.blank.touch: % $(MK) | $$(@D)/
        +       $(info  $(INFO_)GREP ^$$                $@)
        +       $(CAT) <$< \
        +       | if $(GREP) '^$$' >/dev/null; then \
        +               >&2 $(ECHO) "$<: spurious blank lines:"; \
        +               >&2 $(GREP) -n '^$$' <$<; \
        +               exit 1; \
        +       fi;
        +       $(TOUCH) $@
        +
        +
        +.PHONY: lint-man-blank
        +lint-man-blank: $(_LINT_man_blank);
        +
        +
        +endif  # include guard

Actually, I'm going to add this commit, even if you improve CHECKSTYLE,
because I also want to diagnose mdoc(7) pages about it.

The output looks like this:

        $ make lint-man-blank -R
        GREP ^$         .tmp/man/man7/bpf-helpers.7.lint-man.blank.touch
        .tmp/man/man7/bpf-helpers.7: spurious blank lines:
        548:
        552:
        555:
        3057:
        make: *** 
[/srv/alx/src/linux/man-pages/man-pages/contrib/share/mk/lint/man/blank.mk:22: 
.tmp/man/man7/bpf-helpers.7.lint-man.blank.touch] Error 1

(BTW, anyone that tells me that autotools will make my life simpler,
 I should ask them how I could do the same with autotools, in about the
 same 5 minutes.)


Have a lovley day!
Alex


P.S.:  How are you doing with the countof() patches?  Do you need me to
       do anything about them?

-- 
<https://www.alejandro-colomar.es/>

Attachment: signature.asc
Description: PGP signature

Reply via email to