Skip to content

Commit

Permalink
refactor(pagebuilders): Move grid pagebuilder to first class module
Browse files Browse the repository at this point in the history
  • Loading branch information
alerque committed Dec 10, 2022
1 parent f4ad240 commit 1e171ec
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 72 deletions.
79 changes: 7 additions & 72 deletions packages/grid/init.lua
Expand Up @@ -3,6 +3,8 @@ local base = require("packages.base")
local package = pl.class(base)
package._name = "grid"

local oldPagebuilderType, oldTypesetterType

local function startGridInFrame (typesetter)
if not SILE.typesetter.state.grid then return end -- Ensure the frame hook isn't effective when grid is off
local queue = typesetter.state.outputQueue
Expand All @@ -20,73 +22,6 @@ local function startGridInFrame (typesetter)
end
end

local gridPagebuilder = pl.class(SILE.pagebuilders.base)
gridPagebuilder._name = "grid"

function gridPagebuilder:_init()
SILE.pagebuilders.base._init()
end

function gridPagebuilder.findBestBreak (_, options)
local vboxlist = SU.required(options, "vboxlist", "in findBestBreak")
local target = SU.required(options, "target", "in findBestBreak")
local i = 0
local totalHeight = SILE.length()
local bestBreak = 0
SU.debug("pagebuilder", "Page builder for frame", SILE.typesetter.frame.id, "called with", #vboxlist, "nodes,", target)
if SU.debugging("vboxes") then
for j, box in ipairs(vboxlist) do
SU.debug("vboxes", (j == i and " >" or " ") .. j .. ": " .. box)
end
end
while i < #vboxlist do
i = i + 1
if not vboxlist[i].is_vglue then
i = i - 1
break
end
end
while i < #vboxlist do
i = i + 1
local node = vboxlist[i]
SU.debug("pagebuilder", "Dealing with VBox", node)
if node.is_vbox then
totalHeight = totalHeight + node.height:absolute() + node.depth:absolute()
elseif node.is_vglue then
totalHeight = totalHeight + node.height:absolute()
elseif node.is_insertion then
-- TODO: refactor as hook and without side effects!
target = SILE.insertions.processInsertion(vboxlist, i, totalHeight, target)
node = vboxlist[i]
end
local left = target - totalHeight
local _left = left:tonumber()
SU.debug("pagebuilder", "I have", left, "left")
SU.debug("pagebuilder", "totalHeight", totalHeight, "with target", target)
local badness = 0
if _left < 0 then badness = 1000000 end
if node.is_penalty then
if node.penalty < -3000 then badness = 100000
else badness = -_left * _left - node.penalty
end
end
if badness > 0 then
local onepage = {}
for j = 1, bestBreak do
onepage[j] = table.remove(vboxlist, 1)
end
while #onepage > 1 and onepage[#onepage].discardable do
onepage[#onepage] = nil
end
return onepage, 1000
end
bestBreak = i
end
return false, false
end

local oldPageBuilder, oldLeadingFor, oldPushVglue, oldPushExplicitVglue

function package:_init (options)
self.options = options or {}
self.options.spacing = SILE.measurement(self.options.spacing or "1bs")
Expand All @@ -109,13 +44,13 @@ function package:registerCommands ()
SILE.typesetter:registerNewFrameHook(debugGrid)
end)

-- TODO: save original typsetter and pagebuilter class types, recast them
-- to the original types instead of assuming defaults when disabling grid
self:registerCommand("grid", function (options, _)
local spacing = SU.cast("measurement", options.spacing or self.options.spacing)
SILE.typesetter.state.grid = true
self.options.spacing = SILE.parseComplexFrameDimension(spacing)
gridPagebuilder:cast(SILE.pagebuilder)
oldPagebuilderType = SILE.pagebuilder._name
oldTypesetterType = SILE.typesetter._name
SILE.pagebuilders.grid:cast(SILE.pagebuilder)
SILE.typesetters.grid:cast(SILE.typesetter)
SILE.typesetter.options = { spacing = self.options.spacing }
if SILE.typesetter.frame then
Expand All @@ -126,8 +61,8 @@ function package:registerCommands ()

self:registerCommand("no-grid", function (_, _)
SILE.typesetter.state.grid = false
SILE.typesetters.base:cast(SILE.typesetter)
SILE.pagebuilders.base:cast(pagebuilder)
SILE.typesetters[oldTypesetterType]:cast(SILE.typesetter)
SILE.pagebuilders[oldPagebuilderType]:cast(SILE.pagebuilder)
end, "Stops grid typesetting.")

end
Expand Down
68 changes: 68 additions & 0 deletions pagebuilders/grid.lua
@@ -0,0 +1,68 @@
local base = require("pagebuilders.base")

local pagebuilder = pl.class(base)
pagebuilder._name = "grid"

function pagebuilder:_init()
base._init(self)
end

function pagebuilder.findBestBreak (_, options)
local vboxlist = SU.required(options, "vboxlist", "in findBestBreak")
local target = SU.required(options, "target", "in findBestBreak")
local i = 0
local totalHeight = SILE.length()
local bestBreak = 0
SU.debug("pagebuilder", "Page builder for frame", SILE.typesetter.frame.id, "called with", #vboxlist, "nodes,", target)
if SU.debugging("vboxes") then
for j, box in ipairs(vboxlist) do
SU.debug("vboxes", (j == i and " >" or " ") .. j .. ": " .. box)
end
end
while i < #vboxlist do
i = i + 1
if not vboxlist[i].is_vglue then
i = i - 1
break
end
end
while i < #vboxlist do
i = i + 1
local node = vboxlist[i]
SU.debug("pagebuilder", "Dealing with VBox", node)
if node.is_vbox then
totalHeight = totalHeight + node.height:absolute() + node.depth:absolute()
elseif node.is_vglue then
totalHeight = totalHeight + node.height:absolute()
elseif node.is_insertion then
-- TODO: refactor as hook and without side effects!
target = SILE.insertions.processInsertion(vboxlist, i, totalHeight, target)
node = vboxlist[i]
end
local left = target - totalHeight
local _left = left:tonumber()
SU.debug("pagebuilder", "I have", left, "left")
SU.debug("pagebuilder", "totalHeight", totalHeight, "with target", target)
local badness = 0
if _left < 0 then badness = 1000000 end
if node.is_penalty then
if node.penalty < -3000 then badness = 100000
else badness = -_left * _left - node.penalty
end
end
if badness > 0 then
local onepage = {}
for j = 1, bestBreak do
onepage[j] = table.remove(vboxlist, 1)
end
while #onepage > 1 and onepage[#onepage].discardable do
onepage[#onepage] = nil
end
return onepage, 1000
end
bestBreak = i
end
return false, false
end

return pagebuilder

0 comments on commit 1e171ec

Please sign in to comment.