Follow-up Comment #21, bug #68497 (group groff):

Hi garavel,

At 2026-07-10T09:14:37-0400, garavel wrote:
> Follow-up Comment #20, bug #68497 (group groff):
>
> Thanks for your feedback. Here are answers to the pending questions.

I appreciate that, they afford much opportunity for comment...and give
me a mystery to solve.  :)

> 1.
>
>>> The point is that there was a trailing space after ms.acc. groff
>>> -man removed it silently, but groff -mgan takes it seriously as
>>> part of the file name. I let you decide who is right.
>>
>> I advise you to slightly alter that one man page of yours as
>> recommended in groff 1.24.0's release notes or the corresponding
>> entry in its "NEWS" file. [...] What is it your man(7) document
>> trying to do?
>
> I removed the extra-space in the man page as you suggested, which
> solves the problem.

Okay.  And, possibly, per the next point, the whole `so` request can go
away.

> 2.
>
>>> .if t .so /usr/share/lib/tmac/ms.acc
>>
>> ...uh...on a different [note], why is your man(7) document
>> attempting to load a module of the ms(7) package?  That is not
>> documented as supported by any AT&T troff I know of, and it
>> certainly is not by groff.
>
> The persons who wroted this manual page wanted to have accented
> letters in their names, e.g., Se\*'verine.

Understandable.  As far as I know, no man(7) implementation supported
non-ASCII characters until groff in 1989-1991.

> This has no effect when the man page is displayed using nroff,

Right.  This is because character-cell video terminals generally can't
constructively overstrike, and that's the technique "ms.acc" uses for
constructing accented basic Latin characters.  (Not _just_ that;
"ms.acc" also used other features terminals don't support, like type
size changes and "local motions" smaller than a character cell.)

> but worked properly in the PS/PDF files generated by troff.

Yes, because typesetters _can_ constructively overstrike.

> I am open to any better approach that would no import the ms macros.

The NetHack documentation faced a similar problem.  They had a
contributor named Jon Wätte (from long ago I think), who preferred to be
credited as "Jon W}tte" in ASCII-only contexts.

I'll illustrate with an example, but I'm coalescing two commits together
due to a typo fix.


commit 898a430617235a6eb3e2c5d70d67eed3709a0508
Author: nhmall <[email protected]>
Date:   Fri May 29 06:27:02 2026 -0400

    follow-up bits for Guidebook.mn processing

