bugGNU roff - Bugs: bug #61428, [me] new page-length restriction...

 
 

bug #61428: [me] new page-length restriction too restrictive

Submitter:  Dave <barx>
Submitted:  Fri 05 Nov 2021 01:16:58 AM UTC
   
 
Category:  Macro me Severity:  3 - Normal
Item Group:  Incorrect behaviour 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

Mon 07 Mar 2022 12:39:17 AM UTC, comment #16: 

Yeah, it got a little confusing because two bugs were tracking essentially the same problem at two different points in time.  They should be cross-linked now; this bug's original submission already referred to the other, and I just added the link from there back to here.

Dave <barx>
Group Member
Sun 06 Mar 2022 11:29:57 PM UTC, comment #15: 


comment #14:

> comment #12:
> > Commits 4d5b2468 and f6fcbba9 together implemented the patch of comment #11.
>
> I guess I should add a supplementary bug-closer to the ChangeLog.


Hah.  Already did, in b3814ea651.

G. Branden Robinson <gbranden>
Group administrator
Sun 06 Mar 2022 11:28:08 PM UTC, comment #14: 

comment #12:

> Commits 4d5b2468 and f6fcbba9 together implemented the patch of comment #11.


I guess I should add a supplementary bug-closer to the ChangeLog.

Thanks for the reminder, Dave!


commit 4d5b24683497fd9c1b817a663d6a58f15d46c9f6
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Wed Feb 2 02:00:45 2022 +1100

    Revert "[me]: Abort if paper length too short."

    This reverts commit 7bfaf799c4822a99762cc30b0cf16ee89449621c.

    I'll fix this a better way, based on Keith Marshall's technique for ms.

commit f6fcbba95cc77dedcae75e61db26e86922f8f8ba
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Wed Feb 2 04:06:40 2022 +1100

    [me]: Add page length insufficiency check.

    * tmac/e.tmac (@h): Port Keith Marshall's page length checker from
      ms(7).

    Fixes <https://savannah.gnu.org/bugs/?61034>.


G. Branden Robinson <gbranden>
Group administrator
Sun 06 Feb 2022 06:18:16 PM UTC, comment #13: 

comment #12:

> > $ printf '.pl 2v\n.nr fm 0\n.nr hm 0\n.nr tm 0\n.nr bm (-0)\nHello.\n' | tg -me -Tascii
> >
> > Hello.


>
> I'm not sure what the significance here is of setting bm to a negative
> 0, but the example works the same with an unadorned 0 (as one would
> expect).


That was simply a brain fart; I was momentarily hallucinating about trap
locations.

> > If you want me(7) to do single-line document formatting,
> > please file that as a separate ticket.  :P
>
> Haha, no, I'm quite happy with the fix as implemented.  Thank you!


Glad to be of service!  I eagerly await your thoughts on bug #61710.  :)

G. Branden Robinson <gbranden>
Group administrator
Sun 06 Feb 2022 09:38:02 AM UTC, comment #12: 

Commits 4d5b2468 and f6fcbba9 together implemented the patch of comment #11.

comment #11:

> Upon further reflection, I would argue against that position.
>
> me(7) unconditionally sets up header and footer traps.
> Even the `hx` macro doesn't unset them; it simply causes the
> titles to not be emitted when they are encountered.  See
> registers `?H`, `?h`, and the macro `@t`.


Yes, good points.


> $ printf '.pl 2v\n.nr fm 0\n.nr hm 0\n.nr tm 0\n.nr bm (-0)\nHello.\n' | tg -me -Tascii
>
> Hello.


I'm not sure what the significance here is of setting bm to a negative 0, but the example works the same with an unadorned 0 (as one would expect).

> If you want me(7) to do single-line document formatting,
> please file that as a separate ticket.  :P


Haha, no, I'm quite happy with the fix as implemented.  Thank you!

Dave <barx>
Group Member
Thu 03 Feb 2022 08:34:46 PM UTC, comment #11: 

comment #8:

