linux-man.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Paragraphs formatted differently depending on previous ones
@ 2025-05-02 10:56 Alejandro Colomar
  2025-05-02 12:01 ` G. Branden Robinson
  0 siblings, 1 reply; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-02 10:56 UTC (permalink / raw)
  To: branden, groff; +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 6236 bytes --]

Hi Branden,

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.

Below is an example in what is now the latest commit in the Linux
man-pages repository.  The commit I'll be using for this example is
man-pages.git 5889aa978ddc (2025-05-02; "man/man2const/TIOCLINUX.2const:
Document CAP_SYS_ADMIN requirement for TIOCL_SETSEL modes").

	$ git log -1 -p --oneline 5889aa978ddc
	5889aa978 (HEAD -> master, korg/master, korg/HEAD, alx/main, alx/contrib, alx/HEAD, main, contrib) man/man2const/TIOCLINUX.2const: Document CAP_SYS_ADMIN requirement for TIOCL_SET>
	diff --git a/man/man2const/TIOCLINUX.2const b/man/man2const/TIOCLINUX.2const
	index 61f1c596d..b98a0202b 100644
	--- a/man/man2const/TIOCLINUX.2const
	+++ b/man/man2const/TIOCLINUX.2const
	@@ -72,18 +72,30 @@ .SH DESCRIPTION
	 Select character-by-character.
	 The indicated screen characters are highlighted
	 and saved in a kernel buffer.
	+.IP
	+Since Linux 6.7, using this selection mode requires the
	+.B CAP_SYS_ADMIN
	+capability.
	 .TP
	 .B TIOCL_SELWORD
	 Select word-by-word,
	 expanding the selection outwards to align with word boundaries.
	 The indicated screen characters are highlighted
	 and saved in a kernel buffer.
	+.IP
	+Since Linux 6.7, using this selection mode requires the
	+.B CAP_SYS_ADMIN
	+capability.
	 .TP
	 .B TIOCL_SELLINE
	 Select line-by-line,
	 expanding the selection outwards to select full lines.
	 The indicated screen characters are highlighted
	 and saved in a kernel buffer.
	+.IP
	+Since Linux 6.7, using this selection mode requires the
	+.B CAP_SYS_ADMIN
	+capability.
	 .TP
	 .B TIOCL_SELPOINTER
	 Show the pointer at position
	@@ -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.

Now, let's use the diffman-git(1) script.  You can get it by installing
it from source from the man-pages repo: `make && sudo make install`.
You can also run it directly from the repo: `./src/bin/diffman-git`.
Documentation is in the repo as a manual page in man1, of course.

$ diffman-git 5889aa978ddc
--- 5889aa978ddc^:man/man2const/TIOCLINUX.2const
+++ 5889aa978ddc:man/man2const/TIOCLINUX.2const
@@ -38,36 +38,46 @@
                    Select character‐by‐character.  The indicated screen characters  are
                    highlighted and saved in a kernel buffer.
 
+                   Since  Linux 6.7, using this selection mode requires the CAP_SYS_AD‐
+                   MIN capability.
+
             TIOCL_SELWORD
-                   Select  word‐by‐word, expanding the selection outwards to align with
-                   word boundaries.  The indicated screen  characters  are  highlighted
+                   Select word‐by‐word, expanding the selection outwards to align  with
+                   word  boundaries.   The  indicated screen characters are highlighted
                    and saved in a kernel buffer.
 
+                   Since Linux 6.7, using this selection mode requires the  CAP_SYS_AD‐
+                   MIN capability.
+
             TIOCL_SELLINE
                    Select line‐by‐line, expanding the selection outwards to select full
                    lines.  The indicated screen characters are highlighted and saved in
                    a kernel buffer.
 
+                   Since  Linux 6.7, using this selection mode requires the CAP_SYS_AD‐
+                   MIN capability.
+
             TIOCL_SELPOINTER
-                   Show  the  pointer  at  position  (xs, ys) or (xe, ye), whichever is
+                   Show the pointer at position (xs, ys)  or  (xe,  ye),  whichever  is
                    later in text flow order.
 
             TIOCL_SELCLEAR
-                   Remove the current selection highlight, if  any,  from  the  console
+                   Remove  the  current  selection  highlight, if any, from the console
                    holding the selection.
 
                    This does not affect the stored selected text.
 
             TIOCL_SELMOUSEREPORT
-                   Make  the terminal report (xs, ys) as the current mouse location us‐
-                   ing the xterm(1) mouse  tracking  protocol  (see  console_codes(4)).
-                   The  lower 4 bits of sel_mode (TIOCL_SELBUTTONMASK) indicate the de‐
+                   Make the terminal report (xs, ys) as the current mouse location  us‐
+                   ing  the  xterm(1)  mouse  tracking protocol (see console_codes(4)).
+                   The lower 4 bits of sel_mode (TIOCL_SELBUTTONMASK) indicate the  de‐
                    sired button press and modifier key information for the mouse event.
 
-                   If mouse reporting is not enabled for the terminal,  this  operation
+                   If  mouse  reporting is not enabled for the terminal, this operation
                    yields an EINVAL error.
 
-            Since Linux 6.7, using this subcode requires the CAP_SYS_ADMIN capability.
+                   Since Linux 6.7, using this selection mode requires the  CAP_SYS_AD‐
+                   MIN capability.
 
      subcode=TIOCL_PASTESEL
             Paste selection.  The characters in the selection buffer are written to fd.


There are several paragraphs which shouldn't report changes: every
paragraph that doesn't start with "Since Linux 6.7," should be
unchanged.

Is this a bug?  Is it a feature?


Have a lovely day!
Alex

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 10:56 Paragraphs formatted differently depending on previous ones Alejandro Colomar
@ 2025-05-02 12:01 ` G. Branden Robinson
  2025-05-02 12:26   ` grof --run Alejandro Colomar
                     ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-02 12:01 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 8578 bytes --]

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.robinson@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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* grof --run
  2025-05-02 12:01 ` G. Branden Robinson
@ 2025-05-02 12:26   ` Alejandro Colomar
  2025-05-02 14:19     ` G. Branden Robinson
  2025-05-02 12:42   ` Paragraphs formatted differently depending on previous ones Alejandro Colomar
  2025-05-02 13:06   ` Martin Lemaire
  2 siblings, 1 reply; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-02 12:26 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1910 bytes --]

Hi Branden,

On Fri, May 02, 2025 at 07:01:39AM -0500, G. Branden Robinson wrote:
> [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
> }

I was trying to simplify your mailman() function to the following pipe
(after parsing the options):

	man -w "$@" \
	| xargs zcat --force \
	| grog --run \
		-Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l \
		$opts \
		2>/dev/null \
	| less;

And I found out that grog(1) seems to be not accepting a documented
option: --run. [1]  Am I doing something incorrectly?  I never used
grog(1) before, so it might very well be.


Cheers,
Alex

[1]:

$ MANWIDTH=72 man grog | head -n17
grog(1)                 General Commands Manual                 grog(1)

Name
     grog - “groff guess”——infer the groff command a document requires

Synopsis
     grog [--run] [--ligatures] [groff‐option ...] [--] [file ...]
     grog -h grog --help
          grog -v grog --version

Description
     grog reads its input and guesses which groff(1) options are needed
     to render it.  If no operands are given, or if file is “-”, grog
     reads the standard input stream.  The corresponding groff command
     is normally written to the standard output stream.  With the op‐
     tion --run, the inferred command is written to the standard error
     stream and then executed.
alx@devuan:~$ grog --run
grog: error: unrecognized grog option '--run'; ignored
usage: grog [groff-option ...] [--] [file ...]
usage: grog {-v | --version}
usage: grog {-h | --help}


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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 12:01 ` G. Branden Robinson
  2025-05-02 12:26   ` grof --run Alejandro Colomar