commit a9401fd78af5ad691d1837c42eb08e81ce459656
Author: nhmall <[email protected]>
Date:   Wed May 27 23:02:19 2026 -0400

    Guidebook bits for Jon Wätte (Jon W{tte)

    There is no unintentional spelling mistake.
    Close #1523

diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn
index d90b4c4fd..b586163bd 100644
--- a/doc/Guidebook.mn
+++ b/doc/Guidebook.mn
@@ -6549,7 +6549,7 @@ developed NetHack 3.1 for the Amiga.
 \fBCarl Schelin\fP, \fBStephen Spackman\fP, \fBSteve VanDevender\fP,
 and \fBPaul Winner\fP, ported NetHack 3.1 to the PC.
 .pg
-\fBJon W{tte\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP,
+\fB\*(JW\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP,
 \fBMike Engber\fP, \fBDavid Hairston\fP, \fBMichael Hamel\fP,
 \fBJonathan Handler\fP, \fBJohnny Lee\fP, \fBTim Lennan\fP, \fBRob Menke\fP,
 and \fBAndy Swanson\fP, developed NetHack 3.1 for the Macintosh,
@@ -6907,7 +6907,7 @@ Bart House        John Kallen     Pat Rankin
 Benson I. Margulies    John Rupley     Patric Mueller
 Bill Dyer      John S. Bien    Paul Winner
 Boudewijn Waijers      Johnny Lee      Pierre Martineau
-Bruce Cox      Jon W{tte       Ralf Brown
+Bruce Cox      \*(JW   Ralf Brown
 Bruce Holloway Jonathan Handler        Ray Chason
 Bruce Mewborne Joshua Delahunty        Richard Addison
 Cameron Root   Karl Garrison   Richard Beigel
diff --git a/doc/tmac.nh b/doc/tmac.nh
index a109c66af..aa2ed2a56 100644
--- a/doc/tmac.nh
+++ b/doc/tmac.nh
@@ -139,4 +139,6 @@
 .\" before/after last/first 2 characters of a word.
 .ie \n(.g .hy 12
 .el       .hy 14
+.ds JW Jon W{tte\"
+.if \n(.g .if !'\*[.T]'ascii' .ds JW Jon W\(:atte
 .\"tmac.nh/"


What this does is indirect Jon's surname through a *roff string
definition.


.ds JW Jon W{tte\"


It then overrides that definition, but _only_ if the formatter is
_groff_ and the output device is called "ascii".


.if \n(.g .if !'\*[.T]'ascii' .ds JW Jon W\(:atte


Elsewhere, the NetHack Guidebook interpolates the string thus defined.


\fB\*(JW\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP,


So you might do something similar in the relevant man pages.


.ds ss Severine Simon\"
.if \n(.g .ds ss S\[e aa]verine Simon\"


You'll notice that here, we don't have a conditional regarding the
"ascii" device.  That's because groff's output driver for the "ascii"
device (among others), _grotty_(1), gracefully degrades "é" to its base
character if the output encoding is ASCII.

This solution could be enhanced in a couple of different ways.

A.  You could input the character in UTF-8 if you trust the man page
    librarian to run _groff_(1) or GNU _nroff_(1) with the "-k" or
    "-K utf8" options to ensure that it gets interpreted correctly.


.ds ss Severine Simon\"
.if \n(.g .ds ss Séverine Simon\"


B.  If Mme. Simon is credited in multiple man pages and you don't want
    to maintain multiple copies of this workaround, you could isolate it
    one file containing just the foregoing and use `so` requests to
    include that in each man page requiring somewhere before each page
    interpolates the string.  This is like the "ms.acc" solution, but
    because interpretation of `so` requests is not perfectly reliable in
    man pages, often because something other than a _roff_ is
    interpreting them, we can put a twist on this solution, using
    _soelim_(1) _at build time_ to generate the man pages from a form
    that uses the `so` requests.  I recently used this technique in
    _groff_ itself to solve a different kind of problem.

https://cgit.git.savannah.gnu.org/cgit/groff.git/commit/?id=addb8619890bc0c9cf11ac4c37f57164c195ef69

    See specifically the changes to "Makefile.am" and "groff.7.man".

    This enhancement might only be worth the trouble if you're _already_
    generating the man pages for some other reason, and there is a
    pipeline into which you can easily add _soelim_(1).

> 3.
>
>>> With groff 1.24.1 after patching /usr/share/lib/tmac/an as you
>>> suggested, groff -man fails on 18 out of 95 man pages, with the
>>> following error message:
>>>
>>> Assertion failed: context != DELIMITER_GROFF_EXPRESSION, file
>>> /jenkins/jobs/oi-userland/workspace/components/text/groff/groff-1.24.1/src/roff/troff/input.cpp,
>>> line 2887, function is_usable_as_delimiter
>>> grops:<standard input>: warning: no final 'x stop' command
>>> groff: error: gtroff: Aborted (core dumped)
>>
>> Please send us a reproducer for this problem.  One of the 18 failing man
>> pages
>> will do.
>
> I attach a simplified file named 9.l, which is derived from a real
> manual page by removing many parts that do not cause problems to groff
> 1.24.1.

Okay.  Once again, I can't reproduce it in my environment.  I'll need to
spin up that Vagrant instance again.  That will take a little time,
because I already discarded the old one, but fortunately I archived my
shell log of the procedure.  (The OpenIndiana image needed extensive
updating after Vagrant initialized it before I could install its groff
1.24.1 package.)

> On OpenIndiana, the command "groff -man -Tps 9.l > /dev/null" aborts,
> whereas "groff -mgan -Tps 9.l > /dev/null" works.

Understood.  I now consider that reported defect the scope of this
ticket.  GNU _troff_ is choking on something the Illumos/OpenIndiana
man(7) macros do, and apparently only on that platform.

> 4.
>
> Finally, I should point out that the output of groff -mgan is slightly
> different from the one of groff -man.  This is illustrated with the
> attached PNG file.

Yes.  None of the differences I see surprise me.

a.  The page headers and footers differ a bit.  groff man(7) appears to
    be laying out the headers and footers as documented.


groff_man(7):

     .TH identifier section [footer‐middle [footer‐inside [header‐
     middle]]]
            Break the page, reset the page number to 1 (unless the -rC1
            option is given), and use the arguments to populate the page
            header and footer.  Together, identifier and the section of
            the manual to which it belongs can uniquely identify a man
            document on the system.  See man(1) or intro(1) for the
            manual sectioning applicable to your system.  identifier and
            section are positioned at the left and right in the header;
            the latter is set after the former, in parentheses and
            without space.  footer‐middle is centered in the footer.  By
            default, footer‐inside is positioned at the bottom left.
            Use of the double‐sided layout option -rD1 places footer‐
            inside at the bottom left on recto (odd‐numbered) pages, and
            the bottom right on verso (even‐numbered) pages.  By
            default, the outside footer is the page number.  Use of the
            continuous‐rendering option -rcR=1 replaces it with
            identifier and section, as in the header.  header‐middle is
            centered in the header.  If section is an integer between 1
            and 9 (inclusive), an.tmac supplies text for it.  If
            identifier or footer‐inside would overset the space
            available in the header and/or footer, groff man may
            abbreviate them with ellipses.  groff man suppresses headers
            and footers in HTML output.

            Do not redefine TH.  Call it prior to any other man macros.


      groff's "PROBLEMS" file has further advice, originating in the
      1990s.


* I don't like the page headers and footers produced by groff -man.

[-mgan in your case.  --GBR]

There seem to be many different styles of page header and footer
produced by different versions of the -man macros.  You need to put
modified macros from tmac/an.tmac into man.local.  More information is
available in groff_man(7).


      Unix vendors historically had a grand time differentiating
      themselves from each other in this area.

b.  Hyphenation breaks differ in location.  This is another known
    difference of long standing.  _groff_diff_(7) explains.



Other differences
...
     GNU troff does not always hyphenate words as AT&T troff does.  The
     AT&T implementation uses a set of hard‐coded rules specific to U.S.
     English (“suftab”), while GNU troff uses language‐specific
     hyphenation pattern files derived from TeX.  Some versions of troff
     reserved meager storage for hyphenation exception words (arguments
     to the hw request); GNU troff has no such restriction.  When the hy
     request is invoked without an argument, GNU troff sets the
     automatic hyphenation mode to the value of the .hydefault register;
     the AT&T implementation sets it to “1”, which is not suitable in
     GNU troff for some languages, including English.


c.  _groff_ _man_(7) reduces the type size only of subsection headings,
    not section headings.



groff_man(7):
     .SH [heading‐text]
            Set heading‐text as a section heading.  Given no argument,
            SH plants a one‐line input trap; text on the next line
            becomes heading‐text.  The heading text is set in bold (or
            the font specified by the string HF), and, on typesetters,
            slightly larger than the base type size. ...
...
     .SS [subheading‐text]
            Set subheading‐text as a subsection heading indented between
            a section heading and an ordinary paragraph (P).  Given no
            argument, SS plants a one‐line input trap; text on the next
            line becomes subheading‐text.  The subheading text is set in
            bold (or the font specified by the string HF). ...


Solaris _man_(7) _reduces_ the type size of headings.


$ cat -v HISTORY/MAN/openindiana-doctools-0.5.11/an \
  | sed -n '/\.de S[HS]/,/^\.\./p'
.de SH
.}X 0
.nr )E 2
\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6
..
.de SS
.}X .25i "" ""
.nr )E 2
\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6
.br
..


To see the type size reduction happening, we must inspect the definition
of the internal `{X` macro.


$ sed -n '/\.de }X/,/^\.\./p' HISTORY/MAN/openindiana-doctools-0.5.11/an
.de }X
.}E
.ti \\$1
.sp \\n()Pu
.ne 2
.nr )R 0
.fi
.it 1 }N
.SM
.B
..


The `SM` and `B` calls at the end explain the difference.  If this is a
problem, let me know, and I can prepare some "unofficial" advice for
coping with it (exploiting undocumented internals of _groff_ _man_(7)).

The foregoing account for all the differences I can see in the pages,
apparent from slight differences in margin sizes which might be
explicable by the A4 vs. U.S. letter paper size difference.

Let me know of this helps, or doesn't.

P.S.  I'm a big fan of formal methods...and wish I were more of a
      practitioner of them!



    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68497>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/

Attachment: signature.asc
Description: PGP signature

Reply via email to