Hi Alex, At 2025-05-02T12:56:51+0200, Alejandro Colomar wrote: > I'd like to understand why groff(1) formats differently a paragraph > depending on the previous ones. I sometimes experience different > placement of spaces for an unchanged paragraph. I use a script to > diff manual pages at different commits, which is useful to quickly see > the effects of a commit in a formatted page. That script sometimes > shows suprious space changes (produced by groff(1)) for parts of the > page that haven't been changed, and which one would expect should not > be formatted differently.
What you're observing is an artifact of the adjustment process that pads out filled text lines to a consistent width. It's a feature of *roff formatters going back essentially forever--as in, to the early 1970s. And it is indeed not a man page-specific phenomenon. groff_diff(7) briefly mentions it: When adjusting output lines to both margins, AT&T troff at first adjusts spaces starting from the right; GNU troff begins from the left. Both implementations adjust spaces from opposite ends on alternating output lines in this adjustment mode to prevent “rivers” in the text. Some typography people refer to this practice as achieving "uniform grayness". Imagine your eyes defocused so that the text of a printed page is a smear of gray--if every line were supplemented with space favoring either the left or right side, you would perceive the opposite side as being "blacker". As far as I understand the concept, not being a trained typographer, it's the same thing, or tautologically related. Rivers create anisotropies in your grayness. I have proposed the term "adjustment parity", a property that tells you whether an output line requiring adjustment gets adjusted from the left or the right. Roughly, if you change filled text in a *roff document that uses adjustment such that you add or delete an _even_ number of lines, the adjustment of subsequent lines won't change. If you add or delete an odd number of lines, it will. However, that's a *truly* rough statement because a change prior to groff 1.23.0 made GNU troff ignore, for purposes of adjustment parity, lines that don't get adjusted at all. I'll put some more background in a footnote.[1] When diffing changes to man pages for the groff and ncurses projects (and occasional others to which I contribute), I disable adjustment when rendering the pages before and after, using the `-d AD=l` option. groff_man(7): Options The following groff options set registers (with -r) and strings (with -d) recognized and used by the man macro package. To ensure rendering consistent with output device capabilities and reader preferences, man pages should never manipulate them. -dAD=adjustment‐mode Set line adjustment to adjustment‐mode, which is typically “b” for adjustment to both margins (the default), or “l” for left alignment (ragged right margin). Any valid argument to groff’s “.ad” request may be used. See groff(7) for less‐common choices. As you can see, I turn off adjustment when pasting man page contents into emails as well.[2] For example, the script I use to diff groff man pages before pushing a set of commits has this stuff in it. BFLAG= #BFLAG=-b ... : ${AD:=l} ... ARGS="$BFLAG -ww -dAD=$AD -rCHECKSTYLE=3 -rU1 -Tutf8 -e -t -mandoc" ... for P in *.[157] do if [ "$P" = groff_mmse.7 ] then LOCALE=-msv else LOCALE= fi echo $0: $P >&2 echo "groff $ARGS $LOCALE $P" > "$P.cR.txt" groff $ARGS $LOCALE "$P" >> "$P.cR.txt" ... done I then diff(1) the ".cR.txt" file I saved from my last push (corresponding to "origin/master") to the tip of the trunk. I will point out something about your diff, though. > @@ -118,11 +130,11 @@ .SH DESCRIPTION > this operation yields an > .B EINVAL > error. > -.RE > .IP > -Since Linux 6.7, using this subcode requires the > +Since Linux 6.7, using this selection mode requires the > .B CAP_SYS_ADMIN > capability. > +.RE > .TP > .BR subcode = TIOCL_PASTESEL > Paste selection. This change involving movement of the `RE` macro call can potentially change the output as well. > There are several paragraphs which shouldn't report changes: every > paragraph that doesn't start with "Since Linux 6.7," should be > unchanged. ...unless the moved `RE` call creates a surprise. > Is this a bug? Is it a feature? It's a feature. Some people do hate adjustment of nroff output, though, which is why I added a feature to groff man(7) to support disabling it. The history of this practice is inconsistent. Seventh Edition Unix (1979) disabled adjustment of man pages when rendering in nroff mode,[3] and BSD retained that disablement until death. SunOS commented it as early as SunOS 2.0 (1985), thus restoring adjustment in nroff mode, and retained that all the way through Solaris 10 (2005). When James Clark wrote groff starting in about 1989, his man(7) implementation closely emulated SunOS. With the Solaris 11 release in 2010, Oracle discarded its AT&T-descended troff in favor of the then-current groff release. They're still on groff 1.22.2 (2013) today, and so they've been adjusting their man pages in nroff mode for at least 40 years, as has groff for about 35). I don't know what other System V Unices did. Some people have lobbied me to turn the default for adjustment off in nroff mode for man pages, but I've resisted, in part for consistency with groff's own entire history and the expectations of the once large (but now aging) population of Sun Unix users, but also because I feel that groff's defaults in nroff mode should be as similar to troff mode as practical, to minimize surprises when switching among output devices. As of groff 1.23.0 (2023) the default adjustment setting in groff man(7) (and mdoc(7)) is completely under user control. Regards, Branden [1] commit 69efbe0a69a8e7de8904d78e3de8c7e8a58a8b92 Author: G. Branden Robinson <g.branden.robin...@gmail.com> Date: Sat Sep 4 23:20:54 2021 +1000 [troff]: Don't adjust nonadjustable lines. This means that the direction from which an output line in adjustment mode "b" (or its "n" synonym) is filled with supplemental space is not changed if that output line does not require adjustment. This will result in whitespace changes to documents using that adjustment mode, and these changes will be plainly visible on low-resolution output devices like terminals. To illustrate, in the following "A" means an output line requiring adjustment; "F" a line that is "full" and does not; and "L" and "R" indicate distribution of adjustment spaces from the left and right, respectively. groff 1.22.4 groff 1.23.0 ------------ ------------ A L A L A R A R F L F R A R A L * src/roff/troff/env.cpp (distribute_space): Return early if either the amount of desired space to be distributed or the count of space nodes in the output line to distribute it among is zero. * tmac/tests/an_TH-repairs-ad-damage.sh: Update test to expect space to be distributed differently. Fixes <https://savannah.gnu.org/bugs/?61089> and <https://savannah.gnu.org/bugs/index.php?60673>. [2] $ type mailman mailman is a function mailman () { local cmd=; case "$1" in -*) opts="$opts $1"; shift ;; esac; set -- $(man -w "$@"); cmd=$(zcat --force "$@" | grog -Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l $opts); zcat --force "$@" | $cmd | less } [3] https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/lib/tmac/tmac.an Also see variously: https://minnie.tuhs.org/cgi-bin/utree.pl?file=32V/usr/lib/tmac/tmac.an https://minnie.tuhs.org/cgi-bin/utree.pl?file=3BSD/usr/lib/tmac/tmac.an.new https://minnie.tuhs.org/cgi-bin/utree.pl?file=4BSD/usr/lib/tmac/tmac.an.new https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD/usr/lib/tmac/tmac.an.new https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Tahoe/usr/lib/tmac/tmac.an.new https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/share/tmac/tmac.groff_an
signature.asc
Description: PGP signature