@ 2025-05-02 12:42   ` Alejandro Colomar
  2025-05-02 14:29     ` G. Branden Robinson
  2025-05-02 13:06   ` Martin Lemaire
  2 siblings, 1 reply; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-02 12:42 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 6196 bytes --]

Hi Branden,

On Fri, May 02, 2025 at 07:01:39AM -0500, G. Branden Robinson wrote:
> 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]

Hmmmm, it's very interesting.  I was guessing that something like that
might be going on.  So, now I've looked more closely at the diff, and it
seems that the blanks favour alternating left and right to compensate.
That seems quite reasonable, and indeed a feature.

> 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.

By default, I prefer keeping adjustment.  Often, I want to see changes
in adjustment too as part fo the diff.  Maybe I should add an option to
disable adjustment optionally, which could be useful in those cases
where the diff is a bit hard to understand.

> 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

What's -msv?

> 
>     echo $0: $P >&2
>     echo "groff $ARGS $LOCALE $P" > "$P.cR.txt"
>     groff $ARGS $LOCALE "$P" >> "$P.cR.txt"
> ...
> done

Would you mind sharing the entire script?  I might get ideas for
improving diffman-git(1).  (And maybe you can drop your script if
diffman-git(1) would be good-enough for you.)

> 
> I then diff(1) the ".cR.txt" file I saved from my last push
> (corresponding to "origin/master") to the tip of the trunk.

That would be `diffman-git origin/master master`.

> 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.

Makes sense.

> > 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.

The RE movement is intended to indent the "Since Linux 6.7," para.

> > 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.

Hmmm, I like it.  It's good to know that I can disable it for diffing in
some cases, but even for diffing I want it enabled by default.  :)


Cheers,
Alex

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 12:01 ` G. Branden Robinson
  2025-05-02 12:26   ` grof --run Alejandro Colomar
  2025-05-02 12:42   ` Paragraphs formatted differently depending on previous ones Alejandro Colomar
@ 2025-05-02 13:06   ` Martin Lemaire
  2025-05-02 14:51     ` G. Branden Robinson
  2025-05-02 17:42     ` Dave Kemper
  2 siblings, 2 replies; 23+ messages in thread
From: Martin Lemaire @ 2025-05-02 13:06 UTC (permalink / raw)
  To: groff, linux-man; +Cc: Alejandro Colomar

Thank you Branden for those historical insights. 
Off-topic to Alejandro's initial question but related to the subject of
justifying text set in monospace, do we owe this typographic gesture to
the early *roff formaters or was it already a thing in previous
publication tool, either software or hardware ?
Are you aware of theory or paper on the subject ?

Martin


Le Fri, May 02, 2025 at 07:01:39AM -0500, G. Branden Robinson a écrit :
> 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.robinson@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



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-02 12:26   ` grof --run Alejandro Colomar
@ 2025-05-02 14:19     ` G. Branden Robinson
  2025-05-02 14:59       ` Alejandro Colomar
  0 siblings, 1 reply; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-02 14:19 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1709 bytes --]

Hi Alex,

At 2025-05-02T14:26:23+0200, Alejandro Colomar wrote:
> On Fri, May 02, 2025 at 07:01:39AM -0500, G. Branden Robinson wrote:
> > [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
> > }
> 
> I was trying to simplify your mailman() function to the following pipe
> (after parsing the options):
> 
> 	man -w "$@" \
> 	| xargs zcat --force \
> 	| grog --run \
> 		-Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l \
> 		$opts \
> 		2>/dev/null \
> 	| less;
> 
> And I found out that grog(1) seems to be not accepting a documented
> option: --run. [1]  Am I doing something incorrectly?  I never used
> grog(1) before, so it might very well be.

Your grog executable may be out of sync with the man page you're
reading.

Compare `type grog` with `man -w grog`.

> alx@devuan:~$ grog --run
> grog: error: unrecognized grog option '--run'; ignored

grog's `--run` option has been removed in the forthcoming groff 1.24.0
release, so if you're running groff Git's master branch, that could
explain it.

NEWS:

*  grog(1) no longer supports the `--ligatures` and `--run` options.
   Simulate the former (which was specific to the "pdf" output device)
   with the option sequence "-P -U -P y", and the latter by using the
   command substitution feature of your shell; see section "Examples" of
   groff(1).

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 12:42   ` Paragraphs formatted differently depending on previous ones Alejandro Colomar
@ 2025-05-02 14:29     ` G. Branden Robinson
  2025-05-02 15:30       ` Alejandro Colomar
  0 siblings, 1 reply; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-02 14:29 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: groff, linux-man


[-- Attachment #1.1: Type: text/plain, Size: 3843 bytes --]

Hi Alex,

At 2025-05-02T14:42:12+0200, Alejandro Colomar wrote:
> By default, I prefer keeping adjustment.  Often, I want to see changes
> in adjustment too as part fo the diff.  Maybe I should add an option to
> disable adjustment optionally, which could be useful in those cases
> where the diff is a bit hard to understand.

For myself, I found that editorial changes to recast wording or
otherwise add and remove material led to cascading reports of
differences _only_ to spaces in adjusted lines, which usually aren't of
interest to me.

> > for P in *.[157]
> > do
> >     if [ "$P" = groff_mmse.7 ]
> >     then
> >       LOCALE=-msv
> >     else
> >       LOCALE=
> >     fi
> 
> What's -msv?

groff_tmac(5):

   Localization packages
     For Western languages, an auxiliary package for localization sets
     the hyphenation mode and loads hyphenation patterns and exceptions.
     Localization files can also adjust the date format and provide
     translations of strings used by some of the full‐service macro
     packages; alter the input encoding (see the next section); and
     change the amount of additional inter‐sentence space.  For Eastern
     languages, the localization file defines character classes and sets
     flags on them.  By default, troffrc loads the localization file for
     English.
...
     sv     Swedish; localizes man, me, mm, mom, and ms.  Sets the input
            encoding to Latin‐1 by loading latin1.tmac.  Some of the
            localization of the mm package is handled separately; see
            groff_mmse(7).

> >     echo $0: $P >&2
> >     echo "groff $ARGS $LOCALE $P" > "$P.cR.txt"
> >     groff $ARGS $LOCALE "$P" >> "$P.cR.txt"
> > ...
> > done
> 
> Would you mind sharing the entire script?  I might get ideas for
> improving diffman-git(1).

Sure; it's crude and dumb (like its author?)--I don't generally spend a
lot of software engineering effort on stuff I produce only for my own
consumption.  I've attached it.  The script name is revealing of some of
my music listening habits.

> (And maybe you can drop your script if
> diffman-git(1) would be good-enough for you.)

If it stops working for the limited purpose I require it, I may look
into alternatives.  :)

> The RE movement is intended to indent the "Since Linux 6.7," para.

I'd need to look at more context, and haven't, but `IP` already does
that.  The interaction of `RS` and `RE` with `IP`, and the erstwhile
lack of documentation thereof, is in fact the proximate cause of my
involvement with groff development.

groff_man_style(7):

Notes
     Some tips on composing and troubleshooting your man pages follow.
...
     • RS doesn’t indent relative to my indented paragraph.

       The RS macro determines the inset amount, the position at which
       an ordinary paragraph (P and its synonyms) is set; the value of
       the IN register determines its default amount.  This register
       also determines the default indentation used by IP, TP, and the
       deprecated HP.  To create an inset relative to an indented
       paragraph, call RS repeatedly until an acceptable indentation is
       achieved, or give RS an indentation argument that is at least as
       much as the paragraph’s indentation amount relative to an
       adjacent ordinary (P) paragraph.

       Another approach to tagged paragraphs places an RS call
       immediately after the tag; this also forces a break regardless of
       the tag’s width, which some authors prefer.  Follow‐up paragraphs
       under the tag can then be set with P instead of IP.  Remember to
       use RE to end the indented region before starting the next tagged
       paragraph (at the appropriate nesting level).

Regards,
Branden

[-- Attachment #1.2: harry-manback --]
[-- Type: text/plain, Size: 3881 bytes --]

#!/bin/bash

set -e

if [ $# -ne 1 ]
then
    echo "need a directory argument (e.g., \"old\", \"new\")" >&2
    exit 1
fi

if ! [ -x ./build/test-groff ]
then
    echo "./build/test-groff does not exist or is not executable" >&2
    exit 2
fi

groff () {
    ../build/test-groff "$@"
}

BFLAG=
#BFLAG=-b
DIR=$1

MANS=(
./src/utils/lkbib/lkbib.1.man
./src/utils/tfmtodit/tfmtodit.1.man
./src/utils/hpftodit/hpftodit.1.man
./src/utils/pfbtops/pfbtops.1.man
./src/utils/afmtodit/afmtodit.1.man
./src/utils/lookbib/lookbib.1.man
./src/utils/addftinfo/addftinfo.1.man
./src/utils/xtotroff/xtotroff.1.man
./src/utils/indxbib/indxbib.1.man
./src/roff/nroff/nroff.1.man
./src/roff/troff/troff.1.man
./src/roff/groff/groff.1.man
./src/utils/grog/grog.1.man
./src/devices/grodvi/grodvi.1.man
./src/devices/grolbp/grolbp.1.man
./src/devices/grops/grops.1.man
./src/devices/grohtml/grohtml.1.man
./src/devices/grolj4/grolj4.1.man
./src/devices/grotty/grotty.1.man
./src/devices/gropdf/gropdf.1.man
./src/devices/gropdf/pdfmom.1.man
./src/devices/xditview/gxditview.1.man
./src/preproc/preconv/preconv.1.man
./src/preproc/tbl/tbl.1.man
./src/preproc/soelim/soelim.1.man
./src/preproc/eqn/eqn.1.man
./src/preproc/eqn/neqn.1.man
./src/preproc/pic/pic.1.man
./src/preproc/refer/refer.1.man
./src/preproc/grn/grn.1.man
./contrib/pic2graph/pic2graph.1.man
./contrib/hdtbl/groff_hdtbl.7.man
./contrib/mm/groff_mm.7.man
./contrib/mm/mmroff.1.man
./contrib/grap2graph/grap2graph.1.man
./contrib/rfc1345/groff_rfc1345.7.man
./contrib/eqn2graph/eqn2graph.1.man
./contrib/gpinyin/gpinyin.1.man
./contrib/mom/groff_mom.7.man
./contrib/gdiffmk/gdiffmk.1.man
./contrib/glilypond/glilypond.1.man
./contrib/chem/chem.1.man
./contrib/gperl/gperl.1.man
./man/groff_tmac.5.man
./man/groff_out.5.man
./man/groff_diff.7.man
./man/groff_char.7.man
./man/groff.7.man
./man/roff.7.man
./man/groff_font.5.man
./tmac/groff_trace.7.man
./tmac/groff_me.7.man
./tmac/groff_ms.7.man
./tmac/groff_man.7.man
./tmac/groff_man_style.7.man
./tmac/groff_mdoc.7.man
./tmac/groff_www.7.man
)

MANS_SV=(
./contrib/mm/groff_mmse.7.man
)

mkdir "$DIR"
pushd "$DIR" >/dev/null

# the change logs, so we know approximately where we are
cp ../ChangeLog .

for d in chem gdiffmk glilypond gperl gpinyin hdtbl mm mom rfc1345 sboxes
do
	cp ../contrib/$d/ChangeLog ./ChangeLog.$d
done

# our Texinfo manual
cp ../build/doc/groff.txt .

# our Texinfo manual via HTML
cp ../build/doc/groff.html .
lynx -dump groff.html > groff.html.txt

# our ms manuals
groff $BFLAG -ww -Tutf8 -ept -ms ../doc/ms.ms > ms.txt

# our me manuals
#groff $BFLAG -ww -Tutf8 -me ../doc/meintro.me > meintro.txt
#groff $BFLAG -ww -Tutf8 -kt -me -mfr ../doc/meintro_fr.me > meintro_fr.txt
#groff $BFLAG -ww -Tutf8 -me ../doc/meref.me > meref.txt
me_pre=../ATTIC/my.me
groff $BFLAG -ww -Tutf8 -me $me_pre ../build/doc/meintro.me > meintro.txt
groff $BFLAG -ww -Tutf8 -kt -me -mfr $me_pre ../build/doc/meintro_fr.me \
    > meintro_fr.txt
groff $BFLAG -ww -Tutf8 -me $me_pre ../build/doc/meref.me > meref.txt

for F in ${MANS[*]} ${MANS_SV[*]}
do
    G=../build/${F%.man}
    if [ -f "$G" ]
    then
        cp "$G" .
    else
        echo "warning: \"$G\" missing" >&2
    fi
done

: ${AD:=l}

ARGS="$BFLAG -ww -dAD=$AD -rCHECKSTYLE=3 -rU1 -Tutf8 -e -t -mandoc"
NOCR=-rcR=0
LOCALE=
ARGS_HTML="$BFLAG -ww -rCHECKSTYLE=3 -Thtml -e -t -mandoc -P-C -P-G"

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"
    echo "groff $ARGS $LOCALE $NOCR $P" > "$P.no-cR.txt"
    groff $ARGS $LOCALE $NOCR "$P" >> "$P.no-cR.txt"
    echo "<!-- groff $ARGS_HTML $LOCALE -P-I$P $P -->" > "$P.html"
    groff $ARGS_HTML $LOCALE -P-I$P $P >> "$P.html"
    rm "$P"
done

popd >/dev/null

# vim:set ai et sw=4 ts=4 tw=80:

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 13:06   ` Martin Lemaire
@ 2025-05-02 14:51     ` G. Branden Robinson
  2025-05-02 15:34       ` Alejandro Colomar
  2025-05-02 17:42     ` Dave Kemper
  1 sibling, 1 reply; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-02 14:51 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 3792 bytes --]

At 2025-05-02T15:06:46+0200, Martin Lemaire wrote:
> Thank you Branden for those historical insights. 
> Off-topic to Alejandro's initial question but related to the subject of
> justifying text set in monospace, do we owe this typographic gesture to
> the early *roff formaters or was it already a thing in previous
> publication tool, either software or hardware ?

It dates back at least to "old" roff, which is one of the first Unix
programs ever to exist.  It is older than the C language.

roff(7):

History
     Computer‐driven document formatting dates back to the 1960s.  The
     roff system is intimately connected with Unix, but its origins lie
     with the earlier operating systems CTSS, GECOS, and Multics.
...
   Unix and roff
     McIlroy’s roff was one of the first Unix programs.  In Ritchie’s
     term, it was “transliterated” from BCPL to DEC PDP‐7 assembly
     language for the fledgling Unix operating system.  Automatic
     hyphenation was managed with .hc and .hy requests, line spacing
     control was generalized with the .ls request, and what later roffs
     would call diversions were available via “footnote” requests.  This
     roff indirectly funded operating systems research at Murray Hill;
     AT&T prepared patent applications to the U.S. government with it.
     This arrangement enabled the group to acquire a PDP‐11; roff
     promptly proved equal to the task of formatting the manual for what
     would become known as “First Edition Unix”, dated November 1971.

And, sure enough, it performed adjustment.  We can observe its behavior
in Seventh Edition Unix (1979), which while much later chronologically,
also documents roff(1) as "utterly frozen".  Joe Ossanna's nroff(1),
"new roff", appeared in Second Edition Unix (1972) and immediately
sucked up all the oxygen available for document formatting work at the
Bell Labs CSRC.

---snip---
PDP-11 simulator V3.8-1
Disabling XQ
@boot
New Boot, known devices are hp ht rk rl rp tm vt
: rl(0,0)rl2unix
mem = 177856
# Restricted rights: Use, duplication, or disclosure
is subject to restrictions stated in your contract with
Western Electric Company, Inc.
Thu Sep 22 23:33:03 EDT 1988

login: dmr
$ cat lemaire
Off-topic to Alejandro's initial question but related to the subject of
justifying text set in monospace, do we owe this typographic gesture to
the early *roff formaters or was it already a thing in previous
publication tool, either software or hardware?
$ roff lemaire | sed '/^$/d'
Off-topic to Alejandro's initial question but related to the sub-
ject of justifying text set in monospace, do we owe this typogra-
phic gesture to the early *roff formaters or  was  it  already  a
thing in previous publication tool, either software or hardware?
---end snip---

> Are you aware of theory or paper on the subject ?

The practice of adjusting lines of text to be all the same length when
typesetting is an old one.  It appears to be the practice in at least
some late-medieval illuminated manuscripts, and images of the pages of
the Gutenberg Bible that I can find online suggest to me that the
practice goes back to the dawn of the printing press.

Since monospaced typefaces are a straightforward application of movable
type, the concept of "adjusting" printed lines thereof could not have
been novel.  It was simply too tedious a practice to expect of
typewriter operators who composed text on the fly while drafting.
Computers, however, are perfect for automation of tedium.

But I'm far from a subject matter expert.  And a bit too young to opine
authoritatively on life at the CSRC.  Fortunately, some groff list
subscribers have first-hand knowledge.  :)

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-02 14:19     ` G. Branden Robinson
@ 2025-05-02 14:59       ` Alejandro Colomar
  2025-05-03  0:49         ` G. Branden Robinson
  0 siblings, 1 reply; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-02 14:59 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 2260 bytes --]

Hi Branden,

On Fri, May 02, 2025 at 09:19:48AM -0500, G. Branden Robinson wrote:
> Hi Alex,
> 
> At 2025-05-02T14:26:23+0200, Alejandro Colomar wrote:
> > On Fri, May 02, 2025 at 07:01:39AM -0500, G. Branden Robinson wrote:
> > > [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
> > > }
> > 
> > I was trying to simplify your mailman() function to the following pipe
> > (after parsing the options):
> > 
> > 	man -w "$@" \
> > 	| xargs zcat --force \
> > 	| grog --run \
> > 		-Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l \
> > 		$opts \
> > 		2>/dev/null \
> > 	| less;
> > 
> > And I found out that grog(1) seems to be not accepting a documented
> > option: --run. [1]  Am I doing something incorrectly?  I never used
> > grog(1) before, so it might very well be.
> 
> Your grog executable may be out of sync with the man page you're
> reading.
> 
> Compare `type grog` with `man -w grog`.

