[looping in groff list]

Hi Karl,

At 2026-04-12T15:04:32-0600, Karl Berry wrote:
> Hi Hille,
> 
>     when processing the makeindex manual page using troff a few
>     warnings are displayed:
>     ...
>     troff:<standard input>:576: warning: cannot select font 'C'
>     ...
>     Line 576 e.g., reads "\fCpreamble"
> 
> I guess I don't have the groff version that generates those warnings,
> since I don't see them.  I changed them to \f(CW (r78683), but I don't
> know if that helps (new version attached so you can try it if you
> want).

Maybe I can shed some light.

First, the foregoing is a warning, not a behavior change.  Previous
versions of groff weren't able to "select font 'C'" either, albeit they
uttered no complaint.

Second, this is not a syntax error.  `\fC` is valid syntax.  The problem
is that the formatter cannot honor the request that is being made of it.
No font "C" exists to select.

The inputs

  \fZpreamble

  \f(QJpreamble

and

  \f[MY-BOGUS-FONT]preamble

...would encounter similar difficulty.

I can reproduce the problem with my working copy of groff, which
previews groff 1.25 and offers a little more information.

$ nroff --version | head -n 1
GNU nroff (groff) version 1.24.1.402-374b0-modified
$ zcat $(man -w makeindex) | nroff -man -z
troff:<standard input>:576: error: cannot open font description file 'C': No 
such file or directory
troff:<standard input>:576: warning: cannot select font 'C' [-w font]
...
troff:<standard input>:1122: warning: cannot select font 'C' [-w font]

The second warning repeats many times, so I abbreviated the output.
(The initial error message does not appear in released versions of
groff.  For inside baseball, see below.[4])

> I'm not sure if "\f(CW" is the right way to switch to a monospaced
> font, or if in fact there is any portable way to do so at all, with or
> (preferably) without making new definitions. 
> 
>     https://savannah.gnu.org/bugs/?64594

There is no completely portable way to select a monospaced typeface when
using the man(7) macros.  The package was not designed to do so, and
attempting it makes little sense on a terminal device regardless.  Fonts
used by terminal emulators tend to be monospaced anyway because the
rendering model of ECMA-48 presumes a grid of character cells.[1]

Also in AT&T troff, there's no way for a document to define, rename,
alias, or remove a font name, and no way to test for a font's existence.
It seems that AT&T troff regarded fonts as elements of the rendering
device's hardware, and so exposed little programming interface to them.

> It would be helpful if the groff manual, or that bug, or anywhere at
> all, just said what to do. Maybe I missed it.  I looked at a bunch of
> the links off that bug report and looked through the manual, but could
> not make out a comprehensible answer.

I'm sorry to hear that groff's documentation let you down; I've spent
considerable effort on it over the years.

groff's Texinfo manual does not cover macro packages, preprocessors, or
output drivers in detail, except for the "ms" package.[0]  groff_man(7)
and its big brother groff_man_style(7) attempt to exhaustively present
the "man" macro package, the latter with additional material to aid
people who are new to *roff or don't use it frequently.

Here's some applicable material.  It's changed little if at all from
that in the groff 1.24.0 release, made on 28 February.  (I made a small
bug fix release, 1.24.1, 2 weeks later.)

groff_man_style(7):
   Fundamental concepts
     groff is a programming system for typesetting: we thus often use
     the verb “to set” in the sense “to typeset”.  ...
     ...  The formatter prepares output for terminals or for more
     capable typesetters that can change the type size and font family.
...
   Macro reference preliminaries
     A tagged paragraph describes each macro.  We present coupled pairs
     together, as with EX and EE. ...
     ... We identify some macros
     as extensions to the set originally implemented.  They are not
     supported everywhere; see subsection “Use of extensions” below.
...
   Document structure macros
     Document structure macros organize a man page’s content. ...
     Many technical discussions benefit from examples; lengthy ones,
     especially those reflecting multiple lines of input to or output
     from the system, are usefully bracketed by EX and EE. ...
...
     .EX
     .EE    Begin and end example.  After EX, filling is disabled (and,
            on typesetters, a monospaced font family is selected).
            Calling EE enables filling (and restores the previous
            family).

            Example regions are useful for formatting code, shell
            sessions, and text file contents.  An example region is not
            a “literal mode” of any sort: special character escape
            sequences must still be used to produce correct glyphs for
            ', -, \, ^, `, and ~ (see subsection “Portability” below).
            Sentence endings are still detected and supplemental inter‐
            sentence space applied.  If the amount of supplemental
            inter‐sentence spacing is altered, the rendering of, for
            instance, regular expressions using . or ? followed by
            multiple spaces can change.  Use the dummy character escape
            sequence \& before the spaces.

            Ninth Edition Unix introduced the EX and EE extensions.
            Documenter’s Workbench (DWB), Heirloom Doctools, and Plan 9
            troffs, and mandoc (since 1.12.2) support them.  Solaris
            troff does not.
...
   Font style macros
     The man macro package is limited in its font styling options,
     offering only bold (B), italic (I), and roman.  Italic text may
     instead render underscored on terminals. ...
...
   Portability
...
     In roff systems, elemental functions called requests and escape
     sequences control formatting operations.  A request appears on a
     control line.  An escape sequence starts with a backslash (\) and
     can appear almost anywhere.  However, use of roff requests (apart
     from the empty request “.”) risks poor rendering when a page is
     processed by non‐roff formatters that attempt to interpret page
     sources.  (Historically, this was commonly attempted for HTML
     conversion.)  Many of these programs don’t interpret the full roff
     language (let alone extensions): they may be incapable of handling
     numeric expressions, control structures, or register, string, and
     macro definitions, causing a document’s contents to be presented
     incomprehensibly or omitted entirely.  If your document uses
     formatter requests, or escape sequences not shown below, it accepts
     responsibility for restoring formatter state to what the man macro
     package expects.
...
     \fB, \fI, \fR, \fP
               Switch to bold, italic, roman, or back to the previous
               style, respectively.  Either \f or \c is needed when
               three different font styles are required in a word.

                      .RB [ \-\-reference\-dictionary=\fI\,name\/\fP ]

                      .RB [ \-\-reference\-dictionary=\c
                      .IR name ]

               Style escape sequences may be more portable than \c.  As
               shown above, it is up to you to account for italic
               corrections with “\/” and “\,”, which are themselves GNU
               extensions, if desired and if supported by your
               implementation.

               \fP reliably returns to the style in use immediately
               preceding the previous \f escape sequence only if no
               sectioning, paragraph, example, or style macro calls have
               intervened.

               As long as at most two styles are needed in a word, style
               macros like B and BI usually result in more readable roff
               source than \f escape sequences do.
...
   Use of extensions
     To ensure that your man page formats reliably on a wide variety of
     viewers, write it solely with the macros described in this page
     (except for the ones identified as deprecated, which you should
     avoid).  Macros described as extensions might be unsupported by a
     formatter that is important to your audience.  Nevertheless,
     groff’s extensions are present because they perform tasks that are
     otherwise difficult or tedious to achieve portably.  If you require
     an extension but expect your man page to be rendered on a system
     that doesn’t support it, write a configuration test to measure a
     property of the system, and use m4(1), sed(1), or a similar tool to
     generate a .man file from a .man.in file, defining page‐local
     versions of extension macros only where necessary.  You can copy
     extension macro definitions from groff; see an-ext.tmac in section
     “Files” below.
...
Files
...
     /home/branden/groff-HEAD/share/groff/1.24.1/tmac/an-ext.tmac
            Definitions of macros described above as extensions (and not
            deprecated) are contained in this file; in some cases, they
            are simpler versions of definitions appearing in an.tmac,
            and are ignored if the formatter is GNU troff.  They are
            written to be compatible with AT&T troff and permissively
            licensed——not copylefted.  To reduce the risk of name space
            collisions, string and register names begin only with “m”.
            We encourage man page authors who are concerned about
            portability to legacy Unix systems to copy these definitions
            into their pages, and maintainers of troff implementations
            or work‐alike systems that format man pages to re‐use them.
            To ensure reliable rendering, define them after your page
            calls TH; see the discussion of andoc.tmac above.  Further,
            it is wise to define such page‐local macros (if at all)
            after the “Name” section to accommodate timid makewhatis(8)
            or mandb(8) implementations that easily give up scanning for
            indexing material.

> I'm going to take it on myself to cc Branden (hi Branden, Hille's
> original report is at
> https://tug.org/pipermail/tex-k/2026-April/004303.html), since I see
> he was trying to help on some of these related bug reports, and we've
> exchanged a bunch of mail on Automake in the past.

Thanks, Karl.

In a nutshell the problems with `\fC` are that (1) it never accomplishes
anything on any terminal device anywhere and (2) even on typesetter
devices, it frequently does nothing because there is no such thing as a
portable font name in *roff, beyond "R", "I", and "B", because (a) the
sole target device for the original troff (Ossanna troff) was the
Graphic Systems Inc. CAT-4, which had only four font mounting positions
and no concept of font "families", and (b) when Brian Kernighan
developed device-independent troff in about 1980, he did not establish
or demand a consistent font name list or naming scheme that would apply
across multiple output devices.  Divergent practices arose organically
at various sites.

Do you think it would help if I added the foregoing paragraph to to the
"Notes" section of groff_man_style(7), given that is serves as a kind of
"man FAQ"?

groff_man_style(7):

Notes
     Some tips on composing and troubleshooting your man pages follow.

     • What’s the difference between a man page topic and identifier?
...
     • Some ASCII characters look funny or copy and paste wrong.
...
     • Do I ever need to use an empty macro argument ("")?
...
     • RS doesn’t indent relative to my indented paragraph.
...
     • RE doesn’t move the inset back to the expected level.
...
     • Do I need to keep typing the indentation in a series of IP calls?
...
     • Why doesn’t the package provide a string to insert an ellipsis?
...
     • When and how should I use quotation marks?
...
     • Escape sequences of the form \[xx] don’t format correctly.

Maybe something more general, like "how do I shut up warnings?" would
find more favor.

And/or I can add a sentence to the discussion of `\f` escape sequences
like the following.

     \fB, \fI, \fR, \fP
...
               Only the escape sequences shown are dependable.  Others,
               such as \fC, are not portable, meaningless on terminal
               devices, and can prompt warnings from GNU troff(1).

...something like that, maybe?  `\fC` is worth calling out specifically
since it's shockingly popular for a specimen of ineffectual syntax.

> P.S. Obligatory compatibility remark: Seems to me it would have been
> better if groff simply hadn't started emitting those warnings and
> causing lots of busy maintainers to have to spend time and effort on
> "fixing" documents that worked perfectly well, regardless of the
> pedantically-correct nature of the warning. But what do I know.

I sort of get it, but consider the flip side; historically, there was no
way, beyond manual auditing of *roff document source code by a domain
expert, to uncover these problems if one _did_ want to.

My goal in improving groff's diagnostic messages (and increasing the
variety of them) is not to make people jump through hoops but to enable
those who _desire_ to clean up problems to do so.

(This conflict reminds me of the Great Hyphen-Minus Debacle.[2]  I get
the impression that people who don't care about man pages feel that no
one else should either, or are unaware that GNU troff has supported an
`-E` option as a means of shutting it up for over 35 years.[3])

As shown above, I plan for groff 1.25 to disclose the name of the
category that governs each warning the GNU troff formatter emits.  (It
finally occurred to me to rip this idea off from GCC.)

To wrap up, users of man-db man(1) can do any of the following:

export MANROFFOPT=-Wall
export MANROFFOPT=-Ww
export MANROFFOPT=-E

...as appropriate to their level of tolerance for diagnostic messages
while formatting man pages.  See man(1) and the "Warnings" section of
troff(1) for background.

Regards,
Branden

[0] ...a situation that one prominent groff contributor and ms(7)
    non-advocate would like to see end.

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

    (Good news, Dave--I have a new idea for Chapter 4.  Remind me to
    update the ticket with my "gallery" idea.)

[1] If motions or glyphs of dimensions other than a unit in either
    direction are meaningful, the concepts of "row" and "column",
    fundamental to cursor addressing, become more complicated to define.
    Observe the many bugs and difficulties arising from libraries and
    applications attempting to support "bi-width" rendering, as required
    by Unicode "half-width" and "full-width" forms when rendering CJK
    code points on a terminal display.  The change logs of ncurses and
    xterm are instructive on this point.

[2] https://lwn.net/Articles/947941/

[3] groff(1):

Options
...
     -E       Inhibit troff error messages; implies -Ww.

   
https://minnie.tuhs.org/cgi-bin/utree.pl?file=Net2/usr/src/usr.bin/groff/troff/input.cc

   Search for "case 'E'".

[4] Regarding this:

$ nroff --version | head -n 1
GNU nroff (groff) version 1.24.1.402-374b0-modified
$ zcat $(man -w makeindex) | nroff -man -Wall -z
troff:<standard input>:576: error: cannot open font description file 'C': No 
such file or directory

...I see that that error message, which is so new that I haven't even
pushed it to Savannah Git yet, remains troublesome.  I'll either have to
revert the change that activated it, or make it silent in "nroff mode",
which will take some effort because "libgroff", which houses the code,
doesn't know anything about "nroff mode"--that's a formatter-only
concept, and "libgroff" is shared among almost all groff programs.

Attachment: signature.asc
Description: PGP signature

Reply via email to