Re: Excessive leading before floats
Gavin Smith <[email protected]>
| Newsgroups | gmane.comp.tex.texinfo.bugs |
|---|---|
| Message-ID | <anZVulJoWs1oJEAr@orangestar> |
(Original message:
https://lists.gnu.org/archive/html/bug-texinfo/2024-12/msg00022.html)
In this message, our correspondent reported that there could be too much
interparagraph spacing on the page before a large @float. He tried putting
a @vskip before a @float to get more of the whitespace at the bottom of
a page instead:
@vskip 0pt plus 1filll
@float Type,Id
- but this didn't work.
In my reply, I explained that this @vskip glue would be discarded after a
page break, and suggested an alternative:
@vskip 0pt plus 1filll
@vbox to 0pt{}
@float Type,Id
> > It is possible to get the same output as with @page by adding an
> > empty box after the @vskip:
>
> I like this one even more since it will not produce a page break.
> Vertical glue after the float may be required to make the tables evenly sit
> between the surrounding paragraphs when they and in the middle of a page.
>
> I will try these two good sugestions.
>
I kept a note that this was an issue worth coming back to, as the output
was not good without this tweaking of the output with texinfo.tex.
I've had another look at this issue and using a penalty is also a possibility,
as this is a possible breakpoint for a page. Possible page breakpoints are
listed in section 27.4 of "TeX by Topic" (by V. Eijkhout) (although the details
of TeX's page breaking seem quite technical to me). It would look like:
@vskip 0pt plus 1filll
@penalty0
@float Type,Id
As you are aware, development of texinfo.tex is something of a niche interest,
which is why it has taken so long to come back to this issue.
It is a similar problem to line breaking in @uref, although in that case
it is line breaking, not page breaking. The @uref command (used for
URLs) is notorious for bad line breaking, as there is often a paucity of
appropriate line break points inside a URL. The solution we have settled
on uses a pair of penalties to allow a line break:
% Allow a ragged right output to aid breaking long URL's. There can
% be a break at the \allowbreak with no extra glue (if the existing stretch in
% the line is sufficient), a break at the \penalty with extra glue added
% at the end of the line, or no break at all here.
% Changing the value of the penalty and/or the amount of stretch affects how
% preferable one choice is over the other.
% Check test cases in doc/texinfo-tex-test.texi before making any changes.
\def\urefallowbreak{%
\penalty0\relax
\hskip 0pt plus 3 em\relax
\penalty1000\relax
\hskip 0pt plus -3 em\relax
}
The idea here is that the two \hskip's cancel each other out if the possible
breaks are not taken. (The comment about \allowbreak appears to be wrong,
but I belive this is supposed to refer to the \penalty0.) We prefer not
to use the \hskip if it is not needed (otherwise there would be a little
space at the end of the line), which is why we have penalty 0, which is
a smaller penalty than 1000.
We could use a similar solution for floats for the problem of page breaking.
We do use a similar method with pairs of glue that cancel each other out
in other places, such as in index formatting before index initials
(in the definition of \initial):
% We like breaks before the index initials, so insert a bonus.
% The glue before the bonus allows a little bit of space at the
% bottom of a column to reduce an increase in inter-line spacing.
\nobreak
\vskip 0pt plus 4\baselineskip
\penalty -300
\vskip 0pt plus -4\baselineskip
This method is also used in the definition of \partentry, and possibly in other
places that I didn't see.
So I've come to the following patch for texinfo.tex (version 2026-07-23.18):
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index 8015a03f17..2711821422 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -10065,6 +10065,12 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% We can't be used inside a paragraph.
\par
%
+ % Allow a page break with a ragged page bottom.
+ \penalty 0
+ \vskip 0pt plus 5\baselineskip
+ \penalty 1000
+ \vskip 0pt plus -5\baselineskip
+ %
\vtop\bgroup
\def\floattype{#1}%
\def\floatlabel{#2}%
The choice of penalty and glue stretch here are somewhat arbitrary - as far
as I understand, the stretch (5 lines) is the amount we are saying that "looks
okay" at the bottom of a page. The size of the penalty (1000) is balanced
against the badness of stretching interparagraph space to get this break, so
reducing this penalty encourages breaking with the extra space at the bottom
of the page.
This will benefit from testing with a manual with lots of big @float's
(such as Bertrand Petit's, if he is still interested in this issue). I did
try checking with the gawk manual which uses @float fairly heavily, but the
floats were not big enough that it made much of a difference.
> > The solution with @page is better though as @vskip, @vbox etc. are not
> > recognized Texinfo commands, and the output could break if material is
> > added or removed from the document (for example, a large space in the
> > middle of the page with paragraphs at the top and bottom).
>
> Large empty vertical space is unavoidable, whatever the workaround is,
> since TeXinfo's floats aren't actually floating. Having real floats would be
> the only effective fix. I think that large white space is preferable, if not
> ideal, to widely spaced paragraphs which is extremely displeasing. Adding an
> horizontal rule before and after each float may help the reader to
> unambiguously understand that the flow of the main matter was interrupted.
>
> Thank you for your sugestions, I will probably adopt one of them it
> not both.
>
> --
> %!PS -- Bertrand Petit
> /D{def}def/E{exch}D/G{get}D/I{2 div}D/U{dup}D/L{roll}D/Y{setgray}D/N{newpath}D
> /O{N 0 0 moveto}D/P{pop}D/T{translate}D currentpagedevice/PageSize G U 0 G/w E
> D 1 G /h E D w I h I T 0 Y 1 setlinewidth 0 1 2 { P 120 rotate 2 4 w U mul h U
> mul add sqrt I 50 add {N 50 0 3 2 L 0 360 arc stroke}for}for/s{O true charpath
> pathbbox exch 4 -1 L E sub I 3 1 L sub I} D /l(bp)D 0.94 Y /Helvetica findfont
> 22 scalefont setfont l s P(x)s exch P T O l show showpage