Hmmmm.

alx@devuan:~$ which grog
/usr/local/bin/grog
alx@devuan:~$ grog --version
GNU grog (groff) 1.23.0.2695-49927
alx@devuan:~$ man grog | tail -n1
groff 1.23.0                    26 December 2024                        grog(1)

> > alx@devuan:~$ grog --run
> > grog: error: unrecognized grog option '--run'; ignored
> 
> grog's `--run` option has been removed in the forthcoming groff 1.24.0
> release, so if you're running groff Git's master branch, that could
> explain it.
> 
> NEWS:
> 
> *  grog(1) no longer supports the `--ligatures` and `--run` options.
>    Simulate the former (which was specific to the "pdf" output device)
>    with the option sequence "-P -U -P y", and the latter by using the
>    command substitution feature of your shell; see section "Examples" of
>    groff(1).

Okay, this complicates things a bit.  :)


Cheers,
Alex

> 
> Regards,
> Branden



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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 14:29     ` G. Branden Robinson
@ 2025-05-02 15:30       ` Alejandro Colomar
  0 siblings, 0 replies; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-02 15:30 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 13581 bytes --]

Hi Branden,

On Fri, May 02, 2025 at 09:29:07AM -0500, G. Branden Robinson wrote:
> At 2025-05-02T14:42:12+0200, Alejandro Colomar wrote:
> > By default, I prefer keeping adjustment.  Often, I want to see changes
> > in adjustment too as part fo the diff.  Maybe I should add an option to
> > disable adjustment optionally, which could be useful in those cases
> > where the diff is a bit hard to understand.
> 
> For myself, I found that editorial changes to recast wording or
> otherwise add and remove material led to cascading reports of
> differences _only_ to spaces in adjusted lines, which usually aren't of
> interest to me.

I've changed my mind.  I think it's better to disable it by default in
diffman-git(1), and I can enable it easily anyway.  I've applied the
following patch:

<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/commit/?h=contrib&id=637b0aa571b61d98c717e7ab7490df8a3d9e4841>

commit 637b0aa571b61d98c717e7ab7490df8a3d9e4841
Author: Alejandro Colomar <alx@kernel.org>
Date:   Fri May 2 17:08:20 2025 +0200

    src/bin/diffman-git: Disable adjustment by default
    
    One can still enable it by setting an empty MANROFFOPT.
    
    Suggested-by: "G. Branden Robinson" <branden@debian.org>
    Signed-off-by: Alejandro Colomar <alx@kernel.org>

diff --git a/src/bin/diffman-git b/src/bin/diffman-git
index ede506c91..25c0a98b6 100755
--- a/src/bin/diffman-git
+++ b/src/bin/diffman-git
@@ -31,6 +31,7 @@ git rev-parse --show-toplevel | read -r dir;
 cd "$dir";
 
 test -v MAN_KEEP_FORMATTING || export MAN_KEEP_FORMATTING=1;
+test -v MANROFFOPT          || export MANROFFOPT='-d AD=l';
 
 # shellcheck disable=SC2206  # We want only non-empty variables in the array.
 opts=($s $w $u);

> > > for P in *.[157]
> > > do
> > >     if [ "$P" = groff_mmse.7 ]
> > >     then
> > >       LOCALE=-msv
> > >     else
> > >       LOCALE=
> > >     fi
> > 
> > What's -msv?
> 
> groff_tmac(5):
> 
>    Localization packages
>      For Western languages, an auxiliary package for localization sets
>      the hyphenation mode and loads hyphenation patterns and exceptions.
>      Localization files can also adjust the date format and provide
>      translations of strings used by some of the full‐service macro
>      packages; alter the input encoding (see the next section); and
>      change the amount of additional inter‐sentence space.  For Eastern
>      languages, the localization file defines character classes and sets
>      flags on them.  By default, troffrc loads the localization file for
>      English.
> ...
>      sv     Swedish; localizes man, me, mm, mom, and ms.  Sets the input
>             encoding to Latin‐1 by loading latin1.tmac.  Some of the
>             localization of the mm package is handled separately; see
>             groff_mmse(7).

Hmmm.

> > >     echo $0: $P >&2
> > >     echo "groff $ARGS $LOCALE $P" > "$P.cR.txt"
> > >     groff $ARGS $LOCALE "$P" >> "$P.cR.txt"
> > > ...
> > > done
> > 
> > Would you mind sharing the entire script?  I might get ideas for
> > improving diffman-git(1).
> 
> Sure; it's crude and dumb (like its author?)--I don't generally spend a
> lot of software engineering effort on stuff I produce only for my own
> consumption.  I've attached it.  The script name is revealing of some of
> my music listening habits.
> 
> > (And maybe you can drop your script if
> > diffman-git(1) would be good-enough for you.)
> 
> If it stops working for the limited purpose I require it, I may look
> into alternatives.  :)

I suggest you try it.  I has some nice features, like specifying the
amount of context lines, or ignoring white space changes (which is
useful to confirm that some change only affects spacing but nothing
else).  It also allows you to diff arbitrary commits, without having to
store a copy of the formatted output.

> > The RE movement is intended to indent the "Since Linux 6.7," para.
> 
> I'd need to look at more context, and haven't, but `IP` already does
> that.

That para was a continuation of a TP, and now is changed to be a
continuation of a nested TP (thus the RS).  See the diff with some more
context, which might clarify:

$ MANWIDTH=72 diffman-git -U20 HEAD^
--- HEAD^^:man/man2const/TIOCLINUX.2const
+++ HEAD^:man/man2const/TIOCLINUX.2const
@@ -24,75 +24,84 @@
             Get task information.  Disappeared in Linux 1.1.92.
 
      subcode=TIOCL_SETSEL
             Set selection.  argp points to a
 
                 struct {
                     char  subcode;
                     short xs, ys, xe, ye;
                     short sel_mode;
                 };
 
             xs and ys are the starting column and row.  xe and ye are
             the ending column and row.  (Upper left corner is row=col‐
             umn=1.)  sel_mode may be one of the following operations:
 
             TIOCL_SELCHAR
                    Select character‐by‐character.  The indicated screen
                    characters are highlighted and saved in a kernel
                    buffer.
 
+                   Since Linux 6.7, using this selection mode requires
+                   the CAP_SYS_ADMIN capability.
+
             TIOCL_SELWORD
                    Select word‐by‐word, expanding the selection out‐
                    wards to align with word boundaries.  The indicated
                    screen characters are highlighted and saved in a
                    kernel buffer.
 
+                   Since Linux 6.7, using this selection mode requires
+                   the CAP_SYS_ADMIN capability.
+
             TIOCL_SELLINE
                    Select line‐by‐line, expanding the selection out‐
                    wards to select full lines.  The indicated screen
                    characters are highlighted and saved in a kernel
                    buffer.
 
+                   Since Linux 6.7, using this selection mode requires
+                   the CAP_SYS_ADMIN capability.
+
             TIOCL_SELPOINTER
                    Show the pointer at position (xs, ys) or (xe, ye),
                    whichever is later in text flow order.
 
             TIOCL_SELCLEAR
                    Remove the current selection highlight, if any, from
                    the console holding the selection.
 
                    This does not affect the stored selected text.
 
             TIOCL_SELMOUSEREPORT
                    Make the terminal report (xs, ys) as the current
                    mouse location using the xterm(1) mouse tracking
                    protocol (see console_codes(4)).  The lower 4 bits
                    of sel_mode (TIOCL_SELBUTTONMASK) indicate the de‐
                    sired button press and modifier key information for
                    the mouse event.
 
                    If mouse reporting is not enabled for the terminal,
                    this operation yields an EINVAL error.
 
-            Since Linux 6.7, using this subcode requires the
-            CAP_SYS_ADMIN capability.
+                   Since Linux 6.7, using this selection mode requires
+                   the CAP_SYS_ADMIN capability.
 
      subcode=TIOCL_PASTESEL
             Paste selection.  The characters in the selection buffer
             are written to fd.
 
             Since Linux 6.7, using this subcode requires the
             CAP_SYS_ADMIN capability.
 
      subcode=TIOCL_UNBLANKSCREEN
             Unblank the screen.
 
      subcode=TIOCL_SELLOADLUT
             Sets contents of a 256‐bit look up table defining charac‐
             ters in a "word", for word‐by‐word selection.  (Since Linux
             1.1.32.)
 
             Since Linux 6.7, using this subcode requires the
             CAP_SYS_ADMIN capability.
 
      subcode=TIOCL_GETSHIFTSTATE


