Wed, 11 Jan 2012 21:23:08 +0100
Because of the following question on TeX.sx:
I looked into that bit of ancient code that typesets "here" floats and
the more I look the more issues I find with it.
Basically right now if a "here" float succeeds it will more or less insert
\vskip \intextsep %% a)
\penalty \interlinepenalty %% b)
\vskip \intextsep %% c)
\ifnum\outputpenalty <-\@Mii % float encountered in vmode
\vskip -\parskip %% d)
\penalty 10000 % the original breakpoint modified by TeX
This has the following consequences:
a) does not combine with a previous skip (as \addvspace would)
b) provides a breakpoint after the float
c) is not seen by any following \addvspace because of the penalty
after it on the main vertical list
d) cancels the upcoming \parskip that will be added by the next text
line after the float.
Now to make the \intextsep combine with surrounding vertical spaces one
could use \addvspace at a) and would could ensure that the skip at c)
actually comes after the \penalty 10000. That was my proposal to the
question on TeX.sx
However, d) also becomes an issue if we have 2 "here" floats in a row.
In that case there is no \parskip being added between the two floats
thus we will end up with an extra \vskip -\parskip there --- which, if
that has a positive value, will noticeably shorten the space between the
(as an aside: in the current solution we do get \vskip 2x\intextsep -
\parskip here which isn't better but just bad on a different scale)
Now one possible solution that I could think of would be to add \parskip
before the float (if in vertical mode) rather than subtracting it
afterwards. That way it would be before and after and if several floats
come in a row it would be between them (once) as well.
The downside of that would be that the spacing around floats would then
change with a change to \parskip but that is something that happens in
other places too within LaTeX and it would be somewhat consistent.
(not that I propose that as a general fix as that would break far too
But there is more which is not as it should (only the question being
what should it be):
as the float is a box the distance from the top of that box to the
baseline of the previous line of text depends on whether or not that
line has a depth after all the \intextsep is just added after that line
and no adjustment for the depth of that line is made. Thus the position
of the float would depend on the characters in that last line.
Worse: the depth of the lin (stored in \prevdepth) survives until after
the float is typeset (or even after any number of "here" floats are
typeset) and will then be used to calculate the baselineskip for the
first line of text after the float(s).
So if the text line before the float has chars with descenders (say a
"g") then this will shorten the space from the bottom of the float to
the following line -- cool.
Again one could think of schemes to resolve this, e.g., backup by
\prevdepth before the float and then change it to zero so that it
doesn't apply afterwards. However here I'm fare less sure if that is
even ok in all cases: if the last line as some huge depth then this
would mean that the float would even backed up into the previous object
so I don't think that there is a good general solution here.
One could also argue for \nointerlineskip after the float then white
space above and below would be the same.
Anybody any good thoughts what would be or could be an appropriate scheme?