-- 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