> #!/bin/bash
> 
> set -e
> 
> if [ $# -ne 1 ]
> then
>     echo "need a directory argument (e.g., \"old\", \"new\")" >&2
>     exit 1
> fi

Being diffman-git(1), it uses the git(1) repository to find the old
pages and the new ones.  No need to specify paths.

> 
> if ! [ -x ./build/test-groff ]
> then
>     echo "./build/test-groff does not exist or is not executable" >&2
>     exit 2
> fi
> 
> groff () {
>     ../build/test-groff "$@"
> }

I use man(1), so it would be a matter of passing an appropriate PATH to
run your development groff version.

> 
> BFLAG=
> #BFLAG=-b
> DIR=$1
> 
> MANS=(
> ./src/utils/lkbib/lkbib.1.man
> ./src/utils/tfmtodit/tfmtodit.1.man
> ./src/utils/hpftodit/hpftodit.1.man
> ./src/utils/pfbtops/pfbtops.1.man
> ./src/utils/afmtodit/afmtodit.1.man
> ./src/utils/lookbib/lookbib.1.man
> ./src/utils/addftinfo/addftinfo.1.man
> ./src/utils/xtotroff/xtotroff.1.man
> ./src/utils/indxbib/indxbib.1.man
> ./src/roff/nroff/nroff.1.man
> ./src/roff/troff/troff.1.man
> ./src/roff/groff/groff.1.man
> ./src/utils/grog/grog.1.man
> ./src/devices/grodvi/grodvi.1.man
> ./src/devices/grolbp/grolbp.1.man
> ./src/devices/grops/grops.1.man
> ./src/devices/grohtml/grohtml.1.man
> ./src/devices/grolj4/grolj4.1.man
> ./src/devices/grotty/grotty.1.man
> ./src/devices/gropdf/gropdf.1.man
> ./src/devices/gropdf/pdfmom.1.man
> ./src/devices/xditview/gxditview.1.man
> ./src/preproc/preconv/preconv.1.man
> ./src/preproc/tbl/tbl.1.man
> ./src/preproc/soelim/soelim.1.man
> ./src/preproc/eqn/eqn.1.man
> ./src/preproc/eqn/neqn.1.man
> ./src/preproc/pic/pic.1.man
> ./src/preproc/refer/refer.1.man
> ./src/preproc/grn/grn.1.man
> ./contrib/pic2graph/pic2graph.1.man
> ./contrib/hdtbl/groff_hdtbl.7.man
> ./contrib/mm/groff_mm.7.man
> ./contrib/mm/mmroff.1.man
> ./contrib/grap2graph/grap2graph.1.man
> ./contrib/rfc1345/groff_rfc1345.7.man
> ./contrib/eqn2graph/eqn2graph.1.man
> ./contrib/gpinyin/gpinyin.1.man
> ./contrib/mom/groff_mom.7.man
> ./contrib/gdiffmk/gdiffmk.1.man
> ./contrib/glilypond/glilypond.1.man
> ./contrib/chem/chem.1.man
> ./contrib/gperl/gperl.1.man
> ./man/groff_tmac.5.man
> ./man/groff_out.5.man
> ./man/groff_diff.7.man
> ./man/groff_char.7.man
> ./man/groff.7.man
> ./man/roff.7.man
> ./man/groff_font.5.man
> ./tmac/groff_trace.7.man
> ./tmac/groff_me.7.man
> ./tmac/groff_ms.7.man
> ./tmac/groff_man.7.man
> ./tmac/groff_man_style.7.man
> ./tmac/groff_mdoc.7.man
> ./tmac/groff_www.7.man
> )

I calculate the MANS dynamically with a regex:

	case $# in
	0)  git diff --name-only;		;;
	1)  git diff --name-only "$1^..$1";	;;
	*)  git diff --name-only "$1..$2";	;;
	esac \
	| grep -E '(\.[[:digit:]]([[:alpha:]][[:alnum:]]*)?\>|\.man)+(\.man|\.in)*$' \
	| sortman \

> 
> MANS_SV=(
> ./contrib/mm/groff_mmse.7.man
> )
> 
> mkdir "$DIR"
> pushd "$DIR" >/dev/null
> 
> # the change logs, so we know approximately where we are
> cp ../ChangeLog .
> 
> for d in chem gdiffmk glilypond gperl gpinyin hdtbl mm mom rfc1345 sboxes
> do
> 	cp ../contrib/$d/ChangeLog ./ChangeLog.$d
> done
> 
> # our Texinfo manual
> cp ../build/doc/groff.txt .
> 
> # our Texinfo manual via HTML
> cp ../build/doc/groff.html .
> lynx -dump groff.html > groff.html.txt
> 
> # our ms manuals
> groff $BFLAG -ww -Tutf8 -ept -ms ../doc/ms.ms > ms.txt
> 
> # our me manuals
> #groff $BFLAG -ww -Tutf8 -me ../doc/meintro.me > meintro.txt
> #groff $BFLAG -ww -Tutf8 -kt -me -mfr ../doc/meintro_fr.me > meintro_fr.txt
> #groff $BFLAG -ww -Tutf8 -me ../doc/meref.me > meref.txt
> me_pre=../ATTIC/my.me
> groff $BFLAG -ww -Tutf8 -me $me_pre ../build/doc/meintro.me > meintro.txt
> groff $BFLAG -ww -Tutf8 -kt -me -mfr $me_pre ../build/doc/meintro_fr.me \
>     > meintro_fr.txt
> groff $BFLAG -ww -Tutf8 -me $me_pre ../build/doc/meref.me > meref.txt
> 
> for F in ${MANS[*]} ${MANS_SV[*]}
> do
>     G=../build/${F%.man}
>     if [ -f "$G" ]
>     then
>         cp "$G" .
>     else
>         echo "warning: \"$G\" missing" >&2
>     fi
> done
> 
> : ${AD:=l}
> 
> ARGS="$BFLAG -ww -dAD=$AD -rCHECKSTYLE=3 -rU1 -Tutf8 -e -t -mandoc"
> NOCR=-rcR=0
> LOCALE=
> ARGS_HTML="$BFLAG -ww -rCHECKSTYLE=3 -Thtml -e -t -mandoc -P-C -P-G"
> 
> 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"
>     echo "groff $ARGS $LOCALE $NOCR $P" > "$P.no-cR.txt"
>     groff $ARGS $LOCALE $NOCR "$P" >> "$P.no-cR.txt"
>     echo "<!-- groff $ARGS_HTML $LOCALE -P-I$P $P -->" > "$P.html"
>     groff $ARGS_HTML $LOCALE -P-I$P $P >> "$P.html"
>     rm "$P"
> done

Hmmm, my script is dumber; it only calls man(1).  But I guess that's
enough.  You can always tell man(1) to pass stuff to groff(1).

	| sortman \
	| while read -r f; do \
		case $# in
		0)  old="HEAD:$f";  new="./$f";   ;;
		1)  old="$1^:$f";   new="$1:$f";  ;;
		*)  old="$1:$f";    new="$2:$f";  ;;
		esac;

		case $# in
		0)  cat "$new";       ;;
		*)  git show "$new";  ;;
		esac \
		| man /dev/stdin \
		| diff --label "$old" --label "$new" "${opts[@]}" \
			<(git show "$old" | man /dev/stdin) \
			/dev/stdin \
		|| true;
	done;

> 
> popd >/dev/null

popd(1) at the end of a script is not useful.  Or do you source the
script?

> 
> # vim:set ai et sw=4 ts=4 tw=80:


