groff
[Top][All Lists]
Advanced

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

Re: Proposed: next-generation alignment and adjustment control


From: G. Branden Robinson
Subject: Re: Proposed: next-generation alignment and adjustment control
Date: Mon, 24 Jun 2024 21:07:17 -0500

Hi Bjarni,

I urge you to read my earlier messages in this thread carefully.  They
address every point you're making.

At 2024-06-25T00:05:40+0000, Bjarni Ingi Gislason wrote:
>   The bug is shown in the example by
> 
> .ad l 
> mno pqr\p
> .na
> stu vwx\p
> .ad
> yza bcd\p
> 
>   Result is (links, no adjustment, unchanged=previous)
> 
> yza   bcd
> 
>   instead of
> 
> yza bcd
> 
>   With my patch it is
> 
> yza bcd
> 
>   with other parts unchanged from upstream.

Yes.  This behavior is apparently what long-time nroff/troff users
expect.  That it isn't what newcomers to man page composition expect has
not, to date, motivated anyone to change the formatter's behavior.

Interpreted from that perspective,

> yza   bcd

is expected because `ad` without arguments means that "line adjustment
is begun".  When one interprets the word "adjustment" as I do, the
behavior is consistent with CSTR #54's description (and with groff's for
that matter).  CSTR #54 doesn't actually define "adjustment" at all as a
concept: it presents a table and requires a user to contrive their own
definition that fits the cases listed.  This is difficult to do.

What's weird are these behaviors:

.ad c
qrs tuv\p
.na
wxy zab\p
.ad
cde fgh\p

...which results in:

(Once again I'll invite the reader to pause and test their command of
*roff by predicting the output of the foregoing before proceeding.)

 qrs tuv
wxy zab
 cde fgh

So if "adjustment" is, as I claim, "the widening of the spaces between
words until glyphs abut both the left and right margins", well, that's
clearly not happening here.  But neither has "adjustment" "begun".

Same with right-"adjustment":

.ad r
ijk lmn\p
.na
opq rst\p
.ad
uvw xyz\p

...which yields:

  ijk lmn
opq rst
  uvw xyz

One could infer from this that `ad` without arguments means "go back to
what the previous 'adjustment' was", but as we both showed:

.ad l
mno pqr\p
.na
stu vwx\p
.ad
yza bcd\p

...which results in...

mno pqr
stu vwx
yza   bcd

...defeats that claim handily.

>   All the different implementations (also "plan9") just have the same
>   bug.

That all implementations behave the same is why you probably won't get
many *roff traditionalists to agree that it's a bug.  Formatters do
agree on this extremely quirky behavior, which I submit cannot be
rationalized coherently without circular argument.  The word
"adjustment" ends up meaning "whatever nroff/troff does when you invoke
`ad` and `na` thus".  This doesn't help people think about typography or
laying out their document; it forces them instead to ponder the
idiosyncrasies of the tool they're using.  That's intrusive--that's bad.

Here's another example, taking `na` out of the picture.

$ cat ATTIC/more-madness.roff
.pl 1v
.ll 9n
.ad l
abc def\p
.ad
ghi jkl\p
.ad c
mno prq\p
.ad
stu vwx\p
.ad r
yza bcd\p
.ad
efg hgi\p
$ /usr/bin/nroff ATTIC/more-madness.roff
abc def
ghi   jkl
 mno prq
 stu vwx
  yza bcd
  efg hgi

Under my proposal:

$ ./build/test-groff -T ascii ATTIC/more-madness.roff
abc def
ghi   jkl
 mno prq
stu   vwx
  yza bcd
efg   hgi

The status quo is indefensible nonsense.  ("Change my mind!")  I'd
prefer to make GNU troff simply do something that can be explained in
emails of less than 500 words, and warn the--apparently few--people who
use `.ad c/(.na)/.ad` and `.ad r/(.na)/.ad` sequences that their
documents' rendering will change.

A "bug fix" does not generally warrant mention in groff's "NEWS" file.
Your proposal would.  So would mine.  The difference is that mine is, in
my opinion, conceptually cleaner and objectively less disruptive to
existing documents.  `.ad l/(.na)/.ad` is a more common pattern by far
than the other two presented above, simply because `.ad c` and `.ad r`
are little-used.

Any error with sufficiently long pedigree becomes canonical, as with the
spelling of the word "island" in English.  (It once was, and should have
remained, "iland".  Even the King James Bible says so.[1]  Now _there's_
some scripture for you. 😈)

But I say no.  Once in a while we're entitled to repent of our errors...
particularly those of our forebears.

Here's a summary of what I'm pitching, in the style of groff(7).

     .ad        Enable output line adjustment.  Updates \n[.j].
     .ad b      Enable output line adjustment.  Updates \n[.j].
     .ad n      Enable output line adjustment.  Updates \n[.j].
     .ad C      Align output line to left, right, or center as C is "l",
                "r", or "c", respectively.  Updates \n[.j].
     .ad N      Configure output line alignment and adjustment per the
                integer N, which must be a valid value of the .j
                register.
     .na        Disable output line adjustment.  Updates \n[.j].

     \n[.j]         Output line alignment and adjustment encoded as an
                    integer; see .ad and .na.  Do not interpret or
                    perform arithmetic on its value.

(The numerical value of the `.j` register will change under my proposal,
but its semantics are otherwise unaltered: it would continue to work as
it always has.  The warning about not interpreting or performing
arithmetic on its value has been present since groff 1.23, and was, I
understand, folk knowledge among *roff practitioners long before that.)

I'm further considering adding two more registers.

     \n[.adjust]    Output line adjustment enablement (Boolean-valued).
                    See .ad and .na.
     \n[.align]     Output line alignment (string-valued; interpolates
                    "l", "r", or "c".  See .ad.

And I'd be happy to implement two new requests to get people out of the
`ad`/`na`/`\n(.j` quagmire altogether.

     .adjust    Enable output line adjustment.  Its is enabled by
                default.  Updates \n[.j].
     .adjust B  Enable or disable output line adjustment per Boolean
                expression B.  Updates \n[.j].
     .align C   Align output line to left, right, or center as C is "l",
                "r", or "c", respectively.  Updates \n[.j].

Each of these three tiers builds on the previous.  Just the first is
enough to suit my reformist passion, but I think the other two increase
user-friendliness in this area.

Regards,
Branden

[1] https://www.quora.com/Why-is-the-spelling-of-island-is-pronounced-as-iland

Attachment: signature.asc
Description: PGP signature


reply via email to

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