> comment #6:
> > I'm all for minimal reproducing cases, but that one might be
> > too minimal...!  It doesn't really exercise any me(7)
> > features.  The package gets initialized, sure...
>
> That was sort of its point: even without using anything me-ey, the very presence of the -me package rejected (what might, arguably, be) valid input.


Upon further reflection, I would argue against that position.

me(7) unconditionally sets up header and footer traps.  Even the `hx` macro doesn't unset them; it simply causes the titles to not be emitted when they are encountered.  See registers `?H`, `?h`, and the macro `@t`.
 

> Still, it's easy to stick in a -me paragraphing macro before the Hello and get the same results.


> printf '.pl 10v\n.pp\nHello.\n' | groff -me -Tascii


Yes.

> But a reasonable counterargument is that it should stop working unless I also told -me to use no bottom margins; otherwise, I've made my terminal "page" too short to handle all the requested output.


Yes, I think that is the argument that me(7) itself would adopt if it could speak, just going by the way it is written.

It's the top margin, too.  But with modifications to zero out all of the vertical margins, including `hm` and `fm` as well, I can get you down to two lines.


$ printf '.pl 2v\n.nr fm 0\n.nr hm 0\n.nr tm 0\n.nr bm (-0)\nHello.\n' | tg -me -Tascii

Hello.


If you want me(7) to do single-line document formatting, please file that as a separate ticket.  :P

Here's the patch.


diff --git a/tmac/e.tmac b/tmac/e.tmac
index 91dc19830..2c2678817 100644
--- a/tmac/e.tmac
+++ b/tmac/e.tmac
@@ -81,11 +81,6 @@
 .rm @line
 ..
 .