Cheers,
Alex

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 14:51     ` G. Branden Robinson
@ 2025-05-02 15:34       ` Alejandro Colomar
  2025-05-03  1:30         ` G. Branden Robinson
  0 siblings, 1 reply; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-02 15:34 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 4238 bytes --]

Hi Branden,

On Fri, May 02, 2025 at 09:51:04AM -0500, G. Branden Robinson wrote:
> At 2025-05-02T15:06:46+0200, Martin Lemaire wrote:
> > Thank you Branden for those historical insights. 
> > Off-topic to Alejandro's initial question but related to the subject of
> > justifying text set in monospace, do we owe this typographic gesture to
> > the early *roff formaters or was it already a thing in previous
> > publication tool, either software or hardware ?
> 
> It dates back at least to "old" roff, which is one of the first Unix
> programs ever to exist.  It is older than the C language.
> 
> roff(7):
> 
> History
>      Computer‐driven document formatting dates back to the 1960s.  The
>      roff system is intimately connected with Unix, but its origins lie
>      with the earlier operating systems CTSS, GECOS, and Multics.
> ...
>    Unix and roff
>      McIlroy’s roff was one of the first Unix programs.  In Ritchie’s
>      term, it was “transliterated” from BCPL to DEC PDP‐7 assembly
>      language for the fledgling Unix operating system.  Automatic
>      hyphenation was managed with .hc and .hy requests, line spacing
>      control was generalized with the .ls request, and what later roffs
>      would call diversions were available via “footnote” requests.  This
>      roff indirectly funded operating systems research at Murray Hill;
>      AT&T prepared patent applications to the U.S. government with it.
>      This arrangement enabled the group to acquire a PDP‐11; roff
>      promptly proved equal to the task of formatting the manual for what
>      would become known as “First Edition Unix”, dated November 1971.
> 
> And, sure enough, it performed adjustment.  We can observe its behavior
> in Seventh Edition Unix (1979), which while much later chronologically,
> also documents roff(1) as "utterly frozen".  Joe Ossanna's nroff(1),
> "new roff", appeared in Second Edition Unix (1972) and immediately
> sucked up all the oxygen available for document formatting work at the
> Bell Labs CSRC.
> 
> ---snip---
> PDP-11 simulator V3.8-1
> Disabling XQ
> @boot
> New Boot, known devices are hp ht rk rl rp tm vt
> : rl(0,0)rl2unix
> mem = 177856
> # Restricted rights: Use, duplication, or disclosure
> is subject to restrictions stated in your contract with
> Western Electric Company, Inc.
> Thu Sep 22 23:33:03 EDT 1988
> 
> login: dmr
> $ cat lemaire
> Off-topic to Alejandro's initial question but related to the subject of
> justifying text set in monospace, do we owe this typographic gesture to
> the early *roff formaters or was it already a thing in previous
> publication tool, either software or hardware?
> $ roff lemaire | sed '/^$/d'
> Off-topic to Alejandro's initial question but related to the sub-
> ject of justifying text set in monospace, do we owe this typogra-
> phic gesture to the early *roff formaters or  was  it  already  a
> thing in previous publication tool, either software or hardware?
> ---end snip---

This example doesn't show the alternating preference of blanks left and
right.  Do you have any example that would do that?


Cheers,
Alex

> 
> > Are you aware of theory or paper on the subject ?
> 
> The practice of adjusting lines of text to be all the same length when
> typesetting is an old one.  It appears to be the practice in at least
> some late-medieval illuminated manuscripts, and images of the pages of
> the Gutenberg Bible that I can find online suggest to me that the
> practice goes back to the dawn of the printing press.
> 
> Since monospaced typefaces are a straightforward application of movable
> type, the concept of "adjusting" printed lines thereof could not have
> been novel.  It was simply too tedious a practice to expect of
> typewriter operators who composed text on the fly while drafting.
> Computers, however, are perfect for automation of tedium.
> 
> But I'm far from a subject matter expert.  And a bit too young to opine
> authoritatively on life at the CSRC.  Fortunately, some groff list
> subscribers have first-hand knowledge.  :)
> 
> Regards,
> Branden



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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 13:06   ` Martin Lemaire
  2025-05-02 14:51     ` G. Branden Robinson
@ 2025-05-02 17:42     ` Dave Kemper
  2025-05-02 18:46       ` Martin Lemaire
  1 sibling, 1 reply; 23+ messages in thread
From: Dave Kemper @ 2025-05-02 17:42 UTC (permalink / raw)
  To: Martin Lemaire; +Cc: Groff, linux-man

On Fri, May 2, 2025 at 8:07 AM Martin Lemaire <contact@martinlemaire.fr> wrote:
> Off-topic to Alejandro's initial question but related to the subject of
> justifying text set in monospace, do we owe this typographic gesture to
> the early *roff formaters or was it already a thing in previous
> publication tool, either software or hardware ?

Branden addressed the conceptual basis for such adjustment.  The
origin of the specific algorithm used for monospace fonts was revealed
by its inventor in a post a few years ago:

http://lists.gnu.org/r/groff/2018-06/msg00044.html

Other than starting with a different adjustment "direction," this
algorithm remains unchanged in groff today.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 17:42     ` Dave Kemper
@ 2025-05-02 18:46       ` Martin Lemaire
  2025-05-03  0:14         ` G. Branden Robinson
  0 siblings, 1 reply; 23+ messages in thread
From: Martin Lemaire @ 2025-05-02 18:46 UTC (permalink / raw)
  To: Dave Kemper; +Cc: Groff, linux-man

Although Gutenberg had a major impact on printing in the 15th century,
there are traces in Asia of xylogprahy[1] as early as the 6th century. 
It is argued that western educations give the guy too much credit. 
His contribution to the craft was more about crafting inks allowing the
printing on both side of the sheet.
Earlier than that – and closer to the practice that is printing
characters in a monospaced grid – there has been stoichedon[2], a style
of stone engraving where letters are aligned vertically and
horizontally. Words seem to be separated by a spaceless sign between
them. I assume this absence of spaces produced the most uniform and
pleasing grayness.
To my knowledge, we have to wait for the year 2000 for someone called
rs1n to produce a perfectly justified monospaced document[3] without adding or
removing between-word space, writing and typesetting at the same time.

How does *roff monospace justification algorithm relate to its sibling
justifying proportional letters ?
Are the two vaguely related or it's another approach ?

Martin


[1] Printed copy of the Vajracchedikaprajnaparamitasutra, 868 https://idp.bl.uk/collection/51FDAEAFB4A24E2E9981692A98130BC8/

[2] Stoichedon https://en.wikipedia.org/wiki/Stoichedon

[3] Super Metroid – FAQ/Speed Guide, rs1n, 2000 https://gamefaqs.gamespot.com/snes/588741-super-metroid/faqs/10114
mirrored here https://www.martinlemaire.fr/metroid.html


