1"""Task-suite table (tab:tasks) and the task-card appendix, generated from tasks/registry.csv and tasks/task_cards/*.md."""2import os, csv, re, glob3REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))4def tex(s): return s.replace("\\", "\\textbackslash{}").replace("&", "\\&").replace("%", "\\%").replace("_", "\\_").replace("#", "\\#").replace("$", "\\$").replace("~", "\\textasciitilde{}").replace("^", "\\^{}")5def card_field(txt, name):6 m = re.search(r"\*\*" + re.escape(name) + r"\*\*\s*:\s*(.+)", txt)7 return m.group(1).strip() if m else ""8def main():9 reg = sorted(csv.DictReader(open(os.path.join(REPO, "tasks", "registry.csv"))), key=lambda r: (r["split"] != "conf", r["task_id"]))10 rows = []11 for r in reg:12 card = open(os.path.join(REPO, "tasks", "task_cards", r["task_id"] + ".md")).read() if os.path.exists(os.path.join(REPO, "tasks", "task_cards", r["task_id"] + ".md")) else ""13 q = card_field(card, "Question") or card_field(card, "Scientific question")14 q = re.sub(r"\s+", " ", q)[:150]15 rows.append((r["task_id"], r["split"], r["data_type"], "yes" if r["real_data"] == "yes" else "no", "yes" if r["source_documents"] == "yes" else "no", r["oracle_provenance"].replace("_", " "), r["infeasible_or_null_truth"], q))16 L = [r"\begin{longtable}{@{}p{0.72in}p{0.4in}p{0.5in}p{0.3in}p{0.3in}p{0.75in}p{0.3in}p{2.6in}@{}}", r"\caption{Task suite: identifiers, split, data type, observed public data, source documents, reference-answer provenance, null/infeasible truth, and question (abridged from the task cards).}\label{tab:tasks}\\", r"\toprule", r"Task & Split & Data & Real & Src & Oracle & Null & Question (abridged) \\", r"\midrule", r"\endfirsthead", r"\toprule", r"Task & Split & Data & Real & Src & Oracle & Null & Question (abridged) \\", r"\midrule", r"\endhead"]17 for t in rows: L.append(" & ".join(tex(x) for x in t) + r" \\")18 L += [r"\bottomrule", r"\end{longtable}"]19 os.makedirs(os.path.join(REPO, "paper", "tables"), exist_ok=True)20 open(os.path.join(REPO, "paper", "tables", "tab_tasks.tex"), "w").write("\\footnotesize\n" + "\n".join(L) + "\n\\normalsize\n")21 # appendix: task cards verbatim-ish (markdown bullets → itemize)22 A = []23 for r in reg:24 p = os.path.join(REPO, "tasks", "task_cards", r["task_id"] + ".md")25 if not os.path.exists(p): continue26 txt = open(p).read()27 A.append(f"\\subsection*{{{tex(r['task_id'])}}}")28 items = re.findall(r"^- \*\*(.+?)\*\*\s*:?\s*(.*)$", txt, re.M)29 if items:30 A.append(r"\begin{itemize}\setlength\itemsep{0pt}")31 for k, v in items:32 v = re.sub(r"`([^`]*)`", r"\\texttt{\1}", tex(v)); A.append(f"\\item \\textbf{{{tex(k)}}}: {v}")33 A.append(r"\end{itemize}")34 open(os.path.join(REPO, "paper", "appendices", "task_cards.tex"), "w").write("\\small\n" + "\n".join(A) + "\n\\normalsize\n")35 print(len(rows), "tasks tabled;", len(A), "appendix lines")36if __name__ == "__main__": main()37