[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: groff man(7) `B` macro behavior with `\c`, and input traps

From: G. Branden Robinson
Subject: Re: groff man(7) `B` macro behavior with `\c`, and input traps
Date: Sat, 18 Jun 2022 10:40:46 -0500

Hi Ingo,

At 2022-06-17T20:53:13+0200, Ingo Schwarze wrote:
> during the testing described below (which i foolishly expected to
> be minor), i tripped over several new candidates for regressions
> that look unrelated.  This is not a serious report yet, i'll have to
> investigate in more detail and then report properly.  The candidates
> include the following effects that i saw in my usual test setup:

The PDF ones are surprising to me.  But not inexplicable--Deri and I
have both done recent work in this area.  (The problems are likely
solely my fault, though.)

>  * The build died when trying to install font/devpdf/download
>    because the file was never built and consequently didn't exist.

My surmise is that this arises from commit 6e62be835d.  I'll try an
out-of-tree build with MAKE=bmake and see if I can reproduce it.

>  * The PDF font description files (font/devpdf/TR and friends)
>    no longer got installed.

I don't have a clear hypothesis for this one.  I can say it's a little
trickier to deal with because the set of font description files for the
PDF output driver is dynamically generated, and differs depending on the
availability of the URW font files.  This is unlike all of the other
output drivers.  I'll take a closer look; maybe BSD Make will sniff this
one out too.

>  * In the top left corner of manual pages written in man(7),
>    the page name in the header line was set in italic instead
>    of in the correct roman font.

This was a deliberate change; when implementing `MR` I worded the
updates to groff_man(7) carefully to capture this behavior.

commit 999f5083158c77871efdcbbbc072df25039b021f
Author: G. Branden Robinson <>
Date:   Tue Oct 5 20:16:36 2021 +1100

    [man]: Add `MR` macro for man page xrefs.
@@ -3121,6 +3211,30 @@ is used for the title length.
+.BI \-dMF= man-page-title-font
+Set the font used for man page titles named in
+.B .TH
+.B .MR
+the default is
+.RB \(lq I \(rq
+Any valid argument to
+.IR groff 's
+\[lq].ft\[rq] request may be used;
+.MR groff @MAN7EXT@ .
+If the
+.B MF
+string ends in \[lq]I\[rq],
+it is assumed to be an oblique typeface,
+and italic corrections are applied before and after man page titles.
 .BI \-rP n
 Start enumeration of pages at
 .I n

> G. Branden Robinson wrote on Fri, Jun 10, 2022 at 08:07:06AM -0500:
> > At 2022-06-06T09:18:01+0200, Ingo Schwarze wrote:
> >> So since .B uses .itc, and that appears to match Heirloom behaviour
> >> according to your research, it might be unwise to change that now.
> > I've changed it anyway.
> That's fine with me.  With "might", i only meant that that
> compatibiliby should be considered, which you did.  Thoroughly!
> The change makes sense to me.
> I can confirm that
>   .B bold\c
>   roman
> and
>   .B
>   bold\c
>   roman
> now both render "roman" in roman font.  With mandoc, the first already
> renders like groff now does.  With mandoc, the second still renders
> the word "roman" in bold.  I need to take care of that and fix mandoc
> in that respect.

If you want consistency with Unix V7 nroff, it seems so.

$ cat > bboldroman.roff
.TH foo 1
$ nroff -T300s -man bboldroman.roff | od -c
0000000 033 006  \n  \n  \n   f   o   o   (   1   )                    
0000020                                     006             033 006   U
0000040   N   I   X       P   r   o   g   r   a   m   m   e   r   '   s
0000060       M   a   n   u   a   l                                    
0000100                     006             033 006   f   o   o   (   1
0000120   )  \r  \n  \n  \n  \n                     033   E   b   o   l
0000140   d 033   E   r   o   m   a   n   d  \r  \n  \n  \n  \n  \n  \n
0000160  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n
0000240  \n   P   r   i   n   t   e   d       9   /   2   2   /   8   8
0000340       1  \r  \n  \n  \n 033   h 006  \n  \n  \n 033 006 006  \n
0000360 033 006 033 006

I used the DASI-300S driver to suss out the presence of font changes as
described in an earlier mail.  Recalling that, for that terminal,
apparently the sequence (ESC, E) _toggles_ boldface, then what groff
does as of commit 09c028f35a (7 June) is consistent with V7 nroff.

I sure wish someone would leak the Unix 4.0 (1981) troff sources.  I
feel sure that they could be coaxed to build on a V7 environment with
little trouble (since that's where Kernighan originally did his work, as
I understand it).

Maybe a shorter pole would be to write a cat2dit(1) for V7-era C.  One
almost certainly existed in the past, but I've never been able to locate
source code.  John Gardner turned my attention to a man page and C
header file posted long ago to USENET (and which had the legendary Henry
Spencer's fingerprints on it), which together would be enough to
reconstruct one.

> I noticed one other change in behaviour here.
> Consider the following input, which includes a blank input line:
>   preceding text
>   .B
>   bold
>   following text
> It used to render all on one output line.  Now it inserts an output
> line break and 1v vertical space after "preceding text".

I assume you're referring to mandoc(1) here?  On groff 1.22.4 and groff
Git HEAD I get this.

foo(1)                      General Commands Manual                     foo(1)

preceding text

bold following text


"bold" is in bold, consistently.  (There is one change, already noted
above: in Git HEAD, "foo" is now in italics at every occurrence.)

> I wouldn't consider that a regression.  The input is terrible style
> and nobody should insert a blank line at such a place.  Then again,
> *if* encoutering such bad input, i think the new behaviour makes more
> sense.

I agree.  It's a little weird because I think those of us who've
bothered to learn the input-line-trap feature of the man(7) macros at
all have trained ourselves to think that only the "next text line" of
input is affected, but as I've tried to make clear in recent changes to
the groff documentation, that isn't quite the case.  An input trap isn't
sprung until something _writes_ to the output.  Page motions don't

5.27.2 Input Line Traps

 -- Request: .it n name
 -- Request: .itc n name
     Set an input line trap, calling macro NAME after processing the
     next N lines of input that directly produce written output.  Only
     text lines and (some) requests produce output directly.  Macro
     calls of themselves do not--requests or text lines they interpolate

     Consider a macro '.ST S N' which sets the next N input lines in the
     font style S.

          .de ST \" Use style $1 for next $2 text lines.
          .  it \\$2 ES
          .  ft \\$1
          .de ES \" end ST
          .  ft R
          .ST I 1
          .ST I 1
              => oblique face obliqueface  (second "face" upright)

     The 'itc' request is similar, except that lines interrupted with
     the '\c' escape sequence are not applied to the line count.  *Note
     Line Continuation::.  To see the difference, let's change the
     previous example to use 'itc' instead.

          .  itc \\$2 ES
              => oblique face obliqueface  (second "face" oblique)

     Text lines are easily understood as input lines that produce
     written output, but escape sequences like '\D', '\l', and '\L', do
     as well; they thus increment the internal line counter tested for
     fulfillment of the input trap line count.  *Note Drawing

          .de Trap
          TRAP SPRUNG
          .de Mac
          .if r a \l'5n'
          .it 2 Trap
          .it 1 Trap
          .sp \" moves, but does not write or draw
          .itc 1 Trap
          \h'5n'\c \" moves, but does not write or draw

     When 'Trap' gets called depends on whether the 'a' register is
     defined; the control line with the 'if' request may or may not
     produce written output.  We also see that the spacing request 'sp',
     while certainly affecting the output, does not spring the input
     trap.  Similarly, the horizontal motion escape sequence '\h' also
     affected the output, but was not "written".  Observe that we had to
     follow it with '\c' and use 'itc' to prevent the newline at the end
     of the text line from causing a word break, which, like an ordinary
     space character, counts as written output.

          $ groff -Tascii input-trap-example.groff
              => foo bar TRAP SPRUNG baz
              => qux TRAP SPRUNG      jat TRAP SPRUNG
          $ groff -Tascii -ra1 input-trap-example.groff
              => foo _____ TRAP SPRUNG bar baz
              => qux TRAP SPRUNG      jat TRAP SPRUNG

   Input traps are associated with the environment (*note
Environments::); switching to another environment disables the current
input trap, and going back reactivates it, restoring the count of
qualifying lines enumerated in that environment.

I see now that I could further improve the above by adding an adjective.
_Non-blank_ text lines are easily understood as input lines that produce
written output.

Thanks for checking out these changes, and I apologize for not testing
builds often enough with BSD make, if indeed make(1) non-portability is
the root of the problems you encountered.  I'll see if I can find out.


Attachment: signature.asc
Description: PGP signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]