MachineSex/paper/manuscript/build_lay_legends.py
Giorgio Gilestro ab3dc10587 Restructure: descriptive tier and experiment names, paper/manuscript
- paper/pnas -> paper/manuscript (venue-neutral)
- configs/layer1 -> configs/inheritance, src/knowledge -> src/inheritance
  (imported as `inheritance`), make layer1 -> make inheritance; layer2 alias dropped
- inheritance and trained-network bundles named after the manuscript figure
  they feed (fig2_grounding_sweep, figS3_rebaselining, ...), or descriptively
  where they feed none; configs keep their `experiment:` value so parquet
  hashes are unchanged, only output.dir moves
- figure scripts, SI figure sources, notebooks, REPRODUCING.md, README and the
  SI Methods/tables updated; make clean no longer deletes tracked manifests;
  reproduce.sh hashes the s{seed}/ layouts too

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y64o8FKP7rCuXzC48pxpMm
2026-09-13 17:00:40 +01:00

61 lines
2.4 KiB
Python

"""Build the student-level figure guide (figure_legends_for_students.md -> .tex -> PDF).
The Markdown is the source of truth. Lines of the form ``![](path.pdf)`` become figure includes
(paths relative to paper/manuscript/); ``## `` headings become unnumbered sections; everything else goes
through build.py's inline() converter, so the same Markdown subset and unicode handling apply.
Usage: python paper/manuscript/build_lay_legends.py && (cd paper/manuscript && tectonic figure_legends_for_students.tex)
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
from build import inline # noqa: E402
SRC = HERE / "figure_legends_for_students.md"
OUT = HERE / "figure_legends_for_students.tex"
PREAMBLE = r"""\ifdefined\XeTeXversion\else\ifdefined\pdfoutput\pdfoutput=1\fi\fi
\documentclass[11pt]{article}
\usepackage[a4paper, margin=1.0in]{geometry}
\usepackage{graphicx}
\usepackage{amsmath, amssymb}
\usepackage[hidelinks]{hyperref}
\usepackage{microtype}
\setlength{\parskip}{0.5em}
\setlength{\parindent}{0pt}
\begin{document}
"""
def convert(text: str) -> str:
out: list[str] = []
blocks = [b for b in re.split(r"\n\s*\n", text) if b.strip()]
for block in blocks:
first = block.strip()
if first.startswith("# ") and not first.startswith("## "):
out.append(f"\\begin{{center}}{{\\LARGE\\bfseries {inline(first[2:])}}}\\end{{center}}")
elif first.startswith("## "):
out.append(f"\\section*{{{inline(first[3:])}}}")
elif first == "---":
out.append("\\medskip\\hrule\\medskip")
elif re.match(r"^!\[\]\((.+)\)$", first):
path = re.match(r"^!\[\]\((.+)\)$", first).group(1)
assert (HERE / path).exists(), f"missing figure {path}"
out.append(f"\\begin{{center}}\\includegraphics[width=\\textwidth]{{{path}}}\\end{{center}}")
elif first.startswith("- "):
items = [re.sub(r"^- ", "", l.strip()) for l in block.split("\n") if l.strip().startswith("- ")]
out.append("\\begin{itemize}\n" + "\n".join(f"\\item {inline(i)}" for i in items) + "\n\\end{itemize}")
else:
out.append(inline(re.sub(r"\s+", " ", block.strip())))
return PREAMBLE + "\n\n".join(out) + "\n\\end{document}\n"
if __name__ == "__main__":
OUT.write_text(convert(SRC.read_text()))
print(f"wrote {OUT}")