Skip to content

Commit

Permalink
feat(footnotes): add typesetFootnotes function to handle footnote lay…
Browse files Browse the repository at this point in the history
…out and splitting
  • Loading branch information
no-vici committed Jan 15, 2025
1 parent 8e4c26b commit 77787ab
Showing 1 changed file with 113 additions and 1 deletion.
114 changes: 113 additions & 1 deletion packages/parallel/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,118 @@ local function getFootnoteHeight(frame, note, typesetter)
return noteHeight, noteQueue
end

local typesetFootnotes = function()
for frame, notes in pairs(footnotes) do
if notes and #notes > 0 then
SU.debug(package._name, "Processing footnotes for frame: " .. frame)

local typesetter = footnotePool[frame]
typesetter:initFrame(typesetter.frame)
SILE.typesetter = typesetter

-- Add a rule above the footnotes
SILE.call("parallel_footnote:rule")

local nextPageNotes = {}

SILE.settings:temporarily(function()
SILE.call("break") -- To prevent the firt footnote being streched across the frame

local targetHeight = typesetter:getTargetLength():tonumber()
local currentHeight = 0
local baselineSkip = SILE.settings:get("document.baselineskip").height:tonumber() * 0.30

for i, note in ipairs(notes) do
-- Get the cached or calculated height and simulated noteQueue
local noteHeight, noteQueue = getFootnoteHeight(frame, note, typesetter)

-- Adjust for baseline skip
if i > 1 then
noteHeight = noteHeight + baselineSkip
end

if currentHeight + noteHeight <= targetHeight then
-- Add baseline skip before adding the note (except the first note)
if i > 1 then
table.insert(typesetter.state.outputQueue, SILE.types.node.vglue(SILE.types.length(baselineSkip)))
end

-- Note fits entirely
currentHeight = currentHeight + noteHeight
for _, node in ipairs(noteQueue) do
table.insert(typesetter.state.outputQueue, node)
end
else
-- Note needs to be split
local fittedQueue = {}
local remainingQueue = {}
local fittedHeight = 0

for _, node in ipairs(noteQueue) do
local nodeHeight = node.height:absolute():tonumber() + node.depth:absolute():tonumber()
if fittedHeight + nodeHeight <= (targetHeight - currentHeight) then
table.insert(fittedQueue, node)
fittedHeight = fittedHeight + nodeHeight
else
-- Whatever does not fit is sent to the remaining queue
table.insert(remainingQueue, node)
end
end

-- Flush noteQueue from the memory for optimization
noteQueue = nil

-- Add fitted part to the current frame
if #typesetter.state.outputQueue > 0 then
table.insert(typesetter.state.outputQueue, SILE.types.node.vglue(SILE.types.length(baselineSkip)))
end

currentHeight = currentHeight + fittedHeight
for _, node in ipairs(fittedQueue) do
table.insert(typesetter.state.outputQueue, node)
end

-- Typeset the fitted part to the current frame
typesetter:outputLinesToPage(typesetter.state.outputQueue)

-- Reset output queue and move on
typesetter.state.outputQueue = {}

-- Create a new "split" note and add notes to the next page
if #remainingQueue > 0 then
local contentFunc = function()
for _, node in ipairs(remainingQueue) do
table.insert(SILE.typesetter.state.outputQueue, node)
end
end
table.insert(nextPageNotes, {
-- Suppress the footnote marker for the overflowed note
marker = "",
content = contentFunc,
})
end
end
end

-- Output any remaining content
if typesetter.state.outputQueue and #typesetter.state.outputQueue > 0 then
typesetter:outputLinesToPage(typesetter.state.outputQueue)
else
SU.warn("No content to output for frame: " .. frame)
end

-- Add remaining notes to the next page
footnotes[frame] = nextPageNotes

-- Reset output queue after typesetting the remaining footnote content
typesetter.state.outputQueue = {}
end)
else
SU.debug(package._name, "No footnotes to process for frame: " .. frame)
end
end
end

-- Handles page-breaking logic for parallel frames.
local parallelPagebreak = function()
for _, thisPageFrames in ipairs(folioOrder) do
Expand Down Expand Up @@ -188,7 +300,7 @@ local parallelPagebreak = function()
end)

-- Process footnotes before page break
-- typesetFootnotes()
typesetFootnotes()

-- End the current page
SILE.documentState.documentClass:endPage()
Expand Down

0 comments on commit 77787ab

Please sign in to comment.