Hello,

this message is about the man-db program  https://man-db.nongnu.org/
rather than about roff, but i'm posting it here because manual page
questions (including with respect to man-db and other man(1) programs)
are often discussed here, whereas the man-db mailing list had no postings
since 2023:  https://lists.nongnu.org/archive/html/man-db-devel/

I'm referring to this feature, quoting from
https://manpages.debian.org/unstable/man-db/man.1.en.html :

  -l, --local-file
    Activate "local" mode.  Format and display local manual files
    [...]
    If this option is not used, then man will also fall back to
    interpreting manual page arguments as local file names if the
    argument contains a "/" character, since that is a good
    indication that the argument refers to a path on the file system. 

Mandoc adopted this logic for man-db compatibility in 2018, which
was in fact discussed on this very list:

  https://lists.gnu.org/archive/html/groff/2018-04/msg00032.html
  https://lists.gnu.org/archive/html/groff/2018-04/msg00036.html
  https://marc.info/?l=mandoc-source&m=158605368805431

In OpenBSD, it recently came up that this small feature is not
documented for the mandoc implementation of man(1).  When i proposed
(internally in the project) to document it in a COMPATIBILITY section
saying it is supported for man-db compatibility only and discouraging
its use, i met opposition and other developers requested that the
feature instead be removed, for the following reasons:

 1. The main reason is that there is no good way to document the
    feature.  When this happens, that is usually a symptom of an
    ill-designed feature.  So, which options are there for
    documenting it?

     1.1. The canonical place to document this feature is where
          the "page" argument is described, and that is in the
          second sentence of the first paragraph of the man-db
          manual page (and the place would be very similar for
          mandoc man(1)).

          That would be a terrible place because adding a sentence
          in the middle of the first paragraph would muddle the
          waters what the point of the man(1) command is in the
          first place.  It would add tricky complications before
          finishing the explanation of the basics - which would
          be particularly dire in this manual page because it's
          one of the first pages new users get sent to.

     1.2. Below the -l option, as man-db does it, it an anti-logical
          place.  The description of an option is supposed to
          explain what an option does, *not* what happens when
          the option is *not* specified.

          The default behaviour of a program that occurs when
          options are *not* specified really needs to be explained
          before the option list.

     1.3. Somewhere near the end of the page, for example in a
          COMPATIBILITY or CAVEATS section, would mitigate the
          issue of lending undue weight to an unimportant and
          hard-to-explain feature, but it is not a satisfaxtory
          option either.  People who want to understand what
          the "page" argument does won't find it in such a place,
          even less than they now find it below -l.

 2. The secondary reason for deleting the feature is that it is not
    useful and nobody could come up with a use case where it is needed.
    Whenever you say "man path/to/file.1", you can just as easily,
    and indeed more clearly, say "man -l path/to/file.1".
    The possibility to mix page name and file name arguments
    on the same command line, like "man true ./file.1 false"
    is also more confusing than useful - it's hard to see
    what practical purpose that could possibly serve.

 3. In addition to lacking a use case, the feature implements
    gratuitios magic for a purpose that can already be achieved
    with well-defined syntax (that is not even long or cumbersome).
    In general, avoiding needless magic results in a better and
    more usable user interface.

 4. Finally, and maybe least importantly, the feature causes
    needless ambuguity and hence minor fragility.
    While manual page names containing slashes are quite rare,
    a few do exist - for example, in the OpenBSD base system:

       $ man -k Nm=/
      podbuildtoc, pod/buildtoc(1) - Generate table of contents
      rc.d(8) - daemon control scripts

    In FreeBSD-14.2, there are more:

       $ man -M FreeBSD-14.2 -k Nm=/
      ioat, I/OAT(4) - Intel I/O Acceleration Technology
      bootparams(5) - boot parameter database
      openssl-core.h, openssl/core.h(7, 7ossl) - OpenSSL Core types
      openssl-core_dispatch.h, openssl/core_dispatch.h(7, 7ossl) - OpenSSL
        provider dispatch numbers and function types
      openssl-core_names.h, openssl/core_names.h(7, 7ossl) - OpenSSL
        provider parameter names
      locate.updatedb, updatedb(8) - update locate database
      makewhatis.local(8) - start makewhatis for local file systems
      rc, rc.firewall, rc.local, rc.resume, rc.shutdown, rc.d, rc.network,
        rc.pccard, rc.serial(8) - command scripts for auto-reboot and
        daemon startup
      rpc.rquotad(8) - remote quota server
      rpc.rstatd(8) - kernel statistics server
      rpc.rusersd(8) - logged in users server
      rpc.rwalld(8) - write messages to users currently logged in server
      rpc.sprayd, sprayd(8) - spray server
      ypxfr(8) - transfer NIS database from remote server to local host

    In addition to those, NetBSD has:

      dns-sd(1) - Multicast DNS (mDNS) & DNS Service Discovery (DNS-SD)
        Test Tool
      bufferevent.h, event2/bufferevent.h(3) - Functions for buffering
        data for network sending or receiving.
      evbuffer.h, event2/buffer.h(3) - Functions for buffering data
        for network sending or receiving.
      event.h, event2/event.h(3) - Core functions for waiting for
        and receiving events, and using event bases.
      binstall, /usr/mdec/binstall(8/sparc) - install sparc and sparc64
        boot blocks
      installboot(8/amiga) - install a bootstrap on an FFS filesystem partition
      installboot(8/atari) - install a bootstrap on an FFS filesystem partition
      installboot(8/mvme68k) - install a bootstrap on a UFS disk
      mkbootimage(8/alpha) - turn Alpha bootstrap programs into bootable images
      setnetbootinfo(8/alpha) - configure Alpha network bootstrap program
      sgivol, /usr/mdec/sgivol(8/sgimips) - configure SGI Volume Header
      telnetd(8) - DARPA TELNET protocol server

    More examples may or may not exist in manual pages for portable
    software that can optionally be installed on various systems.

So my preferred solution would be to delete the feature from both man-db
and mandoc and tell users to use -l when -l is what they mean, for
improved clarity, reduced ambiguity, and simpler and shorter documentation.

If that removal is not decided, i wonder whether i should remove it only
from mandoc in OpenBSD but leave it in portable mandoc (which is used
optionally in many and by default in a few Linux distros) for compatibility,
or delete it outright from mandoc everywhere?

Or can anyone provide a good reason what this magic and quirky feature
is actually needed for, and how to document it properly without
degrading the quality of the documentation by either making it
excessively prominent and disrupting more important text, or
putting it in an inadequate place such that people won't find it?

Yours,
  Ingo

Reply via email to