Le Fri, May 02, 2025 at 12:42:30PM -0500, Dave Kemper a écrit :
> On Fri, May 2, 2025 at 8:07 AM Martin Lemaire <contact@martinlemaire.fr> wrote:
> > Off-topic to Alejandro's initial question but related to the subject of
> > justifying text set in monospace, do we owe this typographic gesture to
> > the early *roff formaters or was it already a thing in previous
> > publication tool, either software or hardware ?
> 
> Branden addressed the conceptual basis for such adjustment.  The
> origin of the specific algorithm used for monospace fonts was revealed
> by its inventor in a post a few years ago:
> 
> http://lists.gnu.org/r/groff/2018-06/msg00044.html
> 
> Other than starting with a different adjustment "direction," this
> algorithm remains unchanged in groff today.
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 18:46       ` Martin Lemaire
@ 2025-05-03  0:14         ` G. Branden Robinson
  2025-05-05 16:00           ` Joey Hess
  0 siblings, 1 reply; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-03  0:14 UTC (permalink / raw)
  To: Martin Lemaire; +Cc: groff, linux-man, joeyh

[-- Attachment #1: Type: text/plain, Size: 3242 bytes --]

[adding Joey Hess to CC to refresh my memory on bricktext--see below]

At 2025-05-02T20:46:47+0200, Martin Lemaire wrote:
> Although Gutenberg had a major impact on printing in the 15th century,
> there are traces in Asia of xylogprahy[1] as early as the 6th century. 
> It is argued that western educations give the guy too much credit. 
> His contribution to the craft was more about crafting inks allowing the
> printing on both side of the sheet.

That could be.  As I noted, I'm not a domain expert.  But I would be
cautious; as bloodily successful as European colonialism and propaganda
have been, Europeans did not invent the practice of chauvinism.  It
seems to arise naturally among humans everywhere.

I find the sad story of the Moriori in Polynesia to be a telling
example.

> Earlier than that – and closer to the practice that is printing
> characters in a monospaced grid – there has been stoichedon[2], a
> style of stone engraving where letters are aligned vertically and
> horizontally. Words seem to be separated by a spaceless sign between
> them. I assume this absence of spaces produced the most uniform and
> pleasing grayness.

First I've heard of this--neat!

> To my knowledge, we have to wait for the year 2000 for someone called
> rs1n to produce a perfectly justified monospaced document[3] without
> adding or removing between-word space, writing and typesetting at the
> same time.

Hmmm.

[from the linked site]
>>> 03. What program did you use to justify the text?
>>>   None. I just chose words carefully so that everything lined up on
>>>   the right hand side. Everything was done with an ASCII editor.

I know this concept by the name "bricktext"; a guy named Jim Warner has
been practicing it in Git commit messages for the procps project[A]
since at least 2012, but if I remember correctly he was doing it in his
emails many years before that.  I learned of the phenomenon from Joey
Hess on the Debian mailing lists over 20 years ago.  Joey, do you recall
more details?  Was Jim the person you had in mind back then?  Can
someone claim priority in the 1990s?  (Or earlier?  It wouldn't surprise
me if Martin Gardner had an article about it in 1959.)

> How does *roff monospace justification algorithm relate to its sibling
> justifying proportional letters ?  Are the two vaguely related or it's
> another approach ?

They're closely related.  The only difference is that the horizontal
motion quantum on a typewriter/nroff device is much coarser with respect
to the glyph pitch (width) than on typesetters.

The relevant function fits on one screen, if your terminal window is at
least 36 lines high.  :)  (Much of it is given over to comments.)

https://git.savannah.gnu.org/cgit/groff.git/tree/src/roff/troff/env.cpp?id=d96a9c58bbe296b065fa250e3ea1e1a410cdde81#n2185

> [3] Super Metroid – FAQ/Speed Guide, rs1n, 2000
> https://gamefaqs.gamespot.com/snes/588741-super-metroid/faqs/10114
> mirrored here https://www.martinlemaire.fr/metroid.html

I'm not much of a video gamer--few attract my attention and fewer still
hold it--but Super Metroid was indeed a gem.

Regards,
Branden

[A] https://gitlab.com/procps-ng/procps

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-02 14:59       ` Alejandro Colomar
@ 2025-05-03  0:49         ` G. Branden Robinson
  2025-05-03  7:25           ` Alejandro Colomar
  2025-05-05 10:50           ` Colin Watson
  0 siblings, 2 replies; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-03  0:49 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1267 bytes --]

Hi Alex,

At 2025-05-02T16:59:58+0200, Alejandro Colomar wrote:
> On Fri, May 02, 2025 at 09:19:48AM -0500, G. Branden Robinson wrote:
> > Your grog executable may be out of sync with the man page you're
> > reading.
> > 
> > Compare `type grog` with `man -w grog`.
> 
> Hmmmm.
> 
> alx@devuan:~$ which grog
> /usr/local/bin/grog
> alx@devuan:~$ grog --version
> GNU grog (groff) 1.23.0.2695-49927
> alx@devuan:~$ man grog | tail -n1
> groff 1.23.0                    26 December 2024                        grog(1)
[...]
> Okay, this complicates things a bit.  :)

I'm betting `man -w grog` reports "/usr/share/man/man1/grog.1", possibly
with a ".gz" extension--in which case, mystery solved.

In my shell startup files, I make sure to update $MANPATH any time I
update $PATH.

This is not a common piece of cargo that Unix newcomers acquire;
historically, I suppose a lot of man(1) implementations didn't support
$MANPATH, but man-db has for decades, and I see mandoc(1) does too.

Setting it won't, as I understand it, help FreeBSD or macOS users; but
the former have already memorized everything worth knowing about their
systems, and the latter use only "intuitive" software that requires no
documentation.

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-02 15:34       ` Alejandro Colomar
@ 2025-05-03  1:30         ` G. Branden Robinson
  0 siblings, 0 replies; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-03  1:30 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1945 bytes --]

Hi Alex,

At 2025-05-02T17:34:41+0200, Alejandro Colomar wrote:
> On Fri, May 02, 2025 at 09:51:04AM -0500, G. Branden Robinson wrote:
> > ---snip---
> > PDP-11 simulator V3.8-1
> > Disabling XQ
> > @boot
> > New Boot, known devices are hp ht rk rl rp tm vt
> > : rl(0,0)rl2unix
> > mem = 177856
> > # Restricted rights: Use, duplication, or disclosure
> > is subject to restrictions stated in your contract with
> > Western Electric Company, Inc.
> > Thu Sep 22 23:33:03 EDT 1988
> > 
> > login: dmr
> > $ cat lemaire
> > Off-topic to Alejandro's initial question but related to the subject of
> > justifying text set in monospace, do we owe this typographic gesture to
> > the early *roff formaters or was it already a thing in previous
> > publication tool, either software or hardware?
> > $ roff lemaire | sed '/^$/d'
> > Off-topic to Alejandro's initial question but related to the sub-
> > ject of justifying text set in monospace, do we owe this typogra-
> > phic gesture to the early *roff formaters or  was  it  already  a
> > thing in previous publication tool, either software or hardware?
> > ---end snip---
> 
> This example doesn't show the alternating preference of blanks left and
> right.  Do you have any example that would do that?

Sure.  I was going to be glib and say "just repeat any word whose length
in ens + 1 (for the trailing space) is relatively prime to the line
length", but that doesn't quite work because when the trailing space
ends the line, it is discarded.

Still, this serves.

$ for n in $(seq 60); do echo alex; done | nroff | cat -s
alex  alex alex alex alex alex alex alex alex alex alex alex alex
alex alex alex alex alex alex alex alex alex alex alex alex  alex
alex  alex alex alex alex alex alex alex alex alex alex alex alex
alex alex alex alex alex alex alex alex alex alex alex alex  alex
alex alex alex alex alex alex alex alex

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-03  0:49         ` G. Branden Robinson
@ 2025-05-03  7:25           ` Alejandro Colomar
  2025-05-05 10:50           ` Colin Watson
  1 sibling, 0 replies; 23+ messages in thread
From: Alejandro Colomar @ 2025-05-03  7:25 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1782 bytes --]

Hi Branden,

On Fri, May 02, 2025 at 07:49:17PM -0500, G. Branden Robinson wrote:
> At 2025-05-02T16:59:58+0200, Alejandro Colomar wrote:
> > On Fri, May 02, 2025 at 09:19:48AM -0500, G. Branden Robinson wrote:
> > > Your grog executable may be out of sync with the man page you're
> > > reading.
> > > 
> > > Compare `type grog` with `man -w grog`.
> > 
> > Hmmmm.
> > 
> > alx@devuan:~$ which grog
> > /usr/local/bin/grog
> > alx@devuan:~$ grog --version
> > GNU grog (groff) 1.23.0.2695-49927
> > alx@devuan:~$ man grog | tail -n1
> > groff 1.23.0                    26 December 2024                        grog(1)
> [...]
> > Okay, this complicates things a bit.  :)
> 
> I'm betting `man -w grog` reports "/usr/share/man/man1/grog.1", possibly
> with a ".gz" extension--in which case, mystery solved.

Yep, it's the system one.

> In my shell startup files, I make sure to update $MANPATH any time I
> update $PATH.

I'm not sure why, but I don't have any pages for groff(1) under
</usr/local>.  It seems I only installed the binaries.  It's not a
matter of MANPATH not being set.  In fact, I read the pages from the
Linux man-pages installed into </usr/local> every day.  :|


Have a lovely day!
Alex

> 
> This is not a common piece of cargo that Unix newcomers acquire;
> historically, I suppose a lot of man(1) implementations didn't support
> $MANPATH, but man-db has for decades, and I see mandoc(1) does too.
> 
> Setting it won't, as I understand it, help FreeBSD or macOS users; but
> the former have already memorized everything worth knowing about their
> systems, and the latter use only "intuitive" software that requires no
> documentation.
> 
> Regards,
> Branden



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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-03  0:49         ` G. Branden Robinson
  2025-05-03  7:25           ` Alejandro Colomar
@ 2025-05-05 10:50           ` Colin Watson
  2025-05-05 15:41             ` Ingo Schwarze
  1 sibling, 1 reply; 23+ messages in thread
From: Colin Watson @ 2025-05-05 10:50 UTC (permalink / raw)
  To: groff, linux-man

On Fri, May 02, 2025 at 07:49:17PM -0500, G. Branden Robinson wrote:
>In my shell startup files, I make sure to update $MANPATH any time I
>update $PATH.
>
>This is not a common piece of cargo that Unix newcomers acquire;
>historically, I suppose a lot of man(1) implementations didn't support
>$MANPATH, but man-db has for decades, and I see mandoc(1) does too.

FWIW, with man-db, it's usually best for most people not to set MANPATH 
at all unless manual pages are somewhere that can't be straightforwardly 
derived from PATH.  man-db will normally work it out based on PATH, and 
that way it's harder for them to get out of sync.

