Skip to contentSkip to conversation

New sman(1) script

RFC PATCH In review Seth McDonald 4 participants 20 messages Jan 27 – Jan 29 Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#0 lore raw

cover New sman(1) script

G'day,

When parsing man pages, I've noticed I'm often only interested in a particular set of sections within the page (e.g. SYNOPSIS, HISTORY). And since skimming through the page to get to these sections can get monotonous, I wrote up a small bash script to automate the process.

As far as I can tell, no program in src/bin/ can currently do this. The closest is mansect(1), but that outputs the source code rather than the rendered page. So I've improved the script somewhat and written a brief man page for it, as included in this patch set.

The main advantage to this script as opposed to manually awk(1)ing or sed(1)ing man pages is it can preserve the bold/italic formatting in a rendered man page. It currently does so by using sed(1) to locate the section headers with regex which includes the relevant ANSI escape codes dictating bold and regular text.

I would consider this script a WIP still, and likely shouldn't yet be pushed without further edits. The purpose of this patch set is to gauge interest in and comments on this script, moreso than to be immediately applied to the repo.

As an example, the script currently re-renders the whole man page for each section in a for loop, rather than printing each section from the same rendered page, which would likely be more performant. I also named the script sman(1) primarily because I can't think of a better name.

Feel free to give your thoughts!

Seth McDonald (2):
src/bin/sman: Add script
man/man1/sman.1: Add man page

 man/man1/sman.1 | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/sman    | 54 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 man/man1/sman.1
 create mode 100755 src/bin/sman

Range-diff against v0:

-:  ------------ > 1:  d093a884e5fb src/bin/sman: Add script
-:  ------------ > 2:  e1849d315c95 man/man1/sman.1: Add man page

base-commit: 6754bd1a126ed1e9b7d9c2bc1d221681f5182bb3

Signature · 1 line
2.47.3
#1 lore raw

RFC PATCH 1/2 src/bin/sman: Add script

Add a new bash script 'sman', which displays only select sections of a given man page. For example, the SYNOPSIS of stat(2), or the STANDARDS and BUGS of printf(3). Similar to mansect(1), except it displays the rendered man page rather than the associated source code.

It can parse a formatted man page, displaying the specified sections with bold and italic text if MAN_KEEP_FORMATTING is set. Which makes it more useful than manually isolating the wanted page sections with awk(1) or sed(1), which may remove the formatting.

---
 src/bin/sman | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100755 src/bin/sman