-.\" --- sanity check the page dimensions
-.do de check_page_length
-.if (\\n(.pu<14v) .ab \\*(_e: cannot format short page length \\n(.pu
-..
-.
 .\" --- check whether grohtml needs end of title/heading
 .do de1 @html_check_need_title
 .if \\n[devtag-needs-end-of-title] \
@@ -279,8 +274,13 @@
 .
 .de @h                 \" --- header
 .if \n@>1 .tm >> @h %=\\n% ?a=\\n(?a ?b=\\n(?b ?w=\\n(?w
-.if (\\n(.i+\\n(.o)>=\\n(.l \
-.      @err page offset plus indentation exceeds line length
+.do if (u;\\n(tm+\\n(bm+\\n(.V>\\n(.p) \{\
+.      do @err insufficient page length; aborting
+.      pl \\n(nlu
+.      ab
+.\}
+.do if (u;\\n(.i+\\n(.o>=\\n(.l) \
+.      do @err page offset plus indentation exceeds line length
 .\" initialize a pile of junk
 .nr ?h \\n(?H                  \" transfer "next page" to "this page"
 .nr ?H 0
@@ -511,7 +511,6 @@
 .if !'\*(.T'html' .rn bp @b    \" --- begin page
 .
 .de bp                 \" *** begin new page (overrides columns)
-.do check_page_length
 .nr $c \\n($m                  \" force new page, not new column
 .ie \\n(nl>0 \
 .      @b \\$1
@@ -535,13 +534,6 @@
 .      nr _L \\n(.l
 ..
 .
-.rn pl xP              \" --- save troff page length request
-.
-.de pl                 \" *** set page length
-.xP \\$1
-.do check_page_length
-..
-.
 .rn po @O              \" --- local page offset
 .
 .de po                 \" *** page offset
@@ -813,7 +805,6 @@
 ..
 .
 .de @p                 \" --- initialize for paragraph
-.do check_page_length
 .do check_need_title
 .if "\\n(.z"|e" .do @err eqn equation continuation unfulfilled
 .in \\n($iu+\\n(pou
@@ -834,7 +825,6 @@
 .
 .
 .de sh                 \" *** section heading
-.do check_page_length
 .fi
 .do check_need_title
 .if (\\n(si>0)&(\\n(si<1n) \
@@ -973,7 +963,6 @@
 .
 .
 .de 2c                 \" *** double columned output
-.do check_page_length
 .br
 .if \\n($m>1 \
 .      1c\"                            \" revert to 1c if already 2c
@@ -991,7 +980,6 @@
 ..
 .
 .de 1c                 \" *** single columned output
-.do check_page_length
 .br
 .nr $c 1
 .nr $m 1


Keith's method (which he illustrated in ms(7)) of putting the page length check in the page trap is much cleaner than what I was doing.  Apart from being less intrusive, it seems to respect an element of *roff philosophy better--you can break something into a thousand pieces if you want, as long as you put it back together before the formatter needs it.




G. Branden Robinson <gbranden>
Group administrator
Thu 09 Dec 2021 01:22:37 PM UTC, comment #10: 

Hi, Dave!

comment #9:

> comment #8:
> > comment #6:
> > > I think that by "nominal", all Allman meant was that that
> > > distance was as low as the running text could get; we're
> > > all familiar with pages that fail to fill due to the text
> > > ending, `ne` requests, keeps, and so on.
> >
> > That's my reading of the intent there as well.
>
> Actually, I think it's subtler than that.  Even on a page with text going all the way to the bottom, the exact placement of the last line will depend on the type size, leading, and any diagrams (or in -me's case, even super- and subscripts further up the page) that alter the flow of lines on the page.  I believe the "nominal" is pointing out that there is no way to guarantee that \n(bm will exactly equal "the distance from the bottom of the page to the bottom of the text," only that it establishes a textual low-water mark on the page.


Agreed.  If anyone ever pesters us about this, we can add your text to the reference manual.  :)

If only all the issues with me(7) were so easily resolved... :-O

I'm leaving this as "Need Info" because I'm still not sure exactly what to do, apart from catalogging all of the traps me(7) sets so that a minimum page length can be computed dynamically.  Just summing \n(tm and \(bm and adding a vee doesn't seem to do the trick.

G. Branden Robinson <gbranden>
Group administrator
Thu 09 Dec 2021 07:52:47 AM UTC, comment #9: 

comment #8:

> comment #6:
> > I think that by "nominal", all Allman meant was that that
> > distance was as low as the running text could get; we're
> > all familiar with pages that fail to fill due to the text
> > ending, `ne` requests, keeps, and so on.
>
> That's my reading of the intent there as well.


Actually, I think it's subtler than that.  Even on a page with text going all the way to the bottom, the exact placement of the last line will depend on the type size, leading, and any diagrams (or in -me's case, even super- and subscripts further up the page) that alter the flow of lines on the page.  I believe the "nominal" is pointing out that there is no way to guarantee that \n(bm will exactly equal "the distance from the bottom of the page to the bottom of the text," only that it establishes a textual low-water mark on the page.

Dave <barx>
Group Member
Thu 09 Dec 2021 05:04:25 AM UTC, comment #8: 

comment #6:

> I'm all for minimal reproducing cases, but that one might be
> too minimal...!  It doesn't really exercise any me(7)
> features.  The package gets initialized, sure...


That was sort of its point: even without using anything me-ey, the very presence of the -me package rejected (what might, arguably, be) valid input.

Still, it's easy to stick in a -me paragraphing macro before the Hello and get the same results.

printf '.pl 10v\n.pp\nHello.\n' | groff -me -Tascii

> I think that by "nominal", all Allman meant was that that
> distance was as low as the running text could get;


That's my reading of the intent there as well.

> One can reasonably protest that if we don't have headers and
> footers at all, we should be allowed to have a shorter page
> length.  But that is not how me(7) is designed.  The `tm` and
> `bm` registers are independent of header/footer usage,


A valid point.  The real-world situation that I simplified to the point of absurdity above was one using the .pl/.em trick from the Texinfo manual to cut off terminal output right after the last line of output in a document containing no footers.  After the bug #61034 fix, this stopped working on very short documents.  But a reasonable counterargument is that it should stop working unless I also told -me to use no bottom margins; otherwise, I've made my terminal "page" too short to handle all the requested output.

Dave <barx>
Group Member
Tue 07 Dec 2021 11:02:43 PM UTC, comment #7: 

Sigh.  It's opposite day.  Correction inline.

comment #6:

> As implemented, the check is definitely wrong because me(7) exposes all of those as configurable (`.v` only *in*directly though--you're supposed to use its `$v` percentage instead).


G. Branden Robinson <gbranden>
Group administrator
Tue 07 Dec 2021 11:00:27 PM UTC, comment #6: 

Hi Dave,

original submission:

> The fix to bug #61034 has the side effect of disallowing input that formerly worked, e.g.:
>
> printf '.pl 10v\nHello.\n' | groff -me -Tascii
>
> This produced an error-free 10 lines of screen output in 1.22.4.  In a build from the latest sources, it aborts with the error "e.tmac: cannot format short page length 400u".


I'm all for minimal reproducing cases, but that one might be too minimal...!  It doesn't really exercise any me(7) features.  The package gets initialized, sure...

Let's make it a real me(7) document.


$ cat EXPERIMENTS/hello-dave1.me
.pp
Hello, Dave.
$ nroff -me EXPERIMENTS/hello-dave1.me | cat -s

     Hello, Dave.


Sure, seems all right.  But it's also formatting for a 66-line page, which I've elided with `cat -s`.

Let's add some headers and footers.


$ cat EXPERIMENTS/hello-dave2.me
.he 'A'B'C'
.fo 'D'E'F'
.pp
Hello, Dave.
$ nroff -me EXPERIMENTS/hello-dave2.me | cat -s

A                             B                            C

     Hello, Dave.

D                             E                            F


We're still good.  Now let's add your `pl` request.


$ cat EXPERIMENTS/hello-dave3.me
.pl 10v
.he 'A'B'C'
.fo 'D'E'F'
.pp
Hello, Dave.
$ nroff -me EXPERIMENTS/hello-dave3.me | cat -s

A                             B                            C

     Hello, Dave.


Now something has gone wrong--our footer is missing and me(7) didn't even complain.  It is very hard for me to regard this as acceptable output.

If the writer wants a page length that short they need to modify the vertical margin registers to get it.

meref.me says (approximately, I'm in the midst of revising the entire manual):


The spacing
of headers and footers
is controlled by four registers.
.NR (hm
[4v]
is the distance from the top of the page
to the top of the header,
.NR (fm
[3v]
is the distance from the bottom of the page
to the bottom of the footer,
.NR (tm
[7v]
is the distance from the top of the page
to the top of the text,
and
.NR (bm
[6v]
is the distance from the bottom of the page
to the bottom of the text
(nominal).


I think that by "nominal", all Allman meant was that that distance was as low as the running text could get; we're all familiar with pages that fail to fill due to the text ending, `ne` requests, keeps, and so on.  I don't think it intends to suggest anything about the footer getting chopped off.

One can reasonably protest that if we don't have headers and footers at all, we should be allowed to have a shorter page length.  But that is not how me(7) is designed.  The `tm` and `bm` registers are independent of header/footer usage, and in fact fiddly calculations are required to take them into account.

This is revealed when you check out the definitions of the super-legacy, early-1970s old roff compatibility feature.


.de m1                  \" *** position one space
.nr _0 \\n(hmu
.nr hm \\$1v
.nr tm +\\n(hmu-\\n(_0u
.rr _0
..
.
.de m2                  \" *** position two space
.nr tm \\n(hmu+\\n(tpp+\\$1v
..
.
.de m3                  \" *** position three space
.nr bm \\n(fmu+\\n(tpp+\\$1v
..
.
.de m4                  \" *** position four space
.nr _0 \\n(fmu
.nr fm \\$1v
.nr bm +\\n(fmu-\\n(_0u
..


At some point Ossanna and Lesk et al. (?) decided that it made more sense, I surmise, to measure the vertical margins to the running text independently of the presence of (three-part) titles.

Anyway, the bottom line (heh) here is that a default me(7) document absolutely demands 13 vees of space in a document, and one more than that if it's going to have any running text at all.  This jibes with my experimental approach that led to the hard-coded 14v.

I think the think to do here is make the `check_page_length` macro ensure that the page length is strictly greater than the sum of `tm` and `bm`, (or greater than or equal to the sum of `tm`, `bm`, and the line height `.v`.)  As implemented, the check is definitely wrong because me(7) exposes all of those as configurable (`.v` only directly though--you're supposed to use its `$v` percentage instead).

I believe I can satisfy the flexibility requirement but not the simplicity-of-input requirement in your original message quoted above.  My view is that if someone wants me(7) to render extremely short pages, they need to do the slight extra work of setting `tm` and `bm` values appropriate to that unorthodox length--and `hm` and `fm` too, if they want titles on those short pages.

What do you think?

G. Branden Robinson <gbranden>
Group administrator
Tue 07 Dec 2021 10:29:53 PM UTC, comment #5: 

I have the information I need.  Working on this.

As is my wont, I'm teaching myself the macro package by nit-picking its documentation to death.

G. Branden Robinson <gbranden>
Group administrator
Mon 08 Nov 2021 08:51:19 AM UTC, comment #4: 

comment #3:

> The main issue (or I'd have done it myself already) is the
> register names; I don't know me(7)'s off the top of my head.


And I don't know -ms's, so I can't tell at a glance which -me ones are equivalent.  The four -me regusters I mentioned in comment #2 (hm, fm, tm, and bm) specify the spaces between, respectively, the top of the page and the top of the header (modulo bug #60553); the bottom of the page and the bottom of the footer; the top of the page and the top of the text; and the bottom of the page and the bottom of the text.

Dave <barx>
Group Member
Mon 08 Nov 2021 08:14:59 AM UTC, comment #3: 

Keith wrote a better version of this diagnostic for the ms package on 23 October.

https://git.savannah.gnu.org/cgit/groff.git/commit/?id=8830820a9a85ad52a8452017d52e67378a76c4c4

A "port" of that logic to me(7) would be responsive to this ticket and my original concern.  The main issue (or I'd have done it myself already) is the register names; I don't know me(7)'s off the top of my head.

I do note the diagnostic in the above commit does not communicate the sum used in the comparison to the user.  That might indeed be helpful to report.

G. Branden Robinson <gbranden>
Group administrator
Mon 08 Nov 2021 07:52:50 AM UTC, comment #2: 

That's a good point, though feels to me like a separate problem worthy of its own bug report.

The minimum page length hard-coded in commit 7bfaf799, 14v, clearly works for some situations and not others.  The correct minimum page length may depend on the sizes of header and footer margins (the hm, fm, tm, and bm registers), the length of the input, and other factors.  Or perhaps there is a fix to bug #61034 that is more appropriate than simply disallowing short pages.

Dave <barx>
Group Member
Sun 07 Nov 2021 12:58:28 AM UTC, comment #1: 

  The error message is not helpful,

information about how many lines are minimally needed to escape the
message is missing
  or
show the definition of a "short page length" (< N lines).

and show the actual page length count in lines.

  Analogous message in other macro packages should be adapted.

Bjarni Ingi Gislason <bjarniig>
Fri 05 Nov 2021 01:16:58 AM UTC, original submission:  

The fix to bug #61034 has the side effect of disallowing input that formerly worked, e.g.:

printf '.pl 10v\nHello.\n' | groff -me -Tascii

This produced an error-free 10 lines of screen output in 1.22.4.  In a build from the latest sources, it aborts with the error "e.tmac: cannot format short page length 400u".

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 bjarniig (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 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-02-06 barx StatusIn Progress Fixed
        Open/ClosedOpen Closed
        Planned ReleaseNone 1.23.0
    2022-02-03 gbranden StatusNeed Info In Progress
    2021-12-07 gbranden StatusIn Progress Need Info
    2021-12-07 gbranden StatusNeed Info In Progress
        Assigned toNone gbranden
    2021-11-08 gbranden StatusNone Need Info

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code