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
