Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(math): Avoid page breaks before display math equations #2162

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 yet 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
Loading