URL:
  <https://savannah.gnu.org/bugs/?68133>

                 Summary: nail down semantics of character translations
involving non-characters
                   Group: GNU roff
               Submitter: gbranden
               Submitted: Mon 09 Mar 2026 12:05:07 AM UTC
                Category: Core
                Severity: 3 - Normal
              Item Group: None
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Unlocked
         Planned Release: None


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: Mon 09 Mar 2026 12:05:07 AM UTC By: G. Branden Robinson <gbranden>
Item Group unknown at this time.

In 1991,
[https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/troff/input.c?h=1.04#n4265
James Clark called character translations a "really bizarre troff feature",]
and I agree.

* Are translations to space escape sequences like \| and \^ permitted?

* The foregoing two are permitted to be defined as glyphs in a font in
Kernighan's device-independent _troff_ (though at the moment I cannot spot
this provision in CSTR #54 1992).  But what about the other fixed-width space
escape sequences, \space and \0?

* What about _groff_'s "stretchable" space escape sequence, \~?  (See bug
#65829.)

* Are translations to _parameterized_ space escape sequences (such as \h'1i')
permitted?

* Are translations _from_ any of the foregoing to ordinary, spacing, or
indexed characters permitted?

* Are translations from one kind of space escape sequence to another
permitted?

Existing implementations are inconsistent.  (However, DWB 3.3 and Plan 9 from
User Space _troff_s appear to be consistent with each other.)



$ cat ATTIC/stupid-tr-tricks.roff 
.nf
.tr !\|
abc!def
.tr #\^
ghi#jkl
.tr $\ 
mno$pqr
.tr %\0
stu%vwx
.if \n(.g \{\
.tr &\~
yz_&abc
.\}
.tr +\h'1i'
def+ghi
.tr !!##$$%%&&++
.tr \|!
def\|ghi
.tr \^#
jkl\^mno
.tr \ $
pqr\ stu
.tr \0%
vwx\0yz_
.if \n(.g \{\
.tr \~&
ABC\~DEF
.\}
.tr \h'1i'+
GHI\h'1i'JKL
$ dwb nroff  ATTIC/stupid-tr-tricks.roff | cat -s
abc def
ghi jkl
mnopqr
stu%vwx
def+ghi
defghi
jklmno
pqr$stu
vwx yz_
GHI          JKL

$ 9 nroff  ATTIC/stupid-tr-tricks.roff | cat -s
abc def
ghi jkl
mnopqr
stu%vwx
def+ghi
defghi
jklmno
pqr$stu
vwx yz_
GHI          JKL


$ heirloom nroff  ATTIC/stupid-tr-tricks.roff | cat -s
abc\def
ghi\jkl
mnopqr
stu\vwx
def\g'i
defg'i
jklmno
pqr$stu
vwx yz_
GHI          JKL

$ ~/groff-1.22.3/bin/nroff ATTIC/stupid-tr-tricks.roff | cat -s
ATTIC/stupid-tr-tricks.roff:2: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:4: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:6: normal or special character expected (got `\
')
ATTIC/stupid-tr-tricks.roff:8: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:14: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:17: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:19: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:21: normal or special character expected (got `\
')
ATTIC/stupid-tr-tricks.roff:23: normal or special character expected (got a
horizontal space)
ATTIC/stupid-tr-tricks.roff:26: normal or special character expected (got
`\~')
ATTIC/stupid-tr-tricks.roff:29: normal or special character expected (got a
horizontal space)
abc!def
ghi#jkl
mno$pqr
stu%vwx
yz_ abc
def+ghi
defghi
jklmno
pqr stu
vwx yz_
ABC DEF
GHI          JKL

$ ~/groff-1.22.4/bin/nroff ATTIC/stupid-tr-tricks.roff | cat -s
troff: ATTIC/stupid-tr-tricks.roff:2: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:4: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:6: normal or special character expected
(got '\ ')
troff: ATTIC/stupid-tr-tricks.roff:8: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:14: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:17: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:19: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:21: normal or special character expected
(got '\ ')
troff: ATTIC/stupid-tr-tricks.roff:23: normal or special character expected
(got a horizontal space)
troff: ATTIC/stupid-tr-tricks.roff:26: normal or special character expected
(got '\~')
troff: ATTIC/stupid-tr-tricks.roff:29: normal or special character expected
(got a horizontal space)
abc!def
ghi#jkl
mno$pqr
stu%vwx
yz_ abc
def+ghi
defghi
jklmno
pqr stu
vwx yz_
ABC DEF
GHI          JKL

$ ~/groff-1.23.0/bin/nroff ATTIC/stupid-tr-tricks.roff | cat -s
troff:ATTIC/stupid-tr-tricks.roff:2: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:4: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:6: error: expected ordinary or special
character, got an escaped ' '
troff:ATTIC/stupid-tr-tricks.roff:8: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:14: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:17: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:19: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:21: error: expected ordinary or special
character, got an escaped ' '
troff:ATTIC/stupid-tr-tricks.roff:23: error: expected ordinary or special
character, got a horizontal motion
troff:ATTIC/stupid-tr-tricks.roff:26: error: expected ordinary or special
character, got an escaped '~'
troff:ATTIC/stupid-tr-tricks.roff:29: error: expected ordinary or special
character, got a horizontal motion
abc!def
ghi#jkl
mno$pqr
stu%vwx
yz_ abc
def+ghi
defghi
jklmno
pqr stu
vwx yz_
ABC DEF
GHI          JKL



_groff_ 1.24.0 aborts on this input with an assertion failure (bug #68132),
but once I've commented that out I expect it to behave as _groff_ 1.23.0.

At present, I propose to **BAN ALL THIS CRAP** by default (someone light the
John Gardner bat-signal), and exile to compatibility mode only that which is
required to support rendering of historical documents.

Character translations are for _translating_ *_characters_*.

If you want to _redefine_ characters, _groff_ has various `char` requests for
that.

(Also I want to make character translations a property of the environment; see
bug #62691.)

(And I didn't even cover the `.tr ~` "feature", a stupid trick along an
orthogonal axis...)







    _______________________________________________________

Reply to this item at:

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

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

Attachment: signature.asc
Description: PGP signature

Reply via email to