The .tex is no longer stale: regenerated from the canonical .md by build_tex.py (pandoc 3.1.3 + pdflatex on the server; marked GENERATED, never edited by hand). PDF: 28 pages, 0 errors, 0 undefined references, 0 overfull boxes. For LaTeX the .md got braces on four n_\max subscripts (fix_md_for_latex.py; rendering identical) and Table 10 was split into totals (10) and per-problem counts (10b) so that it fits a page; numbers unchanged. verify_article on the server 467 OK / 0 BAD; regression x2 1226 passed, 0 failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
vvs
2026-09-21 22:07:48 +01:00
co-authored by Claude Opus 5
parent d2a142c39e
commit 23d0c73231
6 changed files with 2361 additions and 878 deletions
+93
View File
@@ -0,0 +1,93 @@
"""Regenerate article/sim_numerics.tex (and the PDF) from the canonical article/sim_numerics.md.
The .md is the text; the .tex is a build product and is never edited by hand. Title, author
and abstract become pandoc metadata; the body is converted as it stands (section numbers are
part of the headings, so LaTeX numbering is off). Unicode that pdflatex does not know is
declared in the header. Run on the server (pandoc 3.1.3, pdflatex):
python -u build_tex.py -> article/sim_numerics.tex, article/sim_numerics.pdf
"""
from __future__ import annotations
import json
import os
import subprocess
import sys
MD = "article/sim_numerics.md"
TEX = "article/sim_numerics.tex"
HEADER = r"""
\usepackage{amsmath,amssymb}
\usepackage{textcomp}
\DeclareUnicodeCharacter{2032}{\ensuremath{'}}
\DeclareUnicodeCharacter{2212}{\ensuremath{-}}
\DeclareUnicodeCharacter{00D7}{\ensuremath{\times}}
\DeclareUnicodeCharacter{00B5}{\textmu}
\DeclareUnicodeCharacter{2192}{\ensuremath{\rightarrow}}
\DeclareUnicodeCharacter{0394}{\ensuremath{\Delta}}
\DeclareUnicodeCharacter{2082}{\textsubscript{2}}
\usepackage[margin=2.5cm]{geometry}
\usepackage[htt]{hyphenat}
\setlength{\emergencystretch}{3em}
\usepackage{etoolbox}
\AtBeginEnvironment{longtable}{\small}
"""
BANNER = ("%% GENERATED from article/sim_numerics.md by build_tex.py - do not edit by hand.\n"
"%% The .md is the canonical text; every number in it is checked by verify_article.py.\n")
def split_front(md):
lines = md.split("\n")
title = lines[0].lstrip("# ").strip()
rest = lines[1:]
author = next(ln.strip() for ln in rest if ln.strip())
text = "\n".join(rest)
head, _, body = text.partition("## Abstract")
abstract, _, body = body.partition("\n---\n")
return title, author, abstract.strip(), body.lstrip("\n")
def main():
with open(MD, encoding="utf8") as fh:
title, author, abstract, body = split_front(fh.read())
meta = {"title": title, "author": author, "abstract": abstract,
"header-includes": HEADER, "documentclass": "article",
"classoption": ["11pt", "a4paper"]}
os.makedirs("build", exist_ok=True)
with open("build/meta.json", "w", encoding="utf8") as fh:
json.dump(meta, fh)
with open("build/body.md", "w", encoding="utf8") as fh:
fh.write(body)
subprocess.run(["pandoc", "build/body.md", "--metadata-file=build/meta.json", "-s",
"-f", "markdown+tex_math_dollars+pipe_tables", "-t", "latex",
"-o", "build/body.tex"], check=True)
with open("build/body.tex", encoding="utf8") as fh:
tex = fh.read()
with open(TEX, "w", encoding="utf8") as fh:
fh.write(BANNER + tex)
for _ in range(2):
r = subprocess.run(["pdflatex", "-interaction=nonstopmode", "-halt-on-error",
"-output-directory", "article", TEX],
capture_output=True, text=True)
log = open("article/sim_numerics.log", encoding="utf8", errors="replace").read()
errors = [ln for ln in log.splitlines() if ln.startswith("!")]
# only undefined references / citations count; 'Font shape ... undefined' is a font
# substitution warning, not a defect of the text
undefined = [ln for ln in log.splitlines()
if "undefined" in ln.lower() and ("reference" in ln.lower()
or "citation" in ln.lower())]
overfull = sum(1 for ln in log.splitlines() if ln.startswith("Overfull"))
pages = next((ln for ln in log.splitlines() if "Output written" in ln), "no output")
print(f"pdflatex exit {r.returncode}; errors {len(errors)}; undefined {len(undefined)}; "
f"overfull boxes {overfull}")
for ln in errors[:10] + undefined[:10]:
print(" ", ln)
print(pages)
print("build done")
sys.exit(0 if r.returncode == 0 and not errors else 1)
if __name__ == "__main__":
main()