bugGNU roff - Bugs: bug #63777, explicitly document transition...

 
 

bug #63777: explicitly document transition onto first page

Submitter:  Dave <barx>
Submitted:  Thu 09 Feb 2023 07:07:16 AM UTC
   
 
Category:  Core Severity:  2 - Minor
Item Group:  Documentation Status:  Fixed
Privacy:  Public Assigned to:  gbranden
Open/Closed:  Closed Planned Release:  1.23.0
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 21 Apr 2023 08:40:12 PM UTC, comment #16: 

Thanks, Dave.  Judging by the summary of the new ticket, this one must have been a best-seller!

G. Branden Robinson <gbranden>
Group administrator
Fri 21 Apr 2023 08:37:01 PM UTC, comment #15: 

comment #14:

> Please do file a new ticket about this.


Filed as bug #64087.

Dave <barx>
Group Member
Fri 21 Apr 2023 07:37:53 PM UTC, comment #14: 

Hi Dave,

comment #13:

> Not worth reopening this bug report over, but I notice this point still isn't covered by the documentation update:
>
> comment #3:
> > A horizontal motion of zero length [...] is output, and
> > I would expect it to cause a page transition if one is in the
> > twilight zone.  And it does.
>
> Granted, the case that the manual was updated to cover (that of a break, which might be a side effect of a number of requests) is a plausible situation where one might cause an inadvertent transition to the first page, while the one you cite is...a bit contrived--but nonetheless, I think, not obvious.  Is it thus worth documenting?  Dunno, I'm on the fence about that, but I'm bringing it up to get (an)other opinion(s).


I did in fact forget about this for a while.  Please do file a new ticket about this.  I think the manual, as it gets on toward the end of the formatter reference (currently, chapter 5), needs to start discussing the distinction between formatter instructions that change the environment, those that produce output, and those that do neither (register, string, macro definitions and manipulation).

Eventually this background will better prepare the advanced groff reader to grapple with the internal "node" concept.

G. Branden Robinson <gbranden>
Group administrator
Sat 08 Apr 2023 05:54:40 AM UTC, comment #13: 

Not worth reopening this bug report over, but I notice this point still isn't covered by the documentation update:

comment #3:

> A horizontal motion of zero length [...] is output, and
> I would expect it to cause a page transition if one is in the
> twilight zone.  And it does.


Granted, the case that the manual was updated to cover (that of a break, which might be a side effect of a number of requests) is a plausible situation where one might cause an inadvertent transition to the first page, while the one you cite is...a bit contrived--but nonetheless, I think, not obvious.  Is it thus worth documenting?  Dunno, I'm on the fence about that, but I'm bringing it up to get (an)other opinion(s).

Dave <barx>
Group Member
Wed 15 Feb 2023 03:31:16 AM UTC, comment #12: 

comment #11:

> Thanks, the new wording is great!  The only detail I'd change is removing the @footnote{} tag: the sentence seems worthy of being in the primary text.


Done.  :D


commit 87d0b5e0ef2733f53a856f27c70fabac216f68cd
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Tue Feb 14 19:42:59 2023 -0600

    doc/groff.texi: Follow up Savannah #63777.

    Discuss more details of break behavior per discussion with Dave.


G. Branden Robinson <gbranden>
Group administrator
Wed 15 Feb 2023 12:58:53 AM UTC, comment #11: 

Thanks, the new wording is great!  The only detail I'd change is removing the @footnote{} tag: the sentence seems worthy of being in the primary text.

Dave <barx>
Group Member
Tue 14 Feb 2023 08:21:15 PM UTC, comment #10: 

Okay, try this.  This does a better job, I think, of confronting the common cases first and the long tail(s) later.


 @cindex @code{trf} request, causing implicit break
