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, glob, sys3sys.path.insert(0, os.path.dirname(__file__))4REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))5from texutil import tex6def card_field(txt, name):7 m = re.search(r"\*\*" + re.escape(name) + r"\*\*\s*:\s*(.+)", txt)8 return m.group(1).strip() if m else ""9def main():10 reg = sorted(csv.DictReader(open(os.path.join(REPO, "tasks", "registry.csv"))), key=lambda r: (r["split"] != "conf", r["task_id"]))11 rows = []12 for r in reg:13 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 ""14 q = card_field(card, "Question") or card_field(card, "Scientific question")15 q = re.sub(r"\s+", " ", q)[:150]16 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))17 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"]18 for t in rows: L.append(" & ".join(tex(x) for x in t) + r" \\")19 L += [r"\bottomrule", r"\end{longtable}"]20 os.makedirs(os.path.join(REPO, "paper", "tables"), exist_ok=True)21 open(os.path.join(REPO, "paper", "tables", "tab_tasks.tex"), "w").write("\\footnotesize\n" + "\n".join(L) + "\n\\normalsize\n")22 # appendix: task cards verbatim-ish (markdown bullets → itemize)23 A = []24 for r in reg:25 p = os.path.join(REPO, "tasks", "task_cards", r["task_id"] + ".md")26 if not os.path.exists(p): continue27 txt = open(p).read()28 A.append(f"\\subsection*{{{tex(r['task_id'])}}}")29 items = re.findall(r"^- \*\*(.+?)\*\*\s*:?\s*(.*)$", txt, re.M)30 if items:31 A.append(r"\begin{itemize}\setlength\itemsep{0pt}")32 for k, v in items:33 v = re.sub(r"`([^`]*)`", r"\\texttt{\1}", tex(v)); A.append(f"\\item \\textbf{{{tex(k)}}}: {v}")34 A.append(r"\end{itemize}")35 open(os.path.join(REPO, "paper", "appendices", "task_cards.tex"), "w").write("\\small\n" + "\n".join(A) + "\n\\normalsize\n")36 print(len(rows), "tasks tabled;", len(A), "appendix lines")37if __name__ == "__main__": main()38