src/bin/sman new file +54 -0
new file mode 100755
index 000000000000..8bc239d16e96
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Copyright, the authors of the Linux man-pages project
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+name="$(basename "$0")"
+
+# fail [error message]
+fail() {
+	(($# >= 1)) && echo "$name: $1"
+	echo "Usage: $name [man section] <man page> <page section>..."
+	exit $#
+}
+
+(($# == 0)) && fail
+(($# < 2)) && fail "Too few arguments."
+
+[[ $(which man) ]] || fail "Failed to find man(1)."
+[[ $(which sed) ]] || fail "Failed to find sed(1)."
+
+[[ $MAN_KEEP_FORMATTING ]] && export MAN_KEEP_FORMATTING=1
+[[ $MANWIDTH ]] && export MANWIDTH
+
+# There are currently no man pages whose name starts with a digit.  So
+# its fair to assume that if the first arg starts with a digit, it's
+# referring to a man section.
+if [[ $1 = [0-9]* ]]
+then
+	msect="$1"
+	shift 1
+fi
+
+mpage="$1"
+shift 1
+(($# == 0)) && fail "No page sections specified."
+
+# Check man page exists before getting the same "No manual Entry" error
+# for each user-specified page section.
+man -w $msect "$mpage" > /dev/null || fail "Failed to find $mpage."
+
+for psect
+do
+	# If MAN_KEEP_FORMATTING is set, the section headers should be
+	# in bold.  So wrap regex in the corresponding ANSI escape codes
+	# in this case.
+	man $msect "$mpage" |
+	if [[ $MAN_KEEP_FORMATTING ]]
+	then
+		sed -En $'/^\e\[1m'"${psect^^}"$'\e\[0?m$/,/^\e\[1m[A-Z][A-Z ]*\e\[0?m$/p'
+	else
+		sed -En '/^'"${psect^^}"'$/,/^[A-Z][A-Z ]*$/p'
+	fi |
+	sed '$d' # Remove trailing section headers.
+done
Signature · 1 line
2.47.3
#2 lore raw

Re: [RFC PATCH v1 1/2] src/bin/sman: Add script

You wrote it confusingly (if I wrote it like that it'd be on purpose;
I doubt that was your intent but that's how it reads),
so I isomorphised your program into third normal form:
-- >8 --
#!/bin/sh
#
# Copyright, the authors of the Linux man-pages project
# SPDX-License-Identifier: GPL-3.0-or-later

name="${0##*/}"

# fail [error message]
fail() {
	[ $# -gt 1 ] && echo "$name: $1"
	echo "Usage: $name [man section] <man page> <page section>..."
	exit $#
}

[ $# -eq 0 ] && fail
[ $# -lt 2 ] && fail "Too few arguments."

command -v man > /dev/null 2>&1 || fail "Failed to find man(1)."
command -v sed > /dev/null 2>&1 || fail "Failed to find sed(1)."

[ -n "$MAN_KEEP_FORMATTING" ] && export MAN_KEEP_FORMATTING=1
[ -n "$MANWIDTH" ] && export MANWIDTH

# There are currently no man pages whose name starts with a digit. So

# its fair to assume that if the first arg starts with a digit, it's
# referring to a man section.
if [ "${1#[0-9]}" != "$1" ]
then
	msect="$1"
	shift 1
fi

mpage="$1"
shift 1
[ $# -eq 0 ] && fail "No page sections specified."

# Check man page exists before getting the same "No manual Entry" error

# for each user-specified page section.
man -w $msect "$mpage" > /dev/null || fail "Failed to find $mpage."

for psect
do
psect=$(printf '%s\n' "$psect" | tr [:lower:] [:upper:])
# If MAN_KEEP_FORMATTING is set, the section headers should be
# in bold. So wrap regex in the corresponding ANSI escape codes # in this case.
man $msect "$mpage" |
if [ -n "$MAN_KEEP_FORMATTING" ]
then
sed -En $'/^\e\[1m'"$psect"$'\e\[0?m$/,/^\e\[1m[A-Z][A-Z ]*\e\[0?m$/p'
else
sed -En '/^'"$psect"'$/,/^[A-Z][A-Z ]*$/p'
fi |
sed '$d' # Remove trailing section headers.
done
-- >8 --

Then I made it behave acceptably thusly:
-- >8 --
#!/bin/sh
# Copyright, the authors of the Linux man-pages project # SPDX-License-Identifier: GPL-3.0-or-later

# Some pages' names start with a digit;

# they require specifying the section explicitly.
msect=
if [ "${1#[0-9]}" != "$1" ]
then
	msect="$1"; shift
fi
[ $# -ge 2 ] || {
	printf 'usage: %s [man-section] man-page page-section...\n' "$0" >&2
	exit 1
}

mpage="$1"; shift

# Check man page exists before getting the same "No manual Entry" error

# for each user-specified page section.
man -w $msect "$mpage" > /dev/null || exit

for psect
do
psect=$(printf '%s\n' "$psect" | tr [:lower:] [:upper:])
# If MAN_KEEP_FORMATTING is set, the section headers will be in bold. man $msect "$mpage" |
sed -En $'/^(\e\[1m)?'"$psect"$'(\e\[0?m)?$/,/^(\e\[1m)?[A-Z][A-Z ]*(\e\[0?m)?$/p' | head -n-1 # Remove trailing section headers.
done
-- >8 --

Observe the following:
1. your comment about sections is obviously false:

      $ find /usr/share/man | grep '/[0-9]'
      /usr/share/man/man8/30-systemd-environment-d-generator.8.gz
      /usr/share/man/man1/7za.1.gz
      /usr/share/man/man1/411toppm.1.gz
      /usr/share/man/man1/2ff.1.gz
      /usr/share/man/man1/7z.1.gz
      /usr/share/man/man1/7zr.1.gz
    the way I'd validate my assumption a priori
    (if my system didn't have pages like this) is with
      curl https://deb.debian.org/debian/dists/sid/main/Contents-all.gz   | zgrep share/man/man./[0-9]
      curl https://deb.debian.org/debian/dists/sid/main/Contents-amd64.gz | zgrep share/man/man./[0-9]
 2. you allowed inheriting msect
 3. 80% of your exit conditions were redundant and impossible to hit
 4. man(1) has already logged the relevant error, don't dump garbage after it
 5. usage string always goes to the standard error stream because it's not the output
 6. if [ -n "$MANwhatever" ], then it's in the environment, so export MANwhatever is a no-op
 7. MAN_KEEP_FORMATTING is documented as being "nonempty is set"
    (exactly how you use it), so there's no need to mangle that, either
 8. man not existing gets you a standard error from the shell
 9. sed not existing is not a real condition; but even if it was, you get
    a real error (also, why were those tests "which"?)
10. MAN_KEEP_FORMATTING doesn't actually do anything anyway for me
    (as in it breaks the output entirely because the headers are in bold:
     S^HSY^HYN^HNO^HOP^HPS^HSI^HIS^HS$ (cat -A format)),
    so re-test the expression for your formatter, but I identified the
    common subexpression and put the bolding thing in "()?"

The utility of the other transformations is hopefully obvious.

If you were shipping this you'd want to do the filtering in one pass because the UX of the sections being out of order is IMO suboptimal. And also processing and fully-bufferring the /whole/ rendered output, for big pages, is so slow
(I tested on voreutils ls(1) ‒ <https://ro.ws.co.ls/man1/ls.1.pdf>
time man ls > /dev/null takes 0m0.513s wall clock; multiply this for each section, and you see how this is suboptimal; similarly, voreutils stty(1) measures 0m1.620s;
this is especially suboptimal since big complex pages are exactly the ones you'd want to filter;
also, I think this wants a negative section filter as well (to remove HISTORY or STANDARDS which may be less relevant))
you can work around this a little by sticking a load of stdbuf -oL on the pipeline, but, again, I think the final for loop should be representable as a one-shot AWK program.

Best,

#3 lore raw

Re: [RFC PATCH v1 1/2] src/bin/sman: Add script

Hi наб,

Quoted 10 lines · наб

You wrote it confusingly (if I wrote it like that it'd be on purpose;
I doubt that was your intent but that's how it reads),
so I isomorphised your program into third normal form:
-- >8 --
#!/bin/sh
#
# Copyright, the authors of the Linux man-pages project
# SPDX-License-Identifier: GPL-3.0-or-later

name="${0##*/}"

I find basename(1) much more readable. Also, it's easier to find documentation about it.

Quoted 4 lines
# fail [error message]
fail() {
	[ $# -gt 1 ] && echo "$name: $1"

I agree [(1) is more readable than '[[...]]'. I prefer test(1), though.

[...]

Quoted 4 lines

-- >8 --

Then I made it behave acceptably thusly:
-- >8 --

[...]

Quoted 1 line

-- >8 --

[...]

Quoted 4 lines

If you were shipping this you'd want to do the filtering in one pass because the UX of the sections being out of order is IMO suboptimal. And also processing and fully-bufferring the /whole/ rendered output, for big pages, is so slow

Quoted 8 lines

(I tested on voreutils ls(1) ‒ <https://ro.ws.co.ls/man1/ls.1.pdf>
time man ls > /dev/null takes 0m0.513s wall clock; multiply this for each section, and you see how this is suboptimal; similarly, voreutils stty(1) measures 0m1.620s;
this is especially suboptimal since big complex pages are exactly the ones you'd want to filter;
also, I think this wants a negative section filter as well (to remove HISTORY or STANDARDS which may be less relevant))

In mansect(1) (see below), you can do negative filtering if you want, by writing a complex-enough PCRE2 pattern that rejects some name(s).

Quoted 3 lines

you can work around this a little by sticking a load of stdbuf -oL on the pipeline, but, again, I think the final for loop should be representable as a one-shot AWK program.

It is, and indeed, that's how I implemented mansect(1). Well, I used pcre2grep(1) instead of awk(1), but it is a one-shot program.

	alx@devuan:~/src/linux/man-pages/man-pages/master$ cat src/bin/mansect 
	#!/bin/bash
	#
	# Copyright, the authors of the Linux man-pages project
	# SPDX-License-Identifier: GPL-3.0-or-later
	set -Eefuo pipefail;


	if test $# -lt 1; then
		>&2 printf '%s\n' "$(basename "$0"): error: Too few arguments."
		exit 1;
	fi;

	s="$1";
	shift;

	if test $# -lt 1; then
		preconv;
	else
		find -H "$@" -not -type d \
		| xargs preconv;
	fi \
	| pcre2grep -M \
		-e '^\.lf 1 ' \
		-e '^\.TH ' \
		-e '(?s)^\.SH ('"$s"')$(?:(?!^\.(lf 1|TH|SH) ).)*';

And as I suggested in the other sub-thread, we can just pipe this to a formatter to get the intended behavior:

	$ cat src/bin/mansectf 
	#!/bin/bash
	#
	# Copyright, the authors of the Linux man-pages project
	# SPDX-License-Identifier: GPL-3.0-or-later
	set -Eefuo pipefail;

	mansect "$@" \
	| man /dev/stdin;

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es>
#4 lore raw

Re: [RFC PATCH v1 1/2] src/bin/sman: Add script

In reply to наб

[whimsical response; ignore ad libitum]

Quoted 3 lines · наб

You wrote it confusingly (if I wrote it like that it'd be on purpose; I doubt that was your intent but that's how it reads), so I isomorphised your program into third normal form:

A) I believe the "correct" locution would be "isomorphed", by analogy with "the party magic-user polymorphed the gate guard into a toad".

B) If you, or anyone else, has a well-defined hierarchy of normal forms for shell scripts, I'm (non-whimsically) interested to see it.

What _does_ normalization look like for a non-decidable language?

https://www.oilshell.org/blog/2016/10/20.html

(While the foregoing discusses GNU Bash specifically, I have read--but not seen a proof, and can't promise that I'd understand a proof if I saw one--that POSIX shell is undecidable as well, the "alias" feature being a sufficient condition to produce thus.)

Regards,
Branden

#5 lore raw

Re: [RFC PATCH v1 1/2] src/bin/sman: Add script

Quoted 6 lines · G. Branden Robinson
Quoted 3 lines · наб

You wrote it confusingly (if I wrote it like that it'd be on purpose; I doubt that was your intent but that's how it reads), so I isomorphised your program into third normal form:

A) I believe the "correct" locution would be "isomorphed", by analogy with "the party magic-user polymorphed the gate guard into a toad".

I got there from "applied isomorphisms" so I analysed it as "isomorphism-ised"; if you morph stuff unchangingly instead, "iso-morphed" makes more sense.

(Isomorphed also reads preferentially reflexive to me,
but I see both in literature with a preference for isomorphed, both used reflexively and not.)

Quoted 4 lines

B) (While the foregoing discusses GNU Bash specifically, I have read--but not seen a proof, and can't promise that I'd understand a proof if I saw one--that POSIX shell is undecidable as well, the "alias" feature being a sufficient condition to produce thus.)

If, AIUI, "undecidable" in this case means "the parser depends on the execution of the program being parsed", then alias is sufficient do ensure this property, but I think it's the only feature that lets you inject macros into the parser,
or otherwise interact with it directly like this.

Best,

#6 lore raw

Re: [RFC PATCH v1 1/2] src/bin/sman: Add script

Quoted 7 lines · наб
Quoted 5 lines · G. Branden Robinson

B) (While the foregoing discusses GNU Bash specifically, I have read--but not seen a proof, and can't promise that I'd understand a proof if I saw one--that POSIX shell is undecidable as well, the "alias" feature being a sufficient condition to produce thus.)

Quoted 5 lines

If, AIUI, "undecidable" in this case means "the parser depends on the execution of the program being parsed", then alias is sufficient do ensure this property, but I think it's the only feature that lets you inject macros into the parser, or otherwise interact with it directly like this.

That sounds plausible to me, and consistent with my occasional, undisciplined, and inadequate research on the topic.

Shall we organize a movement to get "alias" taken out of POSIX 202y/203x? I don't care if implementations keep it around, but it sure seems like a dreadful thing for the standard to _mandate_.

Regards,
Branden

#7 lore raw

RFC PATCH 2/2 man/man1/sman.1: Add man page

In reply to Seth McDonald

Add a man page for the sman(1) script.

---
 man/man1/sman.1 | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 man/man1/sman.1
man/man1/sman.1 new file +69 -0
new file mode 100644
index 000000000000..cd167c735615
@@ -0,0 +1,69 @@
+.\" Copyright, the authors of the Linux man-pages project
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH sman 1 (date) "Linux man-pages (unreleased)"
+.SH NAME
+sman
+\-
+print select sections of manual pages
+.SH SYNOPSIS
+.SY sman
+.RI [ man-section ]
+.I man-page
+.IR page-section \~.\|.\|.
+.YS
+.SH DESCRIPTION
+The
+.B sman
+command prints the rendered
+.IR page-section s
+of
+.IR man-page ,
+in the order given.
+.I page-section
+is case insensitive.
+.P
+If any
+.I page-section
+is not present in the man page,
+it is silently ignored.
+If
+.I man-section
+is specified,
+and
+.I man-page
+is not a local file,
+only the given section number is considered
+when searching for the man page.
+.SH ENVIRONMENT
+See
+.BR man (1).
+.SH EXAMPLES
+.EX
+.RB $\~ "MAN_KEEP_FORMATTING=1 sman 2 nice synopsis standards" ;
+.B SYNOPSIS
+.RS 7
+.B #include <unistd.h>
+.P
+.BI "int nice(int " inc );
+.P
+.RS -4
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.RE
+.P
+.BR nice ():
+    _XOPEN_SOURCE
+        || /* Since glibc 2.19: */ _DEFAULT_SOURCE
+        || /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE
+.RE
+.P
+.B STANDARDS
+.RS 7
+POSIX.1-2024 XSI.
+.RE
+.EE
+.SH SEE ALSO
+.BR man (1),
+.BR mansect (1)
Signature · 1 line
2.47.3
#8 lore raw
In reply to Seth McDonald

[CC += Doug, Branden, наб]

Hi Seth!

Quoted 6 lines · Seth McDonald

G'day,

When parsing man pages, I've noticed I'm often only interested in a particular set of sections within the page (e.g. SYNOPSIS, HISTORY). And since skimming through the page to get to these sections can get monotonous, I wrote up a small bash script to automate the process.

Agree. I wrote mansect(1) for the same exact reason.

Quoted 3 lines

As far as I can tell, no program in src/bin/ can currently do this. The closest is mansect(1), but that outputs the source code rather than the rendered page.

You could use mansect(1) for that, and pipe it to man(1) (or groff(1)).

	$ mansect 'STANDARDS|HISTORY' man2/chmod.2 \
	| MANWIDTH=64 man /dev/stdin \
	| cat;
	chmod(2)              System Calls Manual              chmod(2)
	STANDARDS
	     POSIX.1‐2024.

	HISTORY
	     chmod()
		    SVr4, POSIX.1‐1988, 4.4BSD.

	     fchmod()
		    SVr4, 4.4BSD, SUSv1, POSIX.1‐1996.

	     fchmodat()
		    POSIX.1‐2008.  Linux 2.6.16, glibc 2.4.

	     AT_SYMLINK_NOFOLLOW
		    POSIX.1‐2008, glibc 2.32, Linux 6.5.

	Linux man‐pages (unreleased) (date)                    chmod(2)
Quoted 2 lines

So I've improved the script somewhat and written a brief
man page for it, as included in this patch set.

That covers the main use case of mansect(1), so I think this specialized wrapper could be useful.

Quoted 5 lines

The main advantage to this script as opposed to manually awk(1)ing or sed(1)ing man pages is it can preserve the bold/italic formatting in a rendered man page. It currently does so by using sed(1) to locate the section headers with regex which includes the relevant ANSI escape codes dictating bold and regular text.

Agree.

Quoted 4 lines

I would consider this script a WIP still, and likely shouldn't yet be pushed without further edits. The purpose of this patch set is to gauge interest in and comments on this script, moreso than to be immediately applied to the repo.

I'm somewhat interested. I think I didn't write it myself back then because I wasn't yet sure if that was the good design. With time, I think it makes sense to write it.

One of the question I still ask myself about it is whether it should use find(1) or man -w to find the file names. That is, should it accept manual page names and search in the system, or should the user decide by using find(1) or man -w explicitly and piping it to mansect(1)?

	find man2/ -type f | xargs mansect 'STANDARD|SHISTORY' | man /dev/stdin;
	man -w printf.3 | xargs mansect 'STANDARD|SHISTORY' | man /dev/stdin;
vs
	mansect 'STANDARD|SHISTORY' man2/ | man /dev/stdin;
	mansect 'STANDARD|SHISTORY' printf.3 | man /dev/stdin;

I still think when in doubt, it's better to keep it simple, so I use find(1), and let users find the files with man(1) if they need, and run a pipe.

Back then I also opted for the simplicity of allowing users to decide the formatter with which to format the manual page, which BTW is useful to test different ones (mandoc(1), groff(1)). However, having a wrapper that calls man(1) seems useful.

Quoted 3 lines

As an example, the script currently re-renders the whole man page for each section in a for loop, rather than printing each section from the same rendered page, which would likely be more performant.

I honestly can't read that script. My ability to read other people's bash(1) scripts is quite limited. :)

About the interface, I think I like more the interface of mansect(1), which is

mansect section [file ...]

I think that's ideal. We don't need an argument like man(1)'s -s, because that would be more easily specified as

	mansectf LIBRARY printf.3;

The .3 disambiguates without needing a separate argument. However, I don't think we want to do librarian work here, and think we should entirely refrain from accepting manual page names like man(1). I think we should only accept file names. It should be trivial for someone to use

	man -w printf.3 | xargs mansectf LIBRARY;

That simplifies the parsing logic. By having all non-trailing arguments be mandatory, the interface is more obvious, and easier to remember. Almost all Unix programs have such an interface, where there are fixed arguments, and then goes a possibly-empty list of files (or file-like entities) on which to work, and when the list is empty, the file is /dev/stdin.

About specifying several sections, I prefer using a single argument, for the same reasons: having just one mandatory argument with that meaning, and then a list of files. You can use '|' within the section argument to specify more than one (this is documented in mansect(1)).

	man -w printf.3 | xargs mansectf 'LIBRARY|STANDARDS';

Then, about the implementation, it checks the existence of commands, which is unnecessary: the shell will complain for us if they don't exist.

	$ foo
	bash: foo: command not found

Keep it simple.

Then you export a few things:

+[[ $MAN_KEEP_FORMATTING ]] && export MAN_KEEP_FORMATTING=1 +[[ $MANWIDTH ]] && export MANWIDTH

That seems redundant. If it is already exported, the childs will inherit that.

And then about the main work, it can be done by calling mansect(1) in a pipeline.

With that in mind, I've written my own approach, which I've called mansectf.

	$ cat src/bin/mansectf;
	#!/bin/bash
	#
	# Copyright, the authors of the Linux man-pages project
	# SPDX-License-Identifier: GPL-3.0-or-later
	set -Eefuo pipefail;

	mansect "$@" \
	| man /dev/stdin;

Does this work for you? I look at it and wonder if it's worth a separate script, but then it might be useful for people who are less experienced with man(1). To be fair, few people know that man(1) can accept stdin, and even if they know, sometimes convenience wrappers improve readability: for example, printf(1) is unnecessary given that fprintf(3) exists, yet it's thoroughly used and I find it essential.

	printf("foo");
	fprintf(stdout, "foo");

So, I think such a thin wrapper can have its place, as it's the main use case of mansect(1).

Quoted 2 lines

I also named
the script sman(1) primarily because I can't think of a better name.

There already exist two programs with that name:

	$ apt-file find bin/sman
	axiom: /usr/lib/axiom-20210105dp1/bin/sman
	fricas: /usr/lib/fricas/target/x86_64-pc-linux-gnu/bin/sman

Alternatively, I've thought of calling it mansectf(1), where the trailing 'f' means 'formatted' (as in printf(1)). After all, this is a thin wrapper around mansect(1) that formats the output.

Quoted 1 line

Feel free to give your thoughts!

I've CCed a few people to hear their thoughts.

Have a lovely day!
Alex

Quoted 19 lines

Seth McDonald (2):
src/bin/sman: Add script
man/man1/sman.1: Add man page

 man/man1/sman.1 | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/sman    | 54 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 man/man1/sman.1
 create mode 100755 src/bin/sman

Range-diff against v0:

-:  ------------ > 1:  d093a884e5fb src/bin/sman: Add script
-:  ------------ > 2:  e1849d315c95 man/man1/sman.1: Add man page

base-commit: 6754bd1a126ed1e9b7d9c2bc1d221681f5182bb3

Signature · 1 line
2.47.3
Signature · 1 line
<https://www.alejandro-colomar.es>
#9 lore raw

Hi Alex,

Quoted 12 lines · Alejandro Colomar

[CC += Doug, Branden, наб]

Hi Seth!

Quoted 6 lines · Seth McDonald

G'day,

When parsing man pages, I've noticed I'm often only interested in a particular set of sections within the page (e.g. SYNOPSIS, HISTORY). And since skimming through the page to get to these sections can get monotonous, I wrote up a small bash script to automate the process.

Quoted 7 lines

Agree. I wrote mansect(1) for the same exact reason.

Quoted 3 lines

As far as I can tell, no program in src/bin/ can currently do this. The closest is mansect(1), but that outputs the source code rather than the rendered page.

You could use mansect(1) for that, and pipe it to man(1) (or groff(1)).

I honestly have no idea how that never crossed my mind. Seems so obvious in retrospect lol.

[...]

Quoted 5 lines
Quoted 2 lines

So I've improved the script somewhat and written a brief
man page for it, as included in this patch set.

That covers the main use case of mansect(1), so I think this specialized wrapper could be useful.

Agreed. Less typing = better, after all (afaiu). And it can certainly be more appropriately written as an explict wrapper over mansect(1), rather than its own self-contained script.

[...]

Quoted 4 lines

Back then I also opted for the simplicity of allowing users to decide the formatter with which to format the manual page, which BTW is useful to test different ones (mandoc(1), groff(1)). However, having a wrapper that calls man(1) seems useful.

That makes sense, and I agree with this reasoning for mansect(1). Though I do think a simple wrapper with a reasonable default can be good for when you're not interested in the difference.

Quoted 6 lines
Quoted 3 lines

As an example, the script currently re-renders the whole man page for each section in a for loop, rather than printing each section from the same rendered page, which would likely be more performant.

I honestly can't read that script. My ability to read other people's bash(1) scripts is quite limited. :)

Very fair. There's just something about shell scripts that make them particularly difficult to parse imo.

Quoted 8 lines

About the interface, I think I like more the interface of mansect(1), which is

mansect section [file ...]

I think that's ideal. We don't need an argument like man(1)'s -s, because that would be more easily specified as

Quoted 6 lines
	mansectf LIBRARY printf.3;

The .3 disambiguates without needing a separate argument. However, I don't think we want to do librarian work here, and think we should entirely refrain from accepting manual page names like man(1). I think we should only accept file names.

I modelled the interface after man(1) because I assumed that would be more familiar. But I'd certainly be down for an interface like mansect(1)'s if that's preferable.

[...]

Quoted 9 lines

Then, about the implementation, it checks the existence of commands, which is unnecessary: the shell will complain for us if they don't exist.

	$ foo
	bash: foo: command not found

Keep it simple.

Quoted 7 lines

Then you export a few things:

+[[ $MAN_KEEP_FORMATTING ]] && export MAN_KEEP_FORMATTING=1 +[[ $MANWIDTH ]] && export MANWIDTH

That seems redundant. If it is already exported, the childs will inherit that.

These are both just things I sometimes add in my local scripts for easier debugging. Probably should have removed them for the patch.

Quoted 24 lines

And then about the main work, it can be done by calling mansect(1) in a pipeline.

With that in mind, I've written my own approach, which I've called mansectf.

	$ cat src/bin/mansectf;
	#!/bin/bash
	#
	# Copyright, the authors of the Linux man-pages project
	# SPDX-License-Identifier: GPL-3.0-or-later
	set -Eefuo pipefail;

	mansect "$@" \
	| man /dev/stdin;

Does this work for you? I look at it and wonder if it's worth a separate script, but then it might be useful for people who are less experienced with man(1). To be fair, few people know that man(1) can accept stdin, and even if they know, sometimes convenience wrappers improve readability: for example, printf(1) is unnecessary given that fprintf(3) exists, yet it's thoroughly used and I find it essential.

Quoted 5 lines
	printf("foo");
	fprintf(stdout, "foo");

So, I think such a thin wrapper can have its place, as it's the main use case of mansect(1).

This would be perfectly suitable, at least for my use cases. I also think mansectf is a *much* more apt name.

All in all, I also think the best option here is a thin wrapper over mansect(1). The main benefit being that it would simplify many use cases of mansect(1) without adding an unreasonable amount of complexity.

Also, if we were to add mansectf, I would probably opt for adding it to mansect(1)'s man page, rather than giving it its own page.

(P.S. While I'm nowhere near an expert on Unix shells, I honestly feel like I've learnt more about their use from these email exchanges than most other sources. So thanks for that. :) )

Signature · 5 lines
Take care,
	Seth McDonald.

On-list:  2336 E8D2 FEB1 5300 692C  62A9 5839 6AD8 9243 D369
Off-list: 82B9 620E 53D0 A1AE 2D69  6111 C267 B002 0A90 0289
#10 lore raw
Quoted 16 lines · Seth McDonald
Quoted 15 lines · Alejandro Colomar
Quoted 7 lines · Seth McDonald

G'day,

When parsing man pages, I've noticed I'm often only interested in a particular set of sections within the page (e.g. SYNOPSIS, HISTORY). And since skimming through the page to get to these sections can get monotonous, I wrote up a small bash script to automate the process.

Agree. I wrote mansect(1) for the same exact reason.

Quoted 3 lines

As far as I can tell, no program in src/bin/ can currently do this. The closest is mansect(1), but that outputs the source code rather than the rendered page.

Quoted 5 lines
Quoted 2 lines

You could use mansect(1) for that, and pipe it to man(1) (or groff(1)).

I honestly have no idea how that never crossed my mind. Seems so obvious in retrospect lol.

I have ideas for tackling this problem in groff as well, in a way that has the potential to be more powerful and selective.

https://savannah.gnu.org/bugs/?66401

One of the goals I have is to automatically generate link anchors for all TP paragraph tags in man(7), because these are so frequently used to set keywords, literals, and other parameters (like command-line option names) in lists. Roughly, these are same sorts of things you want to have index entries for, if your man pages were indexed. That's why perlpod sprays IX calls all over the man pages it generates.

But approximately no one, as far as I know, ever actually _generates_ an index from perlpod's IX spew. (Caveat: I'm not a close observer of the Perl community, so might have missed people doing this.)

But you don't necessarily _need_ an index if you have hyperlinks or a tag/anchor search capability.

One of the reasons I haven't given this project higher priority is that no one's been urging me to work on it. Another is that to implement it in a way that doesn't cause me to tear my hair out, I think I'm going to need a new formatter feature--a string iterator.

https://savannah.gnu.org/bugs/?62264

The last time I tried to tackle this, about 18 months ago, I ran into problems because I didn't understand the formatter's internals well enough yet. Many refactorings later,[1] I'm gaining confidence.

Another possibility is that automatic tag/anchor deduction can be a stretch goal. Dumping partial man pages on a per-section basis _should_ be easy. This is discussed in Savannah #66401, linked above.

None of the foregoing observations or plans intends to obviate the utility of mansect(1) for anyone. If it works satisfactorily, use it. But if people encounter limitations in it, and those seem solvable only by getting a deeper look into the formatter's brain (program state), then the time may become ripe to work on these tickets.

(Regardless, I want to attack #62264 because string processing in *roff is pure hell, and inflexible too, because diversions can be "handled" like strings if you tilt your head right, but only in limited ways.)

Regards,
Branden

[1] And a great deal of forced learning due to
https://savannah.gnu.org/bugs/?63074
and
https://cgit.git.savannah.gnu.org/cgit/groff.git/commit/?id=52f93e69dddb39bbfbbf7c43e355538e35b8edab
...which both taught me a lot.

You can (in groff 1.24.0) take an NMRI of much of GNU troff's brain in vivo without needing to use a debugger. I consider that a win.

#11 lore raw

Hi Branden,

Quoted 26 lines · G. Branden Robinson
Quoted 16 lines · Seth McDonald
Quoted 15 lines · Alejandro Colomar
Quoted 7 lines · Seth McDonald

G'day,

When parsing man pages, I've noticed I'm often only interested in a particular set of sections within the page (e.g. SYNOPSIS, HISTORY). And since skimming through the page to get to these sections can get monotonous, I wrote up a small bash script to automate the process.

Agree. I wrote mansect(1) for the same exact reason.

Quoted 3 lines

As far as I can tell, no program in src/bin/ can currently do this. The closest is mansect(1), but that outputs the source code rather than the rendered page.

Quoted 5 lines
Quoted 2 lines

You could use mansect(1) for that, and pipe it to man(1) (or groff(1)).

I honestly have no idea how that never crossed my mind. Seems so obvious in retrospect lol.

I have ideas for tackling this problem in groff as well, in a way that has the potential to be more powerful and selective.

Quoted 7 lines

https://savannah.gnu.org/bugs/?66401

One of the goals I have is to automatically generate link anchors for all TP paragraph tags in man(7), because these are so frequently used to set keywords, literals, and other parameters (like command-line option names) in lists. Roughly, these are same sorts of things you want to have index entries for, if your man pages were indexed.

That sounds useful. Thanks!

[...]

Quoted 5 lines

None of the foregoing observations or plans intends to obviate the utility of mansect(1) for anyone. If it works satisfactorily, use it. But if people encounter limitations in it, and those seem solvable only by getting a deeper look into the formatter's brain (program state), then the time may become ripe to work on these tickets.

So far, I'm pretty happy with mansect(1). In fact, I'd like to have it even if groff(1) added that feature. The rationale is that mansect(1) gives me the man(7) source, which I can then format with any formatter, so I can use it to debug an arbitrary formatter.

Quoted 3 lines

(Regardless, I want to attack #62264 because string processing in *roff is pure hell, and inflexible too, because diversions can be "handled" like strings if you tilt your head right, but only in limited ways.)

:-)

Quoted 2 lines

Regards,
Branden

Have a lovely day!
Alex

Quoted 9 lines

[1] And a great deal of forced learning due to
https://savannah.gnu.org/bugs/?63074
and
https://cgit.git.savannah.gnu.org/cgit/groff.git/commit/?id=52f93e69dddb39bbfbbf7c43e355538e35b8edab
...which both taught me a lot.

You can (in groff 1.24.0) take an NMRI of much of GNU troff's brain in vivo without needing to use a debugger. I consider that a win.

Signature · 1 line
<https://www.alejandro-colomar.es>
#12 lore raw
In reply to Seth McDonald

Hi Seth,

On 2026-01-28T04:44:53+0000, Seth McDonald wrote:

[...]

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

As far as I can tell, no program in src/bin/ can currently do this. The closest is mansect(1), but that outputs the source code rather than the rendered page.

You could use mansect(1) for that, and pipe it to man(1) (or groff(1)).

I honestly have no idea how that never crossed my mind. Seems so obvious in retrospect lol.

:-)

[...]

Quoted 9 lines
Quoted 6 lines
Quoted 3 lines

As an example, the script currently re-renders the whole man page for each section in a for loop, rather than printing each section from the same rendered page, which would likely be more performant.

I honestly can't read that script. My ability to read other people's bash(1) scripts is quite limited. :)

Very fair. There's just something about shell scripts that make them particularly difficult to parse imo.

I think tend to have more issues reading scripts that use shell features other than pipes. Scripts that do 'foo|bar|baz|asd|fgh' tend to be quite readable.

Quoted 10 lines
Quoted 10 lines

About the interface, I think I like more the interface of mansect(1), which is

mansect section [file ...]

I think that's ideal. We don't need an argument like man(1)'s -s, because that would be more easily specified as

	mansectf LIBRARY printf.3;
Quoted 8 lines
Quoted 4 lines

The .3 disambiguates without needing a separate argument. However, I don't think we want to do librarian work here, and think we should entirely refrain from accepting manual page names like man(1). I think we should only accept file names.

I modelled the interface after man(1) because I assumed that would be more familiar. But I'd certainly be down for an interface like mansect(1)'s if that's preferable.

A benefit of mansect(1)'s interface is that it can be used on a directory:

mansect HISTORY man2/

And it works on all files under that directory. I've found that to be quite useful.

[...]

Quoted 24 lines
Quoted 24 lines

And then about the main work, it can be done by calling mansect(1) in a pipeline.

With that in mind, I've written my own approach, which I've called mansectf.

	$ cat src/bin/mansectf;
	#!/bin/bash
	#
	# Copyright, the authors of the Linux man-pages project
	# SPDX-License-Identifier: GPL-3.0-or-later
	set -Eefuo pipefail;

	mansect "$@" \
	| man /dev/stdin;

Does this work for you? I look at it and wonder if it's worth a separate script, but then it might be useful for people who are less experienced with man(1). To be fair, few people know that man(1) can accept stdin, and even if they know, sometimes convenience wrappers improve readability: for example, printf(1) is unnecessary given that fprintf(3) exists, yet it's thoroughly used and I find it essential.

Quoted 8 lines
Quoted 5 lines
	printf("foo");
	fprintf(stdout, "foo");

So, I think such a thin wrapper can have its place, as it's the main use case of mansect(1).

This would be perfectly suitable, at least for my use cases. I also think mansectf is a *much* more apt name.

Nice!

Quoted 3 lines

All in all, I also think the best option here is a thin wrapper over mansect(1). The main benefit being that it would simplify many use cases of mansect(1) without adding an unreasonable amount of complexity.

Yup.

Quoted 2 lines

Also, if we were to add mansectf, I would probably opt for adding it to mansect(1)'s man page, rather than giving it its own page.

I think I'll write a separate manual page. I tend to dislike pages that document more than one API, with few exceptions. Exceptions are for example modf/modff/modfl, where the only difference is the type.

Quoted 3 lines

(P.S. While I'm nowhere near an expert on Unix shells, I honestly feel like I've learnt more about their use from these email exchanges than most other sources. So thanks for that. :) )

You're welcome! :-)

(FWIW, I also learnt to write good shell scripts in this mailing list;
especially, preparing scripts for applying global changes to the manual pages, and for finding inconsistencies in manual pages.)

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es>
#13 lore raw

PATCH v2 1/1 src/bin/mansectf, man/man1/mansectf.1: Add program and manual page

In reply to Seth McDonald
Cc Douglas McIlroy <[email protected]>
Cc "G. Branden Robinson" <[email protected]>
Cc наб <[email protected]>
---
 man/man1/mansectf.1 | 56 +++++++++++++++++++++++++++++++++++++++++++++
 src/bin/mansectf    |  9 ++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 man/man1/mansectf.1
 create mode 100755 src/bin/mansectf
man/man1/mansectf.1 new file +56 -0
new file mode 100644
index 000000000..09f0a9fba
@@ -0,0 +1,56 @@
+.\" Copyright, the authors of the Linux man-pages project
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH mansectf 1 (date) "Linux man-pages (unreleased)"
+.SH NAME
+mansectf
+\-
+format specific sections of manual pages
+.SH SYNOPSIS
+.SY mansectf
+.I section
+.RI [ file \~.\|.\|.]
+.YS
+.SH DESCRIPTION
+The
+.B mansectf
+command formats specific sections of manual-page files.
+.SH PARAMETERS
+See
+.BR mansect (1).
+.SH ENVIRONMENT
+See
+.BR man (1).
+.SH EXAMPLES
+.EX
+.RB $\~ "man \-w strtol strtoul | xargs mansectf \[aq]NAME|SEE ALSO\[aq] | cat";
+strtol(3)           Library Functions Manual          strtol(3)
+\&
+NAME
+     strtol, strtoll, strtoq - convert a string to a long inte‐
+     ger
+\&
+SEE ALSO
+     atof(3),  atoi(3),  atol(3), strtod(3), strtoimax(3), str‐
+     toul(3)
+\&
+Linux man‐pages 6.16       2025‐12‐01                 strtol(3)
+───────────────────────────────────────────────────────────────
+strtoul(3)          Library Functions Manual         strtoul(3)
+\&
+NAME
+     strtoul, strtoull, strtouq - convert a string  to  an  un‐
+     signed long integer
+\&
+SEE ALSO
+     a64l(3),  atof(3), atoi(3), atol(3), strtod(3), strtol(3),
+     strtoumax(3)
+\&
+Linux man‐pages 6.16       2025‐09‐21                strtoul(3)
+.EE
+.SH SEE ALSO
+.BR lexgrog (1),
+.BR groff (1),
+.BR pcre2grep (1),
+.BR mandb (8)
src/bin/mansectf new file +9 -0
new file mode 100755
index 000000000..a80f90b06
@@ -0,0 +1,9 @@
+#!/bin/bash
+#
+# Copyright, the authors of the Linux man-pages project
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -Eefuo pipefail;
+
+mansect "$@" \
+| man /dev/stdin;

Range-diff against v1:
-: --------- > 1: c5da437ce src/bin/mansectf, man/man1/mansectf.1: Add program and manual page

base-commit: 6754bd1a126ed1e9b7d9c2bc1d221681f5182bb3

Signature · 1 line
2.51.0
#14 lore raw

Re: [PATCH v2] src/bin/mansectf, man/man1/mansectf.1: Add program and manual page

Hi Alex,

On Wed, 28 Jan 2026 at 19:55:43 +0100, Alejandro Colomar wrote:
[...]

Quoted 3 lines

+.SH PARAMETERS
+See
+.BR mansect (1).

(If this isn't a problem then feel free to skip this)

AFAICT, 'PARAMETERS' isn't a heading used anywhere else. Running

~/Code/Linux/man-pages$ grep -Fnr 'PARAMETERS' man/

comes up empty for me (besides mansectf(1) of course). Perhaps instead the DESCRIPTION can explicitly state this. Something akin to "This command uses the same interface as mansect(1)."

[...]

src/bin/mansectf line 9

Quoted 9 lines
src/bin/mansectf new file +9 -0
+#!/bin/bash
+#
+# Copyright, the authors of the Linux man-pages project
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -Eefuo pipefail;
+
+mansect "$@" \
+| man /dev/stdin;

Thinking about it, one thing I did like from v1 that would be nice to keep is the specified sections being case-insensitive. Since the section headers should always be in uppercase, specifying them in lowercase when invoking mansectf(1) shouldn't introduce any ambiguity (i.e. "Does the user want the 'NAME' or 'Name' section?").

Signature · 5 lines
Take care,
	Seth McDonald.

On-list:  2336 E8D2 FEB1 5300 692C  62A9 5839 6AD8 9243 D369
Off-list: 82B9 620E 53D0 A1AE 2D69  6111 C267 B002 0A90 0289
#15 lore raw

Re: [PATCH v2] src/bin/mansectf, man/man1/mansectf.1: Add program and manual page

Hi Seth,

Quoted 19 lines · Seth McDonald

Hi Alex,

On Wed, 28 Jan 2026 at 19:55:43 +0100, Alejandro Colomar wrote:
[...]

Quoted 3 lines

+.SH PARAMETERS
+See
+.BR mansect (1).

(If this isn't a problem then feel free to skip this)

AFAICT, 'PARAMETERS' isn't a heading used anywhere else. Running

~/Code/Linux/man-pages$ grep -Fnr 'PARAMETERS' man/

comes up empty for me (besides mansectf(1) of course). Perhaps instead the DESCRIPTION can explicitly state this. Something akin to "This command uses the same interface as mansect(1)."

[...]

Quoted 13 lines

src/bin/mansectf line 9

Quoted 9 lines
src/bin/mansectf new file +9 -0
+#!/bin/bash
+#
+# Copyright, the authors of the Linux man-pages project
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -Eefuo pipefail;
+
+mansect "$@" \
+| man /dev/stdin;

Thinking about it, one thing I did like from v1 that would be nice to keep is the specified sections being case-insensitive. Since the section headers should always be in uppercase,

This is not necessarily true, and in fact I plan to change that eventually.

The reason I haven't done that yet is that I'm wondering what would be the best way to refer to sections in running text. Currently, we refer to them by name, and the fact that the name is upper-case makes it obvious.

Still, if you want case insensitivity, since the section is a PCRE2 pattern, you could use '(?i)' (see pcre2pattern(3)):

	$ man -w snprintf | MANWIDTH=64 xargs mansectf '(?i)name' | cat
	snprintf(3)         Library Functions Manual        snprintf(3)
	NAME
	     snprintf, vsnprintf - string print formatted

	Linux man‐pages 6.16‐43... 2025‐12‐07               snprintf(3)

Have a lovely day!
Alex

Quoted 10 lines

specifying them in
lowercase when invoking mansectf(1) shouldn't introduce any ambiguity (i.e. "Does the user want the 'NAME' or 'Name' section?").

Signature · 5 lines
Take care,
	Seth McDonald.

On-list:  2336 E8D2 FEB1 5300 692C  62A9 5839 6AD8 9243 D369
Off-list: 82B9 620E 53D0 A1AE 2D69  6111 C267 B002 0A90 0289
Signature · 1 line
<https://www.alejandro-colomar.es>
#16 lore raw

New PARAMETERS section in manual pages (was: [PATCH v2] src/bin/mansectf, man/man1/mansectf.1: Add program and manual page)

In reply to Seth McDonald

Hi Seth,

Quoted 10 lines · Seth McDonald

Hi Alex,

On Wed, 28 Jan 2026 at 19:55:43 +0100, Alejandro Colomar wrote:
[...]

Quoted 3 lines

+.SH PARAMETERS
+See
+.BR mansect (1).

(If this isn't a problem then feel free to skip this)

Quoted 7 lines

AFAICT, 'PARAMETERS' isn't a heading used anywhere else. Running

~/Code/Linux/man-pages$ grep -Fnr 'PARAMETERS' man/

comes up empty for me (besides mansectf(1) of course). Perhaps instead the DESCRIPTION can explicitly state this. Something akin to "This command uses the same interface as mansect(1)."

That heading is used in FreeBSD. There's also an ARGUMENTS section in other pages, but parameters is technically more correct.

	alx@devuan:~/src/bsd/freebsd/main$ find -type f | grep '\.[123]$' | xargs grep '^\.S[Hh] PARAMETERS' | wc -l
	49
	alx@devuan:~/src/bsd/freebsd/main$ find -type f | grep '\.[123]$' | xargs grep '^\.S[Hh] ARGUMENTS' | wc -l
	49

<https://man.freebsd.org/cgi/man.cgi?query=rdma_get_local_addr&apropos=0&sektion=0&manpath=FreeBSD+15.0-RELEASE+and+Ports&arch=default&format=html>
<https://man.freebsd.org/cgi/man.cgi?query=rpc_gss_set_svc_name&apropos=0&sektion=0&manpath=FreeBSD+15.0-RELEASE+and+Ports&arch=default&format=html>

I've been wanting to add this section for some time. It would make the pages more schematic, which I think improves readability.

What I wonder is wether it should go before or after the description.

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es>
#17 lore raw

Re: New PARAMETERS section in manual pages (was: [PATCH v2] src/bin/mansectf, man/man1/mansectf.1: Add program and manual page)

Hi Alex,

Quoted 2 lines · Alejandro Colomar

That heading is used in FreeBSD. There's also an ARGUMENTS section in other pages, but parameters is technically more correct.

Yes. And less ambiguous. Software developers get into many arguments. ;-)

Quoted 2 lines

I've been wanting to add this section for some time. It would make the pages more schematic, which I think improves readability.

I'd like to propose making it a _subsection_ instead. Subsections are under-used in man pages, and for no good reason I can see (apart from not being documented in the man(7) page of the Seventh Edition Unix manual that introduced the package to the world).

Quoted 1 line

What I wonder is wether it should go before or after the description.

By making it a subsection, it can go _within_ the description, as early or late as makes sense. In many cases, if you need a "Parameters" subsection at all, it should appear as soon as you need it--but no sooner.

I personally feel that at least one paragraph of description orienting the user to the overall purpose of the page is a superior approach to presenting parameteric details before the context within which those details apply has been presented to the reader.

That is also why, in section 1 and 8 (and, strictly, 6) man pages, I prefer to put an "Options" section well down the page, after a full "Description", because often, an option's description can only make sense once the capabilities of the command have been explored.[1]

I think it would also be fine to either (a) not ape FreeBSD in this respect or (b) restrict this "Parameters" subsection to section 2 man pages, as the Linux system call interface is indeed huge and complex. The Standard C library, by contrast, has remained fairly manageable, with bsearch() the fattest cardinal chirping in section 3.

...as far as I know. You are well placed to know better.

Regards,
Branden

[1] I acknowledge two schools of thought that disagree with me (usually stridently) and with each other on this point.

A. Ingo Schwarze thinks man pages shouldn't have "Options" sections
at all. I suppose this viewpoint descends from the Rob Pike "anti-cat-v" school of thought, which holds roughly that because a Unix command should do one thing and do it well (a principle articulated by McIlroy), then if you need a command to do a different thing, you introduce a new command. (While this principle risks exhausting the 676-element set of ideal Thompson Unix command names juxtaposing 2 lowercase letters, McIlroy reports that Thompson's own usage patterns--not to say needs-- were satisfied by only about 100 commands.[2])

B. A generally anonymous horde of man page users feel that the
"Options" section should start on the first screenful of text they see in their pager, no matter what the dimensions of their terminal window. (Presumably, pressing the space bar demands too much of the impatient hacker.) This requirement can be difficult to satisfy, and tends to promote the creation of a subsequent "Usage" section, which is simply a continuation of "Description" split asunder to accommodate the horde.

[2] "As the [Unix] system grew to encompass facilities beyond any individual's ken*, the task of organizing an ever-growing manual for printing became increasingly daunting. ... * Ken's ken was probably the last to saturate. At the time of v5 [1974], shell accounting once revealed that Thompson had used 102 distinctly named programs in the course of a week. Nobody else came close."

https://www.cs.dartmouth.edu/~doug/reader.pdf

#18 lore raw

Re: New PARAMETERS section in manual pages (was: [PATCH v2] src/bin/mansectf, man/man1/mansectf.1: Add program and manual page)

Hi Branden,

On 2026-01-29T14:24:57-0600, G. Branden Robinson wrote:

[...]

Quoted 7 lines
Quoted 2 lines

I've been wanting to add this section for some time. It would make the pages more schematic, which I think improves readability.

I'd like to propose making it a _subsection_ instead. Subsections are under-used in man pages, and for no good reason I can see (apart from not being documented in the man(7) page of the Seventh Edition Unix manual that introduced the package to the world).

I think I prefer a section. PARAMETERS would be closer to OPTIONS than DESCRIPTION.

Quoted 6 lines
Quoted 1 line

What I wonder is wether it should go before or after the description.

By making it a subsection, it can go _within_ the description, as early or late as makes sense. In many cases, if you need a "Parameters" subsection at all, it should appear as soon as you need it--but no sooner.

I think I'll leave it for below the DESCRIPTION. A problem with a subsection is that it would force using subsections below it, if we want to continue with the description.

We might change later.

Quoted 4 lines

I personally feel that at least one paragraph of description orienting the user to the overall purpose of the page is a superior approach to presenting parameteric details before the context within which those details apply has been presented to the reader.

Agree.

Quoted 4 lines

That is also why, in section 1 and 8 (and, strictly, 6) man pages, I prefer to put an "Options" section well down the page, after a full "Description", because often, an option's description can only make sense once the capabilities of the command have been explored.[1]

Agree.

Quoted 4 lines

I think it would also be fine to either

(a) not ape FreeBSD in this respect or

Sorry; non-native speaker here. What does ape mean as a verb?

Quoted 4 lines

(b) restrict this "Parameters" subsection to section 2 man pages, as the Linux system call interface is indeed huge and complex. The Standard C library, by contrast, has remained fairly manageable, with bsearch() the fattest cardinal chirping in section 3.

I agree to start with chapter 2. I can't promise not continuing later with chapter 3, but I agree it has significantly less priority.

Quoted 1 line

...as far as I know. You are well placed to know better.

:-)

Quoted 6 lines

Regards,
Branden

[1] I acknowledge two schools of thought that disagree with me (usually stridently) and with each other on this point.

Quoted 10 lines

A. Ingo Schwarze thinks man pages shouldn't have "Options" sections
at all. I suppose this viewpoint descends from the Rob Pike "anti-cat-v" school of thought, which holds roughly that because a Unix command should do one thing and do it well (a principle articulated by McIlroy), then if you need a command to do a different thing, you introduce a new command. (While this principle risks exhausting the 676-element set of ideal Thompson Unix command names juxtaposing 2 lowercase letters, McIlroy reports that Thompson's own usage patterns--not to say needs-- were satisfied by only about 100 commands.[2])

I tend to be on this side, but not too radically. Some options are necessary.

Quoted 5 lines

B. A generally anonymous horde of man page users feel that the
"Options" section should start on the first screenful of text they see in their pager, no matter what the dimensions of their terminal window. (Presumably, pressing the space bar demands too much of the impatient hacker.)

... or the slash.

Quoted 5 lines

This requirement can be
difficult to satisfy, and tends to promote the creation of a subsequent "Usage" section, which is simply a continuation of "Description" split asunder to accommodate the horde.

Quoted 8 lines

[2] "As the [Unix] system grew to encompass facilities beyond any individual's ken*, the task of organizing an ever-growing manual for printing became increasingly daunting. ... * Ken's ken was probably the last to saturate. At the time of v5 [1974], shell accounting once revealed that Thompson had used 102 distinctly named programs in the course of a week. Nobody else came close."

https://www.cs.dartmouth.edu/~doug/reader.pdf

:D

Have a lovely night!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es>
#19 lore raw

Re: New PARAMETERS section in manual pages (was: [PATCH v2] src/bin/mansectf, man/man1/mansectf.1: Add program and manual page)

Hi Alex,

Quoted 9 lines · Alejandro Colomar
Quoted 4 lines · G. Branden Robinson

By making it a subsection, it can go _within_ the description, as early or late as makes sense. In many cases, if you need a "Parameters" subsection at all, it should appear as soon as you need it--but no sooner.

I think I'll leave it for below the DESCRIPTION. A problem with a subsection is that it would force using subsections below it, if we want to continue with the description.

Not a bad thing, IMO, since I think subsections are under-used in the first place. :)

Quoted 1 line

We might change later.

Yeah, it's a judgment call.

Quoted 4 lines
Quoted 2 lines

I think it would also be fine to either
(a) not ape FreeBSD in this respect or

Sorry; non-native speaker here. What does ape mean as a verb?

Roughly, "to imitate".

Quoted 7 lines
Quoted 4 lines

(b) restrict this "Parameters" subsection to section 2 man pages, as the Linux system call interface is indeed huge and complex. The Standard C library, by contrast, has remained fairly manageable, with bsearch() the fattest cardinal chirping in section 3.

I agree to start with chapter 2. I can't promise not continuing later with chapter 3, but I agree it has significantly less priority.

Makes sense to start where the change can do the most good.

Regards,
Branden