[Top][All Lists]

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

adjustment and hyphenation in mdoc(7) pages

From: G. Branden Robinson
Subject: adjustment and hyphenation in mdoc(7) pages
Date: Fri, 24 Mar 2023 00:55:50 -0500

Hi Alex,

At 2023-03-23T23:53:18+0100, Alejandro Colomar wrote:
> I saw yesterday something that might have to do with this.  Check the
> timespecsub(3bsd) man (actually mdoc(7)) page, and in the SYNOPSYS
> you'll find some weird filled function prototypes.  I tried adding
> hyphens to them, to see if it would break there, and it breaks, even
> on the terminal!
> Here's a small reproducer of this issue (which might have to do with
> the one reported by Brian, or might be a different one):
> $ cat timespecsub.3 
> .Dd June 7, 2010
> .Dt timeradd 3bsd
> .Os
> .Sh NAME
> .Nm timespecsub
> .Nd operations on time structure
> .Ft void
> .Fn timespecsub "struct-timespec *a" \
> "struct-timespec *b" "struct-timespec *res"

This issue isn't related to the one Brian reported except insofar as
man(7) and mdoc(7) are two macro packages with a very similar purpose
trying to do nearly the same thing.  Therefore there is room for
independent bugs in each implementation.

I can reproduce the problem.  In groff Git what is also noticeable
is that groff mdoc(7) now adjusts to both margins by default as is
historically correct for man pages.  (Yes, you can turn this off; see

But it is not correct to do this in synopsis sections.  When I enabled
both-margin adjustment for mdoc(7) in the 1.23.0 development cycle I
neglected to handle this.  So that's unfortunately a regression (or
exposure of a latent bug) from groff 1.22.4.  (I didn't notice because I
don't test a corpus of mdoc(7) test documents apart from groff_mdoc(7),
which _does_ exercise nearly every mdoc(7) macro that exists--its
original purpose is in part exercising the package--but doesn't have a
lengthy synopsis.)  Time for a regression test.

$ ./build/test-groff -mandoc -Tascii ATTIC/timespecsub.mdoc
timeradd(3bsd)                       LOCAL                      timeradd(3bsd)

       timespecsub -- operations on time structure

       timespecsub(struct-timespec    *a,    struct-timespec    *b,    struct-
           timespec *res);

GNU                              June 7, 2010                   timeradd(3bsd)

I conclude that mdoc(7) synopses rendered by groff need to do what
groff's man(7) rendering is already doing: disable hyphenation and
adjust to the left margin only.

Please find a patch attached--it fixes adjustment for me; how about you?

But it doesn't solve the problem you reported.  That is because even
with hyphenation "off", hard hyphens are still considered eligible break
points because that is part of all *roff behavior everywhere, going back
forever.[1]  It is not, I gather, mandoc(1) behavior, though, and it is
mandoc(1) users who are predominantly concerned with mdoc(7) rendering.

This means that mdoc(7) authors will need to learn a habit that is often
neglected by their man(7) rivals as well:

Use the hyphenation control escape sequence wherever necessary.  It can
suppress hyphenation of _any_ word it prefixes in _any_ context.

From groff_man_style(7), forthcoming in groff 1.23.0:

  Fundamental concepts
    groff is a programming system for typesetting: we thus often use the
    verb "to set" in the sense "to typeset".  The formatter troff(1)
    collects words from the input and fills output lines with as many as
    will fit.  Words are separated by spaces and newlines.  A transition
    to a new output line is called a break.  When formatted, a word may
    be broken at hyphens, at \% or \: escape sequences (see subsection
    "Portability" below), or at predetermined locations if automatic
    hyphenation is enabled (see the -rHY option in section "Options"
    \%  Control hyphenation.  The location of this escape sequence
        within a word marks a hyphenation point, supplementing groff's
        automatic hyphenation patterns.  At the beginning of a word, it
        suppresses any automatic hyphenation points within; any
        specified with \% are still honored.

Perhaps instead:

  At the beginning of a word, it suppresses any hyphenation breaks
  within _except_ those specified with \%.

Here is a fixed version of the reproducer:

.Dd June 7, 2010
.Dt timeradd 3bsd
.Nm timespecsub
.Nd operations on time structure
.Ft void
.Fn timespecsub "\%struct-timespec *a" \
"\%struct-timespec *b" "\%struct-timespec *res"

\% is desperately underused, despite being as portable as anything is in
*roff.  Learn it, live it, love it!


[1] The reader is invited to look this one up.  Learn to fire up a V7
    Unix environment under SIMH as I have and party like it's 1979!

Attachment: signature.asc
Description: PGP signature

reply via email to

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