-A break updates the drawing position per the page offset, indentation,
-vertical spacing, and page length, interrupting filling.  Various ways
-of causing breaks were shown in @ref{Breaking}.  The @code{br} request
-likewise causes a break.  A break is implied by several other
-requests:@: @code{bp}, @code{ce}, @code{cf}, @code{fi}, @code{fl},
+When an output line is pending (see below), a break moves the drawing
+position to the beginning of the next text baseline, interrupting
+filling.  Various ways of causing breaks were shown in @ref{Breaking}.
+The @code{br} request likewise causes a break.  Several other requests
+imply breaks:@: @code{bp}, @code{ce}, @code{cf}, @code{fi}, @code{fl},
 @code{in}, @code{nf}, @code{rj}, @code{sp}, @code{ti}, and @code{trf}.
 If the no-break control character is used with any of these requests,
 GNU @code{troff} suppresses the break; instead the requested operation
 takes effect at the next break.  @samp{'br} does nothing.

 @Example
 .ll 55n
 This line is normally filled and adjusted.
 .br
 A line's alignment is decided
 'ce \" Center the next input line (no break).
 when it is output.
 This line returns to normal filling and adjustment.
     @result{} This line is normally filled and adjusted.
     @result{}    A line's alignment is decided when it is output.
     @result{} This line returns to normal filling and adjustment.
 @endExample

 @noindent
 @cindex pending output line
 @cindex partially collected line
 Output line properties like page offset, indentation, and adjustment are
 not determined until the line has been broken.  An output line is said
 to be @dfn{pending} if some input has been collected but an output line
 corresponding to it has not yet been written; such an output line is
 also termed @dfn{partially collected}.  If no output line is pending, it
 is as if a break has already happened; additional breaks, whether
-explicit or implicit, have no effect.
+explicit or implicit, have no effect.@footnote{If the vertical drawing
+position is negative---as it is when the formatter starts up---a break
+starts a new page (even if no output line is pending) unless an
+end-of-input macro is being interpreted.  @xref{End-of-input Traps}.}


G. Branden Robinson <gbranden>
Group administrator
Tue 14 Feb 2023 08:13:16 PM UTC, comment #9: 

Oh crap, I don't define "pending output line" until the next (non-example) paragraph.

The circularity is killing me.  Argh!

G. Branden Robinson <gbranden>
Group administrator
Tue 14 Feb 2023 08:09:56 PM UTC, comment #8: 

How about this?

I overran my vee, which kicked an example to the next page, but oh well.

I reduced the comprehensiveness of my parameter list, since as noted in comment #7, the anatomies of lines and pages haven't been presented yet.


diff --git a/doc/groff.texi b/doc/groff.texi
index 3bd029003..17369a045 100644
--- a/doc/groff.texi
+++ b/doc/groff.texi
@@ -7878,15 +7878,20 @@ Indicator of output device selection (Boolean-valued); see
 @cindex @code{sp} request, causing implicit break
 @cindex @code{ti} request, causing implicit break
 @cindex @code{trf} request, causing implicit break
-A break updates the drawing position per the page offset, indentation,
-vertical spacing, and page length, interrupting filling.  Various ways
-of causing breaks were shown in @ref{Breaking}.  The @code{br} request
-likewise causes a break.  A break is implied by several other
-requests:@: @code{bp}, @code{ce}, @code{cf}, @code{fi}, @code{fl},
+When an output line is pending, a break moves the drawing position to
+the beginning of the next text baseline, interrupting
+filling.@footnote{If the vertical drawing position is negative---as it
+is when the formatter starts up---a break starts a new page unless an
+end-of-input macro is being interpreted.  @xref{End-of-input Traps}.}
+Various ways of causing breaks were shown in @ref{Breaking}.  The
+@code{br} request likewise causes a break.  Several other requests imply
+breaks:@: @code{bp}, @code{ce}, @code{cf}, @code{fi}, @code{fl},
 @code{in}, @code{nf}, @code{rj}, @code{sp}, @code{ti}, and @code{trf}.
 If the no-break control character is used with any of these requests,
 GNU @code{troff} suppresses the break; instead the requested operation
-takes effect at the next break.  @samp{'br} does nothing.
+takes effect at the next break.  @samp{'br} does nothing.  If no output
+line is pending, a break does not normally alter the drawing position;
+but any other effects of a breaking request still occur.

 @Example
 .ll 55n


G. Branden Robinson <gbranden>
Group administrator
Tue 14 Feb 2023 07:50:57 PM UTC, comment #7: 

Hi Dave,

I would not claim that I've said everything that needs to be said here.  I think there's some bridgework to be build among the Texinfo nodes "Page Geometry" (which is mostly or wholly my work) and "Line Layout" and "Page Layout" much later, which I haven't deeply revised.

I do agree that the potential nilpotence of a break is an important fact.  And it turns out I have a vee to spare in the paragraph in question, so I'll see if I can do something about that specific issue while waiting for feedback from Bertrand.

G. Branden Robinson <gbranden>
Group administrator
Tue 14 Feb 2023 07:36:55 PM UTC, comment #6: 

Thanks for the expanded break explanation!

It's a little hard for me to judge--now that I know how it works--how well it explains the situation to someone who doesn't know how it works.  But I wonder if there could still be some improvement here.

For those savannah lurkers who want to follow the discussion but are also too lazy to look at commit ac4e28bd, the new wording is: "A break updates the drawing position per the page offset, indentation, vertical spacing, and page length, interrupting filling."  (As before, from here it talks only about how to cause breaks.)

First, the current wording could be construed to mean a break always updates the drawing position, but in fact it conditionally updates it, only if the drawing position is somewhere other than where the next left margin would be.  (That is, multiple breaks in a row have the same effect as a single break; only one of them updates the drawing position.)

Then, once you start saying something like "updates the drawing position if necessary," the crux of comment #2 again arises: is a position update "necessary" when no output is pending and we're in the no-man's land (no-person's land?) before the first page?

CSTR #54 treated this thing we're not calling a "pseudo-page transition" as a special case whose breaking behavior needed to be explicitly mentioned.  I sympathize with the desire to keep wording general whenever possible--and maybe that is possible here with some wording I haven't conceived of.  But the novice roff user who grasps the basics--including that a break is a thing that normally has an effect only when it needs to--might well be tempted to think that the situation of being "above" the first page and having nothing queued is a case where a break need cause no movement.

Dave <barx>
Group Member
Sun 12 Feb 2023 10:14:41 PM UTC, comment #5: 


commit ac4e28bd9e0ac5c3941275eba9d8ace5f2775662 (HEAD -> master, origin/master, origin/HEAD)
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Sun Feb 12 15:51:26 2023 -0600

    doc/groff.texi: Fix Savannah #63777.

    * doc/groff.texi (Manipulating Filling and Adjustment): Say more about
      the consequences of a break.

    Fixes <https://savannah.gnu.org/bugs/?63777>.  Thanks to Dave Kemper for
    the report.


G. Branden Robinson <gbranden>
Group administrator
Fri 10 Feb 2023 09:25:49 PM UTC, comment #4: 

comment #3:

> the third `rm`


s/rm/tm/

G. Branden Robinson <gbranden>
Group administrator
Fri 10 Feb 2023 09:24:25 PM UTC, comment #3: 

comment #2:

> comment #1:
> But I'm not sure this behavior is implied by the Texinfo documentation.  The passage you quoted contains only one sentence on what a break is: "A break interrupts filling."  But there is no pending output, so nothing to be interrupted, so causing a break at this point logically seems like a no-op, absent information otherwise.


A fair point.  I could add something about advancing the vertical position and resetting the horizontal one.
 

> The Texinfo manual nowhere uses the CSTR #54 term "pseudo-page transition."


Indeed.  I don't recall it being present before, and since I don't like it, I've never added it.

I don't think there's anything "pseudo" about it; it's a reasonable design choice to not "be on" any page at first, in the event there turns out to be no output to produce.  If you do so much as move to position (0,0), there will be output, wasting paper, as it were.

> The text about the nl register refers to a "first page transition," but this term is neither defined nor used anywhere else in the document; in particular, that a break triggers it is not revealed.


It's more general than that in groff; anything producing output will cause the transition onto the first page.

Consider the following exhibit:


$ cat ~/src/GIT/groff/ATTIC/A.roff
.tm 1: nl=\n(nlu
A
.tm 2: nl=\n(nlu
.br \" necessary in Heirloom Doctools troff, but not in groff
.tm 3: nl=\n(nlu
.pl \n(nlu


This produces identical output on groff and Heirloom Doctools troff, but there is a difference.  If you take out the `br` request, the third `rm` reports a vertical position of 0 (in both formatters), which makes sense.  There is still plenty of room on the first output line.  But Heirloom produces another ~65 lines of output (all blank).  Apparently there's a boundary condition issue.  I'm already at the page length so it's "too late" to set it to the current value and have it take effect.  I guess.

An even more minimal example produces an even more interesting disparity.

A horizontal motion of zero length is assuredly "less" output than writing one glyph.  But it is output, and I would expect it to cause a page transition if one is in the twilight zone.  And it does.


$ cat ATTIC/h.roff
.tm 1: nl=\n(nlu
\h'0'
.tm 2: nl=\n(nlu
.\"br \" necessary in Heirloom Doctools troff, but not in groff
.tm 3: nl=\n(nlu
.pl \n(nlu
$ nroff ATTIC/h.roff >/dev/null # groff 1.22.4
1: nl=-1u
2: nl=0u
3: nl=0u
$ ./bin/nroff ~/src/GIT/groff/ATTIC/h.roff >/dev/null # Heirloom
1: nl=-1u
2: nl=40u
3: nl=40u


I can't account for Heirloom's update of the vertical position to 40u instead of 0.  I also don't aim to dig into it.

> (Side note: this nl paragraph is missing an end parenthesis that makes the sentence tricky to parse.)


Fixed in my working copy--thanks!

> The .output request alludes to the behavior when it says, "This request can't be used before the first page has started--if you get an error, simply insert '.br' before the 'output' request."  But this is not a place a user trying to figure out an interaction between .in and a trap would think to look, and even then only documents the general behavior in a sideways manner.


Agreed.

> So unless I'm overlooking something in the manual (possible: I'm using likely search terms, not reading the document top to bottom), a statement to the effect of the one from CSTR #54 would make this clearer.


Also agreed.

I'll see if I can usefully pedagogue this issue.  ;-)

G. Branden Robinson <gbranden>
Group administrator
Fri 10 Feb 2023 08:47:52 PM UTC, comment #2: 

comment #1:

> `in` puts a break on the output, and therefore the vertical
> position passes 0, springing the trap.


Empirical evidence suggests this is indeed what's happening.  And, armed with a little more knowledge, I find it's documented in CSTR #54 (1992), whose section 3 states, "A pseudo-page transition onto the first page occurs... when the first break occurs."  Section 3 is "Page control," and this sentence is the third one of the section, so this information is fairly prominent.  (And sure enough, your raw-roff example works the same on Heirloom troff.)

But I'm not sure this behavior is implied by the Texinfo documentation.  The passage you quoted contains only one sentence on what a break is: "A break interrupts filling."  But there is no pending output, so nothing to be interrupted, so causing a break at this point logically seems like a no-op, absent information otherwise.

The Texinfo manual nowhere uses the CSTR #54 term "pseudo-page transition."  The text about the nl register refers to a "first page transition," but this term is neither defined nor used anywhere else in the document; in particular, that a break triggers it is not revealed.  (Side note: this nl paragraph is missing an end parenthesis that makes the sentence tricky to parse.)

The .output request alludes to the behavior when it says, "This request can't be used before the first page has started--if you get an error, simply insert '.br' before the 'output' request."  But this is not a place a user trying to figure out an interaction between .in and a trap would think to look, and even then only documents the general behavior in a sideways manner.

So unless I'm overlooking something in the manual (possible: I'm using likely search terms, not reading the document top to bottom), a statement to the effect of the one from CSTR #54 would make this clearer.

Dave <barx>
Group Member
Fri 10 Feb 2023 01:42:19 PM UTC, comment #1: 

Hi Dave,

original submission:

> This happens in a recent groff build a little older than rc2 but with the latest -me macros.  But the behavior is identical with a stock 1.22.4 build.


> $ cat test.me
> .mso e.tmac
> .
> .de $H   \" user-defined -me header macro
> .tm nn is \\n(nn
> ..
> .
> .vs 2i
> .
> .nr nn 4
> Hello.
> $ groff -ww test.me > /dev/null
> nn is 4
> $ sed s/vs/in/ test.me | groff -ww > /dev/null
> nn is troff:<standard input>:7: warning: register 'nn' not defined
> 0


> Nothing that I can see about setting the indentation level ought to cause -me to think "starting a new page!"
>
> Ironically, the -me manual specifies .in but not .vs as a safe low-level request.


I can contrive a reproducer in raw roff.


$ cat EXPERIMENTS/kemper-header.roff
.de $H   \" custom page heading macro
.tm nn is \\n(nn.
..
.
.wh 0 $H
.if r XX \{\
.  ie \n(XX .vs 2i
.  el       .in 2i
.\}
.
.nr nn 4
Hello.
.pl \n(nlu


I think what is happening here is that the `vs` request doesn't put anything on the output--it simply alters the environment.  The vertical position therefore does not increase above "-1" (the magic  amid-page-ejection value) until later, when "Hello." is formatted and the `nn` register has been defined.

`in` puts a break on the output, and therefore the vertical position passes 0, springing the trap.

Quoting our Texinfo manual:


5.9 Manipulating Filling and Adjustment
=======================================

A break interrupts filling.  Various ways of causing breaks were shown
in *note Breaking::.  The 'br' request likewise causes a break.  A break
is implied by several other requests: 'bp', 'ce', 'cf', 'fi', 'fl',
'in', 'nf', 'rj', 'sp', 'ti', and 'trf'.  If the no-break control
character is used with any of these requests, GNU 'troff' suppresses the
break; instead the requested operation takes effect at the next break.
''br' does nothing.


I therefore hypothesize that using the no-break control character with `in` will suppress the warning.


$ cat EXPERIMENTS/kemper-header2.roff
.de $H   \" custom page heading macro
.tm nn is \\n(nn.
..
.
.wh 0 $H
.if r XX \{\
.  ie \n(XX .vs 2i
.  el       'in 2i
.\}
.
.nr nn 4
Hello.
.pl \n(nlu


...and so it appears.

I therefore believe the system is working as documented.

What do you think?

G. Branden Robinson <gbranden>
Group administrator
Thu 09 Feb 2023 07:07:16 AM UTC, original submission:  

This happens in a recent groff build a little older than rc2 but with the latest -me macros.  But the behavior is identical with a stock 1.22.4 build.

$ cat test.me
.mso e.tmac
.
.de $H   \" user-defined -me header macro
.tm nn is \\n(nn
..
.
.vs 2i
.
.nr nn 4
Hello.
$ groff -ww test.me > /dev/null
nn is 4
$ sed s/vs/in/ test.me | groff -ww > /dev/null
nn is troff:<standard input>:7: warning: register 'nn' not defined
0

Nothing that I can see about setting the indentation level ought to cause -me to think "starting a new page!"

Ironically, the -me manual specifies .in but not .vs as a safe low-level request.

Dave <barx>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by gbranden (Posted a comment)
  • -email is unavailable- added by barx (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-02-12 gbranden StatusConfirmed Fixed
        Open/ClosedOpen Closed
        Planned ReleaseNone 1.23.0
    2023-02-10 gbranden StatusNeed Info Confirmed
        Summarybreak before output has begun invokes top-of-page trap explicitly document transition onto first page
    2023-02-10 barx Severity3 - Normal 2 - Minor
        Item GroupIncorrect behaviour Documentation
        Summary[me] .in request invokes .$H macro break before output has begun invokes top-of-page trap
    2023-02-10 gbranden CategoryMacro package me Core
        StatusNone Need Info
        Assigned toNone gbranden

    Back to the top

    Powered by Savane 3.13-f762.
    Corresponding source code