I've root-caused the problem; expect a fix in my next push.

At 2025-10-28T20:48:12+0100, onf wrote:
> On Tue Oct 28, 2025 at 8:00 PM CET, Ingo Schwarze wrote:
> > so i also tested with one of the strings predefined by manual page
> > macro sets: \*(Ba prints a vertical bar as expected, but a macro
> > argument "Ba" prints simply "Ba" rather than a vertical bar.
> > So the bug seems unique to .T.
> > [...]
> 
> That is interesting. I assumed this bug would be due to groff doing
> something like
>   .if d\\$1
> without differentiating between mdoc macros and the rest.

It does do something like that.  The problem is not that a `.T` string
exists, but that a `.T` _register_ _also_ exists.

commit 897acc5fcd06ee91127185619d33bd90a22dee6e
Author:     G. Branden Robinson <[email protected]>
AuthorDate: Wed Oct 29 05:52:10 2025 -0500
Commit:     G. Branden Robinson <[email protected]>
CommitDate: Wed Oct 29 06:02:18 2025 -0500

    [mdoc]: Fix Savannah #67646 (`.T` as macro arg).

    * tmac/doc.tmac (doc-get-arg-type*): Handle the *roff internal string
      '.T' specially in an mdoc macro argument sequence; it is defined in
      the formatter, which _also_ defines a '.T' _register_, colliding
      perfectly with mdoc's argument type system.  This change prevents `.T`
      from being called as a macro and interpolating its value, a surprising
      outcome to mdoc users.

    Fixes <https://savannah.gnu.org/bugs/?67646>.  Thanks to onf for the
    report.  Problem dates back "all the way"; not only does groff 1.22.3
    (November 2014) have it, but the 4.4BSD-Lite2 implementation of mdoc
    does as well.  mdoc as a *roff macro package implements its own bespoke
    type system to accompany its bespoke macro processor; the type of a
    macro argument (a string or macro) is determined by looking up its name
    as a _register_.  mandoc(1) does not exhibit this problem, likely
    because it lacks a *roff formatter that defines both a `.T` register and
    a `.T` string; rather it simulates both of these.

...

diff --git a/tmac/doc.tmac b/tmac/doc.tmac
index 47064f9c6..6f61f45d8 100644
--- a/tmac/doc.tmac
+++ b/tmac/doc.tmac
@@ -2644,10 +2644,17 @@ .de doc-get-arg-type*
 .      if r doc-punct\*[doc-arg\$1] \
 .        nr doc-arg-type \n[doc-punct\*[doc-arg\$1]]
 .    \}
-.    el \
-.      if r \*[doc-arg\$1] \
-.        if d \*[doc-arg\$1] \
-.          nr doc-arg-type 1
+.    el \{\
+.      \" Handle the *roff internal string '.T' specially; it is defined
+.      \" in the formatter, which _also_ defines a '.T' _register_,
+.      \" colliding perfectly with mdoc's argument type system.
+.      ie !'\?\*[doc-arg\$1]\?'\?.T\?' \
+.        if r \*[doc-arg\$1] \
+.          if d \*[doc-arg\$1] \
+.            nr doc-arg-type 1
+.      el \
+.        nr doc-arg-type 2
+.    \}
 .  \}
 ..
 .ec

Regards,
Branden

Attachment: signature.asc
Description: PGP signature

Reply via email to