"""Table-only companion route; preserve raw cell arrays separately from Markdown. Run with the repository's preinstalled tools/lab-venv/bin/python. The output deliberately excludes ordinary prose; it is not a document converter. """ import hashlib import importlib.metadata import json import platform import time from datetime import datetime from pathlib import Path import pdfplumber LAB = Path(__file__).resolve().parent OUT = LAB / "pdfplumber-tables" OUT.mkdir(exist_ok=True) runs_path = LAB / "runs.json" runs = json.loads(runs_path.read_text()) results = [] for source in sorted((LAB / "corpus").glob("*.pdf")): started = time.perf_counter() blocks, pages = [], [] with pdfplumber.open(source) as pdf: for page in pdf.pages: tables = page.extract_tables() pages.append({"page": page.page_number, "tables": tables}) for table in tables: rows = [[(cell or "").replace("\n", "
").replace("|", "\\|") for cell in row] for row in table] if not rows: continue lines = ["| " + " | ".join(rows[0]) + " |", "| " + " | ".join("---" for _ in rows[0]) + " |"] lines.extend("| " + " | ".join(row) + " |" for row in rows[1:]) blocks.append("\n".join(lines)) elapsed = round(time.perf_counter() - started, 4) (OUT / f"{source.stem}.md").write_text("\n\n".join(blocks), encoding="utf-8") (OUT / f"{source.stem}.json").write_text(json.dumps({ "source": source.name, "source_sha256": hashlib.sha256(source.read_bytes()).hexdigest(), "pages": pages, "route": "page.extract_tables() defaults; table-only", }, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") results.append({"tool": "pdfplumber-tables", "sample": source.stem, "output": f"pdfplumber-tables/{source.stem}.md", "elapsed_s": elapsed, "error": None}) print(f"pdfplumber-tables x {source.stem}: {elapsed}s") runs["results"] = [r for r in runs["results"] if r["tool"] != "pdfplumber-tables"] + results runs["tools"]["pdfplumber-tables"] = { "version": importlib.metadata.version("pdfplumber"), "device": "cpu", "elapsed_s": round(sum(r["elapsed_s"] for r in results), 4), "error": None, "scope": "table-only; prose and non-table pages intentionally excluded", } runs_path.write_text(json.dumps(runs, ensure_ascii=False, indent=1) + "\n") print("python", platform.python_version(), "executed", datetime.now().astimezone().isoformat())