Files

77 lines
3.1 KiB
Lua
Raw Permalink Normal View History

-- Copyright (c) 2026 Marc Wäckerlin. SPDX-License-Identifier: MIT
-- A picture that stands alone in its paragraph gets its caption under it.
--
-- `![Das Logo als Bild](logo.png)` carries a text between the brackets, and
-- every reader who writes it means it as the caption. GFM has no such rule: the
-- text becomes the alternative text of the picture, which reaches a screen
-- reader and nobody else, and the PDF shows a picture with nothing under it.
--
-- pandoc has the rule under the name implicit_figures, and its GFM reader does
-- not carry it, so the paragraph is turned into a figure here. What the figure
-- then looks like — where it stands, how the caption is set — comes from the
-- package like everything else.
-- A picture that stands directly under a heading does not float away from it.
--
-- A floating picture leaves the page it was written on, and where the heading
-- announced nothing but that picture, the heading stays behind alone at the
-- foot of the page. Measured over one report: a page ended with its heading,
-- 430 points of it still empty, and its picture began on the next. The
-- reservation a heading takes cannot answer this — the room was there, and what
-- should have filled it had left the page.
--
-- So this one picture is placed where it stands. It then either fits under its
-- heading, or the page breaks BEFORE the heading and the two travel together,
-- which is what a reader expects of a heading.
local function nailed(figure)
return {
pandoc.RawBlock('latex', '\\begingroup\\floatplacement{figure}{H}'),
figure,
pandoc.RawBlock('latex', '\\endgroup'),
}
end
function Blocks(blocks)
if not FORMAT:match('latex') then return nil end
local kept, previous = pandoc.Blocks{}, nil
for _, block in ipairs(blocks) do
if block.t == 'Figure' and previous and previous.t == 'Header' then
for _, piece in ipairs(nailed(block)) do
kept:insert(piece)
end
else
kept:insert(block)
end
previous = block
end
return kept
end
-- A picture of pixels says so, because only this side knows the file name.
--
-- How large a picture may be drawn is the package's rule, and it is not the
-- same rule for a drawing and for a photograph: a drawing is drawn again at
-- every size, a raster of pixels gets coarse. What the package sees is the
-- finished box, which carries no file name any more, so the mark is set here
-- and read by the picture that follows it.
local RASTER = {
png = true, jpg = true, jpeg = true, bmp = true,
gif = true, tif = true, tiff = true,
}
function Image(image)
if not FORMAT:match('latex') then return nil end
local extension = image.src:match('%.([%a%d]+)$')
if extension and RASTER[extension:lower()] then
return { pandoc.RawInline('latex', '\\businessbitmap'), image }
end
end
function Para(para)
if #para.content ~= 1 then return nil end
local image = para.content[1]
if image.t ~= 'Image' or #image.caption == 0 then return nil end
return pandoc.Figure(
pandoc.Blocks{ pandoc.Plain{ image } },
{ long = pandoc.Blocks{ pandoc.Plain(image.caption) } })
end