-- 
Colin Watson (he/him)                              [cjwatson@debian.org]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-05 10:50           ` Colin Watson
@ 2025-05-05 15:41             ` Ingo Schwarze
  2025-05-07 18:10               ` G. Branden Robinson
  0 siblings, 1 reply; 23+ messages in thread
From: Ingo Schwarze @ 2025-05-05 15:41 UTC (permalink / raw)
  To: groff, linux-man

Hello,

Colin Watson wrote on Mon, May 05, 2025 at 11:50:10AM +0100:
> On Fri, May 02, 2025 at 07:49:17PM -0500, G. Branden Robinson wrote:

>> In my shell startup files, I make sure to update $MANPATH any time I
>> update $PATH.
>> 
>> This is not a common piece of cargo that Unix newcomers acquire;
>> historically, I suppose a lot of man(1) implementations didn't support
>> $MANPATH, but man-db has for decades, and I see mandoc(1) does too.

> FWIW, with man-db, it's usually best for most people not to set MANPATH at
> all unless manual pages are somewhere that can't be straightforwardly
> derived from PATH.  man-db will normally work it out based on PATH, and that
> way it's harder for them to get out of sync.

Actually, mandoc(1) does not really recommend setting MANPATH either.

I consider it the job of the maintainer of the mandoc package on each
operating system to set MANPATH_DEFAULT to a value that is reasonable
for the operating system, as documented in configure.local.example.

If the system administrator of a particular machine really wants to
go full tilt crazy and use a site-specific directory layout, the
best way to deal with that in mandoc is putting "manpath" directives
into /etc/man.conf(5).

When users have to worry about setting MANPATH, i think somebody is
doing something suboptimal somewhere, either the system administrator
or even more likely the package manager of the oprating system.

Less configuration = more happiness.  Make it sane by default.

For example, personally, i hardly ever use MANPATH for anything except
for testing purposes during core mandoc development.  In the extremely
rare cases where i want to access custom manual page trees in non-standard
locations, i use the -M command line option rather than MANPATH.

So even a highly specialized developer who spends about half his time
on manual page development barely needs MANPATH at all.  The thought
that ordinary users might feel compelled to use it is rather
surprising.

Yours,
  Ingo

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Paragraphs formatted differently depending on previous ones
  2025-05-03  0:14         ` G. Branden Robinson
@ 2025-05-05 16:00           ` Joey Hess
  2025-06-02  6:49             ` on "bricktext" (was: Paragraphs formatted differently depending on previous ones) G. Branden Robinson
  0 siblings, 1 reply; 23+ messages in thread
From: Joey Hess @ 2025-05-05 16:00 UTC (permalink / raw)
  To: groff, linux-man; +Cc: Martin Lemaire

[-- Attachment #1: Type: text/plain, Size: 875 bytes --]

G. Branden Robinson wrote:
> I know this concept by the name "bricktext"; a guy named Jim Warner has
> been practicing it in Git commit messages for the procps project[A]
> since at least 2012, but if I remember correctly he was doing it in his
> emails many years before that.  I learned of the phenomenon from Joey
> Hess on the Debian mailing lists over 20 years ago.  Joey, do you recall
> more details?  Was Jim the person you had in mind back then? 

The name possibly vaguely rings a bell, but I searched my email achives
and didn't see him back to the mid 90's.

It seems more likely to me that I was writing, and just happened to have
a paragraph almost perfectly self justify and then played with it a bit.
Or I could have seen it on usenet at some point. Also, .signature blocks
commonly were formatted as bricks back in the day.

-- 
see shy jo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: grof --run
  2025-05-05 15:41             ` Ingo Schwarze
@ 2025-05-07 18:10               ` G. Branden Robinson
  0 siblings, 0 replies; 23+ messages in thread
From: G. Branden Robinson @ 2025-05-07 18:10 UTC (permalink / raw)
  To: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1952 bytes --]

Hi Colin and Ingo,

At 2025-05-05T11:50:10+0100, Colin Watson wrote:
> FWIW, with man-db, it's usually best for most people not to set
> MANPATH at all unless manual pages are somewhere that can't be
> straightforwardly derived from PATH.  man-db will normally work it out
> based on PATH, and that way it's harder for them to get out of sync.

At 2025-05-05T17:41:48+0200, Ingo Schwarze wrote:
> Actually, mandoc(1) does not really recommend setting MANPATH either.
> 
> I consider it the job of the maintainer of the mandoc package on each
> operating system to set MANPATH_DEFAULT to a value that is reasonable
> for the operating system, as documented in configure.local.example.
[...]
> So even a highly specialized developer who spends about half his time
> on manual page development barely needs MANPATH at all.  The thought
> that ordinary users might feel compelled to use it is rather
> surprising.

I can't be sure because I haven't kept my dot files under version
control for sufficiently long, but I think I figured out why I've
carried $MANPATH construction logic in my .bashrc for so long.

About 18 years ago when taking a job at $FIRM, I had the option to be
issued either an Intel-based Macintosh laptop (the choice of all the
cool turtleneck kids) or one with a GNU/Linux distro officially
supported by the firm's IT department...but it was an RPM-based distro.
It might have been CentOS and not a fresh spin thereof.

In other words the distro might have been so old that the man(1) in use
was Brouwer/Lucifredi man, of which I did not have a high opinion.
Having to manage my own $MANPATH was likely a major reason I was annoyed
with it.  But as I noted later in a groff commit message, that program
"as of this writing [2020] saw its last release in 2011 (1.6g)."

So thanks for the pointing the opportunity I can take to kick some cruft
out of shell startup files.  :)

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* on "bricktext" (was: Paragraphs formatted differently depending on previous ones)
  2025-05-05 16:00           ` Joey Hess
@ 2025-06-02  6:49             ` G. Branden Robinson
  2025-06-02  7:16               ` on "bricktext" James Cloos
  0 siblings, 1 reply; 23+ messages in thread
From: G. Branden Robinson @ 2025-06-02  6:49 UTC (permalink / raw)
  To: Joey Hess; +Cc: groff, linux-man

[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]

[probably getting off-topic for linux-man]

Hi Joey,

At 2025-05-05T12:00:38-0400, Joey Hess wrote:
> G. Branden Robinson wrote:
> > I know this concept by the name "bricktext"; a guy named Jim Warner
> > has been practicing it in Git commit messages for the procps
> > project[A] since at least 2012, but if I remember correctly he was
> > doing it in his emails many years before that.  I learned of the
> > phenomenon from Joey Hess on the Debian mailing lists over 20 years
> > ago.  Joey, do you recall more details?  Was Jim the person you had
> > in mind back then? 
> 
> The name possibly vaguely rings a bell, but I searched my email
> achives and didn't see him back to the mid 90's.
> 
> It seems more likely to me that I was writing, and just happened to
> have a paragraph almost perfectly self justify and then played with it
> a bit.  Or I could have seen it on usenet at some point. Also,
> .signature blocks commonly were formatted as bricks back in the day.

I found an exhibit of bricktext from 1998.

https://lists.debian.org/debian-devel/1998/10/msg02449.html

Regards,
Branden

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: on "bricktext"
  2025-06-02  6:49             ` on "bricktext" (was: Paragraphs formatted differently depending on previous ones) G. Branden Robinson
@ 2025-06-02  7:16               ` James Cloos
  0 siblings, 0 replies; 23+ messages in thread
From: James Cloos @ 2025-06-02  7:16 UTC (permalink / raw)
  To: G. Branden Robinson; +Cc: Joey Hess, groff, linux-man

>>>>> "BR" == G Branden Robinson <g.branden.robinson@gmail.com> writes:

BR> I found an exhibit of bricktext from 1998.

BR> https://lists.debian.org/debian-devel/1998/10/msg02449.html

didn't we all do a instance or three of that back in the day?

ie adjust some words here and there to arrange justification?

-JimC
-- 
James Cloos <cloos@jhcloos.com>
            OpenPGP: https://jhcloos.com/0x997A9F17ED7DAEA6.asc

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2025-06-02  7:26 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-02 10:56 Paragraphs formatted differently depending on previous ones Alejandro Colomar
2025-05-02 12:01 ` G. Branden Robinson
2025-05-02 12:26   ` grof --run Alejandro Colomar
2025-05-02 14:19     ` G. Branden Robinson
2025-05-02 14:59       ` Alejandro Colomar
2025-05-03  0:49         ` G. Branden Robinson
2025-05-03  7:25           ` Alejandro Colomar
2025-05-05 10:50           ` Colin Watson
2025-05-05 15:41             ` Ingo Schwarze
2025-05-07 18:10               ` G. Branden Robinson
2025-05-02 12:42   ` Paragraphs formatted differently depending on previous ones Alejandro Colomar
2025-05-02 14:29     ` G. Branden Robinson
2025-05-02 15:30       ` Alejandro Colomar
2025-05-02 13:06   ` Martin Lemaire
2025-05-02 14:51     ` G. Branden Robinson
2025-05-02 15:34       ` Alejandro Colomar
2025-05-03  1:30         ` G. Branden Robinson
2025-05-02 17:42     ` Dave Kemper
2025-05-02 18:46       ` Martin Lemaire
2025-05-03  0:14         ` G. Branden Robinson
2025-05-05 16:00           ` Joey Hess
2025-06-02  6:49             ` on "bricktext" (was: Paragraphs formatted differently depending on previous ones) G. Branden Robinson
2025-06-02  7:16               ` on "bricktext" James Cloos

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).