| author | Alan Dipert
<alan@dipert.org> 2025-12-06 18:27:38 UTC |
| committer | Alan Dipert
<alan@dipert.org> 2025-12-06 18:27:38 UTC |
| parent | 66b208f3965f370d22a3141b586246b36e466312 |
| generator.py | +1 | -1 |
| main.py | +3 | -3 |
| render_text.py | +39 | -14 |
diff --git a/generator.py b/generator.py index 4cedb33..4f2b0f5 100644 --- a/generator.py +++ b/generator.py @@ -586,7 +586,7 @@ def generate_test( } ) - proword = {"easy": "ECHO", "medium": "FOXTROT", "hard": "GOLF", "extreme": "HOTEL"}[hardness] + proword = {"easy": "MAPLE", "medium": "CEDAR", "hard": "CYPRESS", "extreme": "SEQUOIA"}[hardness] meta = { "version": "backtrack-0.2", "description": "Alan's Language Aptitude iNstrument (ALAN) synthesized via backtracking search", diff --git a/main.py b/main.py index fe95dcb..bf41fa7 100644 --- a/main.py +++ b/main.py @@ -26,9 +26,9 @@ def parse_args() -> argparse.Namespace: ) parser.add_argument( "--profile", - choices=["ECHO", "FOXTROT", "GOLF", "HOTEL"], + choices=["MAPLE", "CEDAR", "CYPRESS", "SEQUOIA"], default=None, - help="Alias for hardness without revealing labels in output (ECHO=easy, FOXTROT=medium, GOLF=hard, HOTEL=extreme).", + help="Alias for hardness without revealing labels in output (MAPLE=easy, CEDAR=medium, CYPRESS=hard, SEQUOIA=extreme).", ) parser.add_argument( "--run-dir", @@ -54,7 +54,7 @@ def _git_sha() -> str | None: def main() -> None: args = parse_args() - proword_map = {"ECHO": "easy", "FOXTROT": "medium", "GOLF": "hard", "HOTEL": "extreme"} + proword_map = {"MAPLE": "easy", "CEDAR": "medium", "CYPRESS": "hard", "SEQUOIA": "extreme"} hardness = args.hardness if args.profile: hardness = proword_map[args.profile] diff --git a/render_text.py b/render_text.py index 7edaa0b..c11e9a9 100644 --- a/render_text.py +++ b/render_text.py @@ -141,7 +141,7 @@ def _booklet_latex(data: Dict[str, Any]) -> str: lines = [ r"\documentclass[10pt]{article}", - r"\usepackage[margin=0.75in]{geometry}", + r"\usepackage[margin=0.65in]{geometry}", r"\usepackage[T1]{fontenc}", r"\usepackage[scaled=0.95]{helvet}", r"\usepackage{microtype}", @@ -151,29 +151,41 @@ def _booklet_latex(data: Dict[str, Any]) -> str: r"\setlength{\parskip}{4pt}", r"\setlength{\parindent}{0pt}", r"\setlist[itemize]{leftmargin=*,itemsep=2pt,topsep=2pt}", + r"\usepackage{xcolor}", + r"\usepackage{fancyhdr}", + r"\pagestyle{fancy}", + r"\fancyhf{}", + r"\fancyhead[L]{ALAN}", + r"\fancyhead[R]{" + + (r"\texttt{" + "; ".join(safe_bits) + r"}" if header_line else "") + + r"}", + r"\fancyfoot[R]{\thepage}", r"\begin{document}", - r"\section*{Alan's Language Aptitude iNstrument (ALAN)}", + r"\begin{center}", + r"{\Large\bfseries Alan's Language Aptitude iNstrument (ALAN)}\\[4pt]", + (header_line if header_line else ""), + r"\rule{0.9\linewidth}{0.4pt}", + r"\end{center}", ] - if header_line: - lines.append(header_line) if meta.get("instructions"): - lines.append(_tex_escape(meta["instructions"])) + lines.append(r"{\color{gray}" + _tex_escape(meta["instructions"]) + r"}") if meta.get("rules"): - lines.append(r"\subsection*{Grammar Cheat Sheet}") - lines.append(r"\begin{itemize}") + lines.append(r"\subsection*{\color{gray}Grammar Cheat Sheet}") + lines.append(r"\begin{itemize}[leftmargin=1em]") for rule in meta["rules"]: lines.append(rf"\item {_tex_escape(rule)}") lines.append(r"\end{itemize}") dict_data = meta.get("dictionary", {}) if dict_data: - lines.append(r"\subsection*{Starter Dictionary}") + lines.append(r"\vspace{4pt}\rule{0.9\linewidth}{0.2pt}") + lines.append(r"\subsection*{\color{gray}Starter Dictionary}") for title, group in [ ("Nouns", dict_data.get("nouns", {})), ("Verbs", dict_data.get("verbs", {})), ("Adjectives", dict_data.get("adjectives", {})), ]: lines.append(rf"\paragraph*{{{_tex_escape(title)}}}") - lines.append(r"\begin{itemize}") + lines.append(r"\begin{itemize}[leftmargin=1em]") for eng, lang in group.items(): lines.append(rf"\item {_tex_escape(eng)} = {_tex_escape(lang)}") lines.append(r"\end{itemize}") @@ -187,12 +199,13 @@ def _booklet_latex(data: Dict[str, Any]) -> str: lines.append(r"") lines.append(r"") for q in section.get("questions", []): - lines.append(r"\needspace{12\baselineskip}") - lines.append(rf"\noindent\textbf{{{q['number']}. {_tex_escape(q['stem'])}}}") - lines.append(r"\begin{itemize}[leftmargin=1.25em]") + lines.append(r"\needspace{14\baselineskip}") + lines.append(rf"\noindent\textbf{{{q['number']}.}} {_tex_escape(q['stem'])}") + lines.append(r"\begin{itemize}[leftmargin=1.5em]") for opt in q.get("options", []): lines.append(rf"\item[{_tex_escape(opt['label'])})] {_tex_escape(opt['text'])}") lines.append(r"\end{itemize}") + lines.append(r"\vspace{4pt}") lines.append(r"\end{document}") return "\n".join(lines) @@ -200,16 +213,22 @@ def _booklet_latex(data: Dict[str, Any]) -> str: def _key_latex(data: Dict[str, Any]) -> str: lines = [ r"\documentclass[10pt]{article}", - r"\usepackage[margin=0.75in]{geometry}", + r"\usepackage[margin=0.65in]{geometry}", r"\usepackage[T1]{fontenc}", r"\usepackage[scaled=0.95]{helvet}", r"\usepackage{microtype}", r"\usepackage{enumitem}", r"\usepackage{needspace}", + r"\usepackage{xcolor}", + r"\usepackage{fancyhdr}", r"\renewcommand{\familydefault}{\sfdefault}", r"\setlength{\parskip}{4pt}", r"\setlength{\parindent}{0pt}", r"\setlist[itemize]{leftmargin=*,itemsep=2pt,topsep=2pt}", + r"\pagestyle{fancy}", + r"\fancyhf{}", + r"\fancyhead[L]{ALAN}", + r"\fancyfoot[R]{\thepage}", r"\begin{document}", r"\section*{Answer Key}", ] @@ -267,6 +286,11 @@ def main() -> None: args = parse_args() with open(args.in_path, "r", encoding="utf-8") as f: data = json.load(f) + run_dir = data.get("meta", {}).get("run_dir") + if args.test_pdf is None and run_dir: + args.test_pdf = os.path.join(run_dir, "test_booklet.pdf") + if args.key_pdf is None and run_dir: + args.key_pdf = os.path.join(run_dir, "answer_key.pdf") booklet_text = render_booklet(data) key_text = render_key(data) with open(args.test_out, "w", encoding="utf-8") as f: @@ -277,7 +301,6 @@ def main() -> None: _write_pdf(_booklet_latex(data), args.test_pdf) if args.key_pdf: _write_pdf(_key_latex(data), args.key_pdf) - run_dir = data.get("meta", {}).get("run_dir") if run_dir and os.path.isdir(run_dir): for src in [args.test_out, args.key_out, args.test_pdf, args.key_pdf]: if not src: @@ -285,6 +308,8 @@ def main() -> None: if not os.path.exists(src): continue dest = os.path.join(run_dir, os.path.basename(src)) + if os.path.abspath(dest) == os.path.abspath(src): + continue try: shutil.copyfile(src, dest) except OSError: