import os import shutil import subprocess import sys def build_pdf(): # Define directories # Script is in e:\health-tech\papers\vsa\scripts\ # Papers are in e:\health-tech\papers\vsa\papers\ # Assets are in e:\health-tech\papers\vsa\data\paper_assets\ script_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(script_dir) # e:\health-tech\papers\vsa\ papers_dir = os.path.join(project_root, "papers") assets_dir = os.path.join(project_root, "data", "paper_assets") tex_filename = "The Atomic VSA.tex" tex_path = os.path.join(papers_dir, tex_filename) # Required assets assets = [] # scan .tex file for assets print(f"Scanning {tex_filename} for assets...") try: with open(tex_path, 'r', encoding='utf-8') as f: content = f.read() import re # Look for \IfFileExists{filename} OR \includegraphics{filename} # Matches: fig1.png, image.jpg, etc. # We explicitly look for the file usage in the template matches = re.findall(r'\\IfFileExists\{([^}]+)\}', content) matches += re.findall(r'\\includegraphics(?:\[.*?\])?\{([^}]+)\}', content) # Deduplicate and clean assets = sorted(list(set(matches))) # Filter out LaTeX macro arguments (start with #) assets = [a for a in assets if not a.startswith('#')] print(f"Found {len(assets)} required assets: {assets}") except Exception as e: print(f"Error reading .tex file: {e}") return print(f"Building PDF for {tex_filename}...") # 1. Copy assets to papers directory (where latex expects them) print("Copying assets...") # Source directories to search in search_dirs = [assets_dir, project_root] for asset in assets: # Skip if asset is just a base filename without extension (latex sometimes omits .png) # But our current usage includes extensions. if not asset: continue found = False for src_dir in search_dirs: src = os.path.join(src_dir, asset) if os.path.exists(src): dst = os.path.join(papers_dir, asset) shutil.copy2(src, dst) print(f" Copied {asset} from {src_dir}") found = True break if not found: # Try recursive search in data/paper_assets if not immediately found for root, dirs, files in os.walk(assets_dir): if asset in files: src = os.path.join(root, asset) dst = os.path.join(papers_dir, asset) shutil.copy2(src, dst) print(f" Copied {asset} from {root} (recursive search)") found = True break if not found: print(f" WARNING: Asset not found in search paths: {asset}") # 2. Check for pdflatex if shutil.which("pdflatex") is None: print("\nERROR: 'pdflatex' executable not found.") print(" 1. 'pip install pdflatex' is NOT sufficient (it is just a wrapper).") print(" 2. You must install a LaTeX distribution.") print(" -> WINDOWS: Run 'winget install MiKTeX' or download from miktex.org") print(" -> LINUX: 'sudo apt install texlive-full'") print(" -> MAC: 'brew install mactex'") return # 3. Run pdflatex print("Running pdflatex...") # Needs to be run twice for cross-references/labels to resolve correctly cmd = ["pdflatex", "-interaction=nonstopmode", tex_filename] try: # Run 1 subprocess.run(cmd, cwd=papers_dir, check=True) print(" Pass 1 complete.") # Run 2 subprocess.run(cmd, cwd=papers_dir, check=True) print(" Pass 2 complete.") pdf_path = os.path.join(papers_dir, "The Atomic VSA.pdf") if os.path.exists(pdf_path): print(f"PDF Build Successful!") print(f"Output: {pdf_path}") else: print("ERROR: PDF file not found after build.") except subprocess.CalledProcessError as e: print(f"Error during pdflatex execution: {e}") # Could print log file here if needed except Exception as e: print(f"Unexpected error: {e}") if __name__ == "__main__": build_pdf()