Files
Marc WäckerlinandClaude Opus 5 adc58e19d7 One LaTeX design for a company, in three templates
A company that writes with LaTeX ends up with a document class, a letter class
and a presentation theme that share a design and not a line of code. Every fix
is then made three times, two of them late and the third never.

Here the page is written once. A company declares its colours, faces and logo in
one file, and the document template, the letter class and the presentation theme
read that one file. Nothing in the suite carries a colour value, a font name or
a file name of any company, which is what lets it be published while the
companies stay private.

Every measure of the page follows from a measurement or from a named definition:
the room the head and the foot need is taken from the boxes they really build,
one line of the body text stands between the head and the text and between the
text and the foot, a heading never stands alone at the foot of a page, a picture
takes the size of the family, and a Markdown file reaches the same page as the
same document written in LaTeX.

The suite ships with a company that does not exist, Nordwind AG, so that it
builds and is measured anywhere: three colours, the TeX Gyre families every
installation carries, and an icon drawn in TikZ.

574 checks over five measurements, all of them on the rendered page or on the
build log rather than on the source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 15:06:07 +02:00

65 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