(I see that Jeremias agrees with Andreas about how to interpret the nested
keeps, so I reply just once)
Andreas L. Delmelle wrote:
In very rough terms, the logic behind it would be:
if a given break #1 has a plain adjustment ratio of 3 and a governing
keep of "auto",
and the next break #2, regardless of its adjustment ratio, would
violate a keep-constraint with a higher value,
=> apply a 'correction factor' to the demerits of break #1 so that
the influence of the plain adjustment ratio is significantly reduced,
and it will be considered a "good break" in spite of its being "way
too short".
If the effective demerit computation of break #2 takes into account
the fact that that break itself would violate a keep (other than
"auto"), its demerits would in turn be artificially increased, so if
eventually presented with a choice, the algorithm would prefer the
first break over the second.
No idea if this would be feasible in practice though...
double effectiveRatio = (adjustmentRatio * keepRatio);
where keepRatio is a double value based on the keep-values, that
would either leave the adjustmentRatio as is (= 1), or increase/
reduce the influence of the plain value.
Seems a good idea!
Maybe we could *add* something to adjustmentRatio, so we could be quite
sure that a break violating a keep suddenly becomes quite ugly even if its
original ratio would be < 1.
I am trying to imagine if we have to handle in a different way breaks
violating a keep and having a ratio < 0 ... maybe these are the ones that
really needs to be depracated.
Satisfying a keep condition without overflowing involves the creation of
*short* lines, as what we want to avoid is violating a keep just to fill a
line better. So:
- probably there is no need to penalize a break violating a keep if it has
a high ratio: successive breaks will surely be better, whether they
still violate a keep or not
- a "long" break, on the other hand, should be used only if there isn't
any other alternative (for example, because the content of the keep is a
single word longer than a line), so they should not enter the record
structure, but only saved as a lastTooLong solution.
So, what we need could be just correct the violating breaks having a
negative ratio, so that it becomes < -1 and would not become an active
node (unless there is a restart, in which case it's ok).
... but I'm basically writing down things as I think, so I could be
missing some important point!
One last quick note concerning nesting: what if the inner inline
had a *lower* force? feasible breaks in it should be first given a
high penalty (to see if we can put everything together) and then a
lower one (so the penalties should hold a nested chain of force
values)?
Indeed, easy enough if the parent inline has a keep of "always"
[...]
One might argue that by violating the inner keep, we would also
violate the outer keep, and as such it makes no difference where the
violation occurs... On the other hand, I wonder whether the use-case
for such combinations would not precisely be to indicate to the
formatter: "If violating a keep is unavoidable, then this is where it
should preferably happen..."
Ok, you are for the "stronger keep wins" interpretation, and now I'm
convinced too.
At first, my doubt was that in this way we have an explicitly specified
value that gets "overridden" by another one specified on an *ancestor*
node. This seemed to me a strange exception to the general principle that
an explicit value overrides an inherited one, until I realized this is
quite similar to the space resolution rules, where the space set for an
object could win against one set in one of its descendants, because of its
higher precedence.
So, now I think that an inner keep with lesser force should not have any
effect.
Luca