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>
This commit is contained in:
Marc WäckerlinandClaude Opus 5 committed 2026-09-22 15:06:07 +02:00
commit adc58e19d7
39 files changed
+6627

No files matched your search

+340
View File
@@ -0,0 +1,340 @@
#!/usr/bin/env python3
"""The way from Markdown to the PDF of a company, measured at the PDF.
The converter is the second road into the same design, and the two have to end
in the same page: the same font, the same logo, the same table that fits the
line. What is measured here is the result and not the call.
"""
import os
import re
import shutil
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import support
from support import Check, Page
EXAMPLES = os.path.join(support.ROOT, "examples")
CONVERTER = os.path.join(support.ROOT, "bin", "md2pdf.py")
OUT = os.path.join(support.BUILD, "md2pdf")
def runnable(check):
"""The converter is called by its name, so it has to be executable.
The README describes exactly that way — a link in a directory of the PATH —
and a file without the bit ends in "Permission denied". Reported on
2026-09-21 from a company that had linked it and called it.
"""
check.that(os.access(CONVERTER, os.X_OK),
"bin/md2pdf.py carries no execute bit, so a link to it on the "
"PATH cannot be called by its name")
def convert(check):
shutil.rmtree(OUT, ignore_errors=True)
os.makedirs(OUT, exist_ok=True)
result = support.run(["python3", CONVERTER, "--identity",
"nordwind", "--out-dir", OUT, "--keep-tex",
os.path.join(EXAMPLES, "report.md")])
pdf = os.path.join(OUT, "report.pdf")
check.that(os.path.exists(pdf),
f"the converter produced no PDF:\n{result.stdout[-1500:]}")
return pdf
def measured(check):
"""The line and the character were measured, not taken from the fallback.
The numbers the filters compute a column width from belong to the paper, the
margins and the face of the company. They live outside TeX, in a Lua filter,
so the converter builds a probe with the identity of the company and reads
them out of it. Without the probe every company would compute with the
numbers of the company this suite came from.
"""
metrics = os.path.join(OUT, "build", "metrics.txt")
check.that(os.path.exists(metrics),
"the converter wrote no measurement of the line")
if not os.path.exists(metrics):
return
with open(metrics, encoding="utf-8") as handle:
found = dict(re.findall(r"^(\w+) ([0-9.]+)pt$", handle.read(),
re.MULTILINE))
check.that("linewidth" in found, "the probe measured no line width")
if "linewidth" not in found:
return
# A4 is 597.5 points wide and the template keeps 1cm on each side, so the
# line is 540 points give or take the rounding of the paper.
width = float(found["linewidth"])
check.that(530 < width < 545,
f"the measured line is {width} points wide, which is not the "
"type area of an A4 page with the margins of this template")
def inside(check, pdf):
"""Nothing of the document stands outside the type area.
A Markdown table says nothing about its column widths, and without the
filter LaTeX writes the last words of a wide table past the edge of the
paper.
"""
page = Page(pdf, 1)
factor = 72.0 / page.dpi
columns = page.ink_columns()
right = columns[-1] * factor
left = columns[0] * factor
# The paper is 595 points wide and the template keeps 1cm, 28.35 points, on
# each side. Half a point of tolerance for the rounding of the raster.
check.that(left > 27, f"ink stands {left:.1f} points from the left edge, "
"inside the margin")
check.that(right < 568, f"ink reaches {right:.1f} points, past the right "
"margin of the page")
def content(check, pdf):
text = support.text(pdf)
check.that("Lorem Ipsum" in text, "the title block did not arrive")
check.that("Consetetur sadipscing elitr" in text and "41'820" in text,
"the table did not arrive")
# The path in the running text is broken at the characters that structure
# it, so it stays inside the line. What arrives in the text layer is the
# path with its pieces, never a line that runs past the margin.
check.that("business-identity.sty" in text.replace("\n", ""),
"the path in the running text did not arrive")
faces = support.fonts(pdf)
check.that(any("DejaVu" in face for face in faces),
f"the marks did not reach the page: {faces}")
# A formula in the three ways a writer writes one, and a fourth that is none:
# inside a fenced code block the dollars are an example of themselves and stay
# on the page as text.
FORMULA = """---
title: Formula
author: Erika Muster
---
# Consetetur
Inline $E = mc^2$ in a sentence.
$$a = \\frac{b}{c}$$
$$
\\text{Ratio}
=
\\frac{\\text{Nutzen}}
{\\text{Kosten}}
$$
```text
$$
x
=
y
$$
```
"""
def formula(check):
"""A formula arrives as a formula, also written over several lines.
The grammar of the reader sees a line carrying nothing but `=` as the
underline of a heading, so a formula over several lines used to come out as
a heading of the first level with the dollars in it, and the build stayed
green. Reported on 2026-09-21 from another company of this family, which
built a twelve-page analysis with the formula standing as a green heading.
"""
path = os.path.join(support.BUILD, "formula.md")
os.makedirs(support.BUILD, exist_ok=True)
with open(path, "w", encoding="utf-8") as handle:
handle.write(FORMULA)
result = support.run(["python3", CONVERTER, "--identity", "nordwind",
"--out-dir", OUT, "--keep-tex", path])
pdf = os.path.join(OUT, "formula.pdf")
check.that(os.path.exists(pdf),
f"the document with the formula did not build:\n"
f"{result.stdout[-1500:]}")
if not os.path.exists(pdf):
return
text = support.text(pdf)
# The dollars of a formula never reach the page; the ones in the code block
# do, and they are the proof that nothing was repaired in there.
body = text.split("$$")[0] if "$$" in text else text
check.that(text.count("$$") == 2,
f"the page carries {text.count('$$')} rows of dollars, and only "
"the two of the code block belong there")
check.that("Ratio" in body and "Nutzen" in body,
"the formula over several lines did not arrive as a formula")
check.that("Kosten" in body, "the second half of the formula is missing")
faces = support.fonts(pdf)
check.that(any("Math" in face or "math" in face for face in faces),
f"no mathematics face on a page with three formulas: {faces}")
# The same document twice: once written in Markdown, once in LaTeX. A document
# looks the same whichever road it takes, so the two pages carry their ink in
# the same places.
TWIN_BODY = (
("Consetetur", "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, "
"sed diam nonumy eirmod tempor invidunt ut labore et dolore magna "
"aliquyam erat."),
("Dolor Sit", "Stet clita kasd gubergren, no sea takimata sanctus est "
"Lorem ipsum dolor sit amet."),
("Sadipscing Elitr", "At vero eos et accusam et justo duo dolores et ea "
"rebum."),
)
TWIN_MD = "---\ntitle: Lorem Ipsum\nauthor: Erika Muster\ndate: 21 September 2026\n---\n\n" \
+ "\n".join(f"{'#' * (level + 1)} {head}\n\n{text}\n"
for level, (head, text) in enumerate(TWIN_BODY))
TWIN_TEX = r"""\documentclass[a4paper,10pt]{article}
\usepackage{nordwind}
\title{Lorem Ipsum}
\author{Erika Muster}
\date{21 September 2026}
\begin{document}
\maketitle
""" + "\n".join(
"\\%s{%s}\n\n%s\n" % (("section", "subsection", "subsubsection")[level],
head, text)
for level, (head, text) in enumerate(TWIN_BODY)) + r"""
\end{document}
"""
def bands(pdf):
"""The rows of ink of the first page, grouped into blocks, in points."""
page = Page(pdf, 1)
factor = 72.0 / page.dpi
grouped, current = [], []
for row in page.ink_rows():
if current and row - current[-1] > 1:
grouped.append((current[0] * factor, current[-1] * factor))
current = []
current.append(row)
if current:
grouped.append((current[0] * factor, current[-1] * factor))
return grouped
# A picture out of Markdown: the same rules as one written in LaTeX, and the
# converter is what says which of them is a raster of pixels.
PICTURE_MD = """---
title: Lorem Ipsum
author: Erika Muster
---
## Consetetur
![Lorem ipsum dolor sit amet](example-image-16x9.pdf)
## Dolor Sit
![Consetetur sadipscing elitr](example-image-a.png)
"""
def pictures(check):
"""A picture out of Markdown takes the size of the family.
The converter hands every picture to pandoc's own bound, and that is where
the rules of the template hang: the lying picture on the first page takes
the whole line, the raster one on the second is the one the converter marks
as pixels, and both stand centred.
"""
path = support.write("picture.md", PICTURE_MD)
result = support.run(["python3", CONVERTER, "--identity", "nordwind",
"--out-dir", OUT, path])
pdf = os.path.join(OUT, "picture.pdf")
check.that(os.path.exists(pdf),
f"the document with the pictures did not build:\n"
f"{result.stdout[-1000:]}")
if not os.path.exists(pdf):
return
for number, name in ((1, "lying"), (2, "raster")):
page = Page(pdf, number)
factor = 72.0 / page.dpi
rows = page.ink_rows()
check.that(rows, f"the {name} picture is not on page {number}")
if not rows:
continue
grouped, current = [], []
for row in rows:
if current and row - current[-1] > 1:
grouped.append(current)
current = []
current.append(row)
grouped.append(current)
tallest = max(grouped, key=lambda band: band[-1] - band[0])
columns = page.ink_columns(tallest[0], tallest[-1] + 1)
width = (columns[-1] - columns[0] + 1) * factor
left = columns[0] * factor
right = page.width * factor - columns[-1] * factor
check.that(width <= 545,
f"the {name} picture is {width:.1f} points wide, more than "
"the 540.6 of the line")
check.that(abs(left - right) < 4,
f"the {name} picture stands {left:.1f} points from the left "
f"edge and {right:.1f} from the right, so it is not centred")
def twins(check):
"""A document out of Markdown is the document out of LaTeX.
Both roads end in the same template, so the same content has to stand in
the same places: same distances under the title block, same three lines
over every heading, same line for every paragraph.
"""
md = support.write("twin.md", TWIN_MD)
result = support.run(["python3", CONVERTER, "--identity", "nordwind",
"--out-dir", OUT, md])
converted = os.path.join(OUT, "twin.pdf")
check.that(os.path.exists(converted),
f"the twin out of Markdown did not build:\n"
f"{result.stdout[-1000:]}")
written, _ = support.build(support.write("twin.tex", TWIN_TEX), EXAMPLES)
if not os.path.exists(converted):
return
out_of_md, out_of_tex = bands(converted), bands(written)
check.that(len(out_of_md) == len(out_of_tex),
f"the page out of Markdown carries {len(out_of_md)} blocks of "
f"ink and the one out of LaTeX {len(out_of_tex)}")
if len(out_of_md) != len(out_of_tex):
return
worst = max(abs(a[0] - b[0]) for a, b in zip(out_of_md, out_of_tex))
check.that(worst < 1,
f"a block of the page stands {worst:.1f} points lower out of "
"Markdown than out of LaTeX")
def missing(check):
"""A document that does not exist ends in a message and never in a PDF."""
result = support.run(["python3", CONVERTER, "--identity",
"nordwind", "--out-dir", OUT,
os.path.join(OUT, "gibtesnicht.md")])
check.that(result.returncode != 0,
"the converter reported success for a file that does not exist")
check.that("gibtesnicht.md" in result.stdout,
"the message does not name the file that is missing")
check.that(not os.path.exists(os.path.join(OUT, "gibtesnicht.pdf")),
"the converter produced a PDF for a file that does not exist")
def main():
check = Check("md2pdf")
runnable(check)
pdf = convert(check)
if os.path.exists(pdf):
measured(check)
inside(check, pdf)
content(check, pdf)
formula(check)
pictures(check)
twins(check)
missing(check)
return check.done()
if __name__ == "__main__":
sys.exit(main())