64 lines
2.6 KiB
Lua
64 lines
2.6 KiB
Lua
-- Copyright (c) 2026 Marc Wäckerlin. SPDX-License-Identifier: MIT
|
|||
|
|
-- A sentence that announces a table or a list keeps it on its page.
|
||
|
|
--
|
||
|
|
-- "The numbers at a glance:" stands as the last line of a page while the table
|
||
|
|
-- it announces begins on the next one. It is the case of the heading in another
|
||
|
|
-- shape, and the penalty that answers the heading does not answer this one: a
|
||
|
|
-- longtable decides at its own start whether its head and its first row still
|
||
|
|
-- fit and breaks the page itself, past every penalty behind the sentence. The
|
||
|
|
-- room has to stand in FRONT of the sentence, and how much room that is comes
|
||
|
|
-- from the package, which learns it from the table.
|
||
|
|
--
|
||
|
|
-- What marks such a sentence is the colon it ends with together with what
|
||
|
|
-- follows it: a table or a list of any kind. A sentence that ends in a colon
|
||
|
|
-- and is followed by a paragraph announces nothing that can be torn from it.
|
||
|
|
--
|
||
|
|
-- This filter runs BEFORE the one that gives a table its column widths, because
|
||
|
|
-- that one wraps a table in a group of its own and the table would then no
|
||
|
|
-- longer be what follows the sentence.
|
||
|
|
local ANNOUNCED = {
|
||
|
|
Table = true,
|
||
|
|
BulletList = true,
|
||
|
|
OrderedList = true,
|
||
|
|
DefinitionList = true,
|
||
|
|
}
|
||
|
|
|
||
|
|
-- The one thing counted here is how many lines the SENTENCE takes, because a
|
||
|
|
-- sentence is a text and nothing in the package can know it. What the block
|
||
|
|
-- under it needs to begin is measured by the package: a table at the table
|
||
|
|
-- itself, through the aux file, and a list against the floor the package sets.
|
||
|
|
-- So nothing is added for it here.
|
||
|
|
--
|
||
|
|
-- How many characters a line holds is measured and arrives in the environment,
|
||
|
|
-- the same two numbers the table filter uses; the fallback is the measurement
|
||
|
|
-- of the origin of this family.
|
||
|
|
local LINE = (tonumber(os.getenv('MD2PDF_LINEWIDTH')) or 538)
|
||
|
|
/ (tonumber(os.getenv('MD2PDF_CHARACTER')) or 5.3)
|
||
|
|
|
||
|
|
local function lines(block)
|
||
|
|
local length = #pandoc.utils.stringify(block)
|
||
|
|
return math.max(1, math.ceil(length / LINE))
|
||
|
|
end
|
||
|
|
|
||
|
|
local function announces(block, following)
|
||
|
|
if block.t ~= 'Para' or not following or not ANNOUNCED[following.t] then
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
return pandoc.utils.stringify(block):match(':%s*$') ~= nil
|
||
|
|
end
|
||
|
|
|
||
|
|
function Blocks(blocks)
|
||
|
|
if not FORMAT:match('latex') then return nil end
|
||
|
|
local kept = pandoc.Blocks{}
|
||
|
|
for index, block in ipairs(blocks) do
|
||
|
|
if announces(block, blocks[index + 1]) then
|
||
|
|
kept:insert(pandoc.RawBlock(
|
||
|
|
'latex', '\\businessleadin[' .. lines(block) .. ']'))
|
||
|
|
kept:insert(block)
|
||
|
|
kept:insert(pandoc.RawBlock('latex', '\\businesstogether'))
|
||
|
|
else
|
||
|
|
kept:insert(block)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
return kept
|
||
|
|
end
|