Hi Guillem,

I recently encountered the following commit log message of yours to a
libbsd repository.[1]

commit 58474628790a4d63956e389c5f7489944a3bdf1f
Author:     Guillem Jover <[email protected]>
AuthorDate: Sun May 17 23:01:52 2026 +0200
Commit:     Guillem Jover <[email protected]>
CommitDate: Mon May 18 04:56:59 2026 +0200

    man: Disable hyphenation globally for all man pages

    There is no place for hyphenation in a technical document. Unfortunately
    groff insists on hyphenating words that are known to be technical terms
    such as in .Xr, or .Fn, etc. Where groff upstream suggests that those
    words need to be marked up with things like \%, which looks like
    unnecessary busy work.

    The current workaround requires to use low-level troff markup to
    globally disable hyphenation with groff, which is less than ideal, but
    the best known option available.

Permit me to unpack the foregoing.

> There is no place for hyphenation in a technical document.

I wonder how many technical documents you consulted before venturing
this proclamation.  Here are some technical documents that employ
hyphenation.  I trust that you don't find them obscure.

1.  Kernighan, B. and Ritchie, D.  The C Programming Language, 2nd
    edition.  Prentice-Hall, 1988.  See pp. ix-xi, 1-4, etc.

2.  Knuth, D.  The Art of Computer Programming, Volume 1: Fundamental
    Algorithms, 3rd edition.  Addison-Wesley, 1997.  Second digital
    release, 2016.  See pp. v-vi, vii-xi, xv-xvi, 2-5, 7-10, etc.

3.  Cormen, T. H.; Leiserson, C. E.; Rivest, R. L.; and Stein, C.
    Introduction to Algorithms, 3rd edition.  MIT Press, 2009.  See pp.
    xiii-xix, 3-10, etc.

4.  Brooks, F. P., Jr.  The Mythical Man-Month, 20th anniversary
    edition.  Addison-Wesley, 1995.  See pp. vii-xii, 4, 6-9, 14-17,
    etc.

5.  Aho, A. V.; Lam, M. S.; Sethi, R.; and Ullman, J. D.; Compilers:
    Principles, Techniques, & Tools, 2nd edition.  Addison-Wesley, 2007.
    See pp. vi, vii, 1-5, 8-10, etc.

6.  Anderson, R.  Security Engineering, 2nd edition.  Wiley, 2008.  See
    pp. xxx-xxxiii, xxxvi, 1, 3-4, 6-11, etc.

7.  Sipser, M.  Introduction to the Theory of Computation.  PWS
    Publishing, 1997.  See xi-xv, 1-4, 7-10, etc.

8.  Silberschatz, A.; Galvin, P. B.; and Gagne, G.  Operating System
    Concepts, 8th edition.  Wiley, 2010.  See pp. vi, x-xii, 1, 13,
    16-19, etc.

9.  DeMarco, T. and Lister, T.  Peopleware: Productive People and Teams.
    Dorset House, 1987.  See pp. ix-x, 1, 3-5, 7-8, 10, etc.

10. Schneier, B.  Applied Cryptography: Protocols, Algorithms, and
    Source Code in C.  20th anniversary edition.  Wiley, 2015.  See pp.
    xiii-xiv, xvii-xxv, 1-10, etc.

In two of these,[2] the very first line of the preface is hyphenated.
Further, I ignored cases of explicit hyphens, as in phrases like
"short-term" or "Solaris-related", or in compound surnames like
"Piggott-Smith".  That leaves words that were, I suppose, automatically
hyphenated, as with "com·puting", "run·ning", "vol·ume", or
"environ·ment".

I therefore challenge you to defend your claim, or withdraw it.

> Unfortunately groff insists on hyphenating words that are known to be
> technical terms

Known to whom?

> such as in .Xr, or .Fn, etc.

If you're saying that the semantics of a macro supply enough context for
the macro package itself to suppress automatic hyphenation in its
arguments--in mdoc(7)'s case, until reading another "callable" macro, at
any rate,[3]--that is indeed a possibility, and one that I explored
successfully when implementing the new `MR` man(7) macro for groff 1.23
(2023).

groff_man(7):

     .MR topic [manual‐section [trailing‐text]]
            (since groff 1.23) Set a man page cross reference as
            “topic(manual‐section)”.  If manual‐section is absent, the
            package omits the surrounding parentheses.  If trailing‐text
            (typically punctuation) is specified, it follows the closing
            parenthesis without intervening space.  Hyphenation is
            disabled while the cross reference is set.  topic is set in
            the font specified by the MF string.  If manual‐section is
            present, the cross reference hyperlinks to a URI of the form
            “man:topic(manual‐section)”.

And in fact groff_mdoc's `Xr` macro already does that.[3]  However, `Fn`
does not, and so I interpret your commit log as a bug report to that
effect.  I'll file an appropriate  Savannah ticket against groff.

> Where groff upstream suggests that those words need to be marked up
> with things like \%, which looks like unnecessary busy work.

Yes.  Another--likely much less tedious--approach involves using the
`hw` request to declare a man page's hyphenation exception words within
the document.  (Or, in source maintenance, an entire project's list of
hyphenation exception words could be kept in a single file and `so`urced
into the installed version of the man page.  Ingo Schwarze, the
mandoc(1) maintainer, and I would both discourage shipping a populated
man page with `so` requests in it, since there is no convention for
locating such auxiliary *roff files on the file system.  Further, Ingo
is of the opinion that `so` is an inherent security risk in any
application, as I recall.

One in fact sometimes sees man pages, even very old ones, with `hw`
requests in them for this exact purpose.  The practice never caught
on, however.  Possibly that's because even that much less demanding
practice was widely regarded as busy work, too.  But even if it wasn't,
technical limitations made AT&T troff's hyphenation word exception
feature incompletely satisfying in man pages.

First, there was no way to clear the list of hyphenation exception
words, as you might want to do when rendering multiple man pages.  A man
page from project A should not be able to mess up the hyphenation of
words in a man page from project B.

Second, groff_diff(7) notes a worse problem.

     ... Some versions of troff
     reserved meager storage for hyphenation exception words (arguments
     to the hw request); ...

These two limitations created negative synergy; if the formatter ran out
of room for hyphenation exception words, an `hw` request could become
futile, and there was no way to recover any of the memory before the
program exited.  For decades, GNU troff has used dynamically allocated
storage for hyphenation exception words, so it is practically impossible
to run out of room for them.

Better still, the forthcoming groff 1.25 solves the other half of the
problem.

NEWS:

*  A new request, `rhw`, removes user-defined hyphenation exception
   words from the current hyphenation language's list thereof.  Those
   supplied by files like "tmac/hyphenex.{cs,en,pl}" are retained.

A man page that does not require portability to the AT&T troff family
therefore can start leveraging this feature, avoiding...

> unnecessary busy work.

...thus.

> The current workaround requires to use low-level troff markup to
> globally disable hyphenation with groff,

Your technique is to inject `.nr HY 0` requests into every man page.

diff --git a/man/TIMESPEC_TO_TIMEVAL.3bsd b/man/TIMESPEC_TO_TIMEVAL.3bsd
index 28ebcf4..5ff2722 100644
--- a/man/TIMESPEC_TO_TIMEVAL.3bsd
+++ b/man/TIMESPEC_TO_TIMEVAL.3bsd
@@ -30,6 +30,7 @@
 .Dd April 12, 2011
 .Dt TIMEVAL_TO_TIMESPEC 3bsd
 .Os
+.nr HY 0
 .Sh NAME
 .Nm TIMEVAL_TO_TIMESPEC ,
 .Nm TIMESPEC_TO_TIMEVAL
diff --git a/man/arc4random.3bsd b/man/arc4random.3bsd
index 7205f44..fd9c845 100644
--- a/man/arc4random.3bsd
+++ b/man/arc4random.3bsd
@@ -30,6 +30,7 @@
 .Dd November 16, 2014
 .Dt arc4random 3bsd
 .Os
+.nr HY 0
 .Sh NAME
 .Nm arc4random ,
 .Nm arc4random_uniform ,
...

That technique will fail in the forthcoming groff 1.25, at least for
man(7) documents.[4]  I'll need to double-check that it does for mdoc(7)
as well--thank you for the reminder!

The `HY` register is a user-facing feature.  It is to be used by the
_reader_ of man pages, **not** by man page authors.

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.
...
     -rHY=0   Disable automatic hyphenation.  Normally, it is
              enabled (1).  The hyphenation mode is determined by the
              groff locale; see section “Localization” of groff(7).

groff_mdoc(7):

Options
     The following groff options set registers (with -r) and strings
     (with -d) recognized and used by the mdoc macro package.  To ensure
     rendering consistent with output device capabilities and reader
     preferences, man pages should never manipulate them.
...
     Normally, automatic hyphenation is enabled using a mode appropriate
     to the groff locale; see section “Localization” of groff(7).  It
     can be disabled by setting the ‘HY’ register to zero.
           groff -Tutf8 -rHY=0 -mdoc foo.man | less -R

> which is less than ideal, but the best known option available.

If you dislike automatic hyphenation, the best option available is to
deconfigure it on your system.

groff_man_style(7):

Files
...
     /etc/groff/man.local
            Put site‐local changes and customizations into this file.

                   .\" Put only one space after the end of a sentence.
                   .ss 12 0 \" See groff(7).
                   .\" Keep pages narrow even on wide terminals.
                   .if n .if \n[LL]>80n .nr LL 80n

            On multi‐user systems, it is more considerate to users whose
            preferences may differ from the administrator’s to be less
            aggressive with such settings, or to permit their override
            with a user‐specific man.local file.  Place the requests
            below at the end of the site‐local file to manifest
            courtesy.
                   .soquiet \V[XDG_CONFIG_HOME]/man.local
                   .soquiet \V[HOME]/.man.local
            However, a security‐sandboxed man(1) program may lack
            permission to open such files.

You should add...

.nr HY 0

...to that file if you want, _not_ to man page source documents that you
distribute to the public.

I predict that you will not receive many complaints about undesirably
hyphenated literals in man pages you maintain.  If you do, you can
suggest the same advice to the people making them.  If your readers
prefer automatic hyphenation but object only to its inappropriate
application, then they are the perfect people to contribute patches that
resolve the problems they observe.

Crowdsourcing a task that you find tedious and unrewarding is a superior
solution to frustrating the ability of others to work on it.

Principle #3 of the Debian Social Contract is sage and broadly
applicable advice: "We will not hide problems."

Leaving problems unconcealed is a superior approach to inventing easily
disproved claims about the craft of technical writing.

Regards,
Branden

[1] https://gitlab.freedesktop.org/libbsd/libbsd.git
[2] Knuth and CLRS

[3] Exhibit:

$ cat ATTIC/hyphenation.mdoc
.Dd 2026-09-19
.Dt foo 1
.Os "groff test suite"
.Sh Name
.Nm foo
.Nd frobnicate a bar
.Sh Description
.hw super-user
.Nm
performs the inverse operation of
.Xr bar 1 , which the friendly administrator can run .
.Pp
.Nm
performs the inverse operation of
.Xr bar 1 ,
which the friendly administrator can run.
Internally,
it invokes the
.Ox No function
.Fn zotzotzotzotzot "int luser-id" .
Goodbye,
man page reader!
$ nroff -mdoc ATTIC/hyphenation.mdoc
foo(1)                       General Commands Manual                      foo(1)

Name
     foo —— frobnicate a bar

Description
     foo   performs   the  inverse  operation  of  bar(1),  which  the  friendly
     administrator can run.

     foo performs the inverse operation of bar(1), which the  friendly  adminis‐
     trator  can run.  Internally, it invokes the OpenBSD function zotzotzotzot‐
     zot(int luser‐id).  Goodbye, man page reader!

groff test suite                   2026‐09‐19                             foo(1)

Observe that "administrator" does not hyphenate when it appears as an
argument to mdoc(7)'s `Xr` macro, but does hyphenate when occurring on
an ordinary text line.

[4]

commit 0d5a8fe5db117f3392fa74cb4c228db79c05443f
Author: G. Branden Robinson <[email protected]>
Date:   Tue Jul 15 22:35:05 2025 -0500

    [man]: Fix Savannah #67363 (1/4).

    Make man page rendering more robust against meddling with the
    hyphenation mode by individual pages.  In part this is to ensure that
    meddling doesn't persist outside the meddlesome document when rendering
    multiple pages, but it also makes user preferences more reliably
    discernible.  Prompted by a discussion (about adjustment) with Russ
    Allbery in late 2023.

    * tmac/an.tmac ([initialization]): When rendering a man page, this macro
      file is read before any man(7) document: track man/mdoc initialization
      status in new register `andoc*is-initialized`.  When initializing, if
      the `HY` register is set, we know it was specified on the command line
      or by the "man.local" file.  Stash its value in new register
      `andoc*HY` so it can be recovered after meddling by the document.

      (an*reset-hyphenation-mode): Accept an argument, and if valid, assign
      its value to the `HY` register.

      (TH): Remove the potentially page-local `HY` register when starting a
      new document, and call `an*reset-hyphenation-mode` interpolating
      `andoc*HY` as an argument to impose the user's preference (or the
      package default) at each new document.

    * tmac/tests/an_hyphenation-mode-restoration-works.sh: Add test to
      verify preservation of document- and user-selected hyphenation mode.
    * tmac/tmac.am (tmac_TESTS): Run test.

    Fixes <https://savannah.gnu.org/bugs/?67363> (1/4).  Thanks to Russ
    Allbery for posing the challenge.

Attachment: signature.asc
Description: PGP signature

Reply via email to