Skip to content

Commit

Permalink
fix(math): Avoid page breaks before display math equations
Browse files Browse the repository at this point in the history
See #2160.
This is a conservative workaround.
Introducing the predisplay/postdisplay penalties is the right thing to
do, but a more general solution to the full issue requires a more subtle
handling of in-paragraph display math equations, which is not considered
here.
  • Loading branch information
Omikhleia authored and Didier Willis committed Nov 9, 2024
1 parent 626fe7a commit aaec4b7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
25 changes: 25 additions & 0 deletions packages/math/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,31 @@ function package.declareSettings (_)
type = "VGlue",
default = SILE.types.node.vglue("2ex plus 1pt"),
})

-- Penalties for breaking before and after a display math formula
-- See TeX's \predisplaypenalty and \postdisplaypenalty
SILE.settings:declare({
parameter = "math.predisplaypenalty",
type = "integer",
default = 10000, -- strict no break by default as in (La)TeX
help = "Penalty for breaking before a display math formula",
})
SILE.settings:declare({
parameter = "math.postdisplaypenalty",
type = "integer",
-- (La)TeX's default is 0 (a normal line break penalty allowing a break
-- after a display math formula)
-- See https://github.com/sile-typesetter/sile/issues/2160
-- And see implementation in handleMath(): we are not yeat doing the right
-- things with respect to paragraphing, so setting a lower value for now
-- to ease breaking after a display math formula rather than before
-- when the formula is in the middle of a paragraph.
-- (In TeX, these penalties would apply in horizontal mode, with a display
-- math formula being a horizontal full-width box, our implementation
-- currently use them as vertical penalties).
default = -50,
help = "Penalty for breaking after a display math formula",
})
end

function package:registerCommands ()
Expand Down
16 changes: 14 additions & 2 deletions packages/math/typesetter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,15 @@ local function handleMath (_, mbox, options)
mbox:shapeTree()

if mode == "display" then
SILE.typesetter:endline()
-- See https://github.com/sile-typesetter/sile/issues/2160
-- We are not excactly doing the right things here with respect to
-- paragraphing expectations.
-- The vertical penalty will flush the previous paragraph, if any.
SILE.call("penalty", { penalty = SILE.settings:get("math.predisplaypenalty"), vertical = true })
SILE.typesetter:pushExplicitVglue(SILE.settings:get("math.displayskip"))
-- Repeating the penalty after the skip does not hurt but should not be
-- necessary if our page builder did its stuff correctly.
SILE.call("penalty", { penalty = SILE.settings:get("math.predisplaypenalty"), vertical = true })
SILE.settings:temporarily(function ()
-- Center the equation in the space available up to the counter (if any),
-- respecting the fixed part of the left and right skips.
Expand All @@ -233,9 +240,14 @@ local function handleMath (_, mbox, options)
elseif options.number then
SILE.call("math:numberingstyle", options)
end
SILE.typesetter:endline()
-- The vertical penalty will flush the equation.
-- It must be done in the temporary settings block, because these have
-- to apply as line boxes are being built.
SILE.call("penalty", { penalty = SILE.settings:get("math.postdisplaypenalty"), vertical = true })
end)
SILE.typesetter:pushExplicitVglue(SILE.settings:get("math.displayskip"))
-- Repeating: Same remark as for the predisplay penalty above.
SILE.call("penalty", { penalty = SILE.settings:get("math.postdisplaypenalty"), vertical = true })
else
SILE.typesetter:pushHorizontal(mbox)
end
Expand Down

0 comments on commit aaec4b7

Please sign in to comment.