"""Split a PDF into two contiguous halves by page (PyMuPDF).""" from __future__ import annotations from dataclasses import dataclass @dataclass(frozen=True) class PdfSplitMeta: page_range_a: str # e.g. "1-50" (1-based, inclusive) page_range_b: str total_pages: int def split_pdf_two_halves(src_path: str, dest_a: str, dest_b: str) -> tuple[PdfSplitMeta | None, str]: """ First half = pages 1 .. floor(n/2), second half = rest (at least one page each requires n >= 2). Returns (meta, "") on success or (None, error_message). """ try: import fitz # PyMuPDF except ImportError: return None, "PyMuPDF (fitz) is not installed." doc = None try: doc = fitz.open(src_path) n = len(doc) if n < 2: return None, "This PDF has only one page; split requires at least two pages. Try compressing or splitting the file manually." mid = n // 2 # pages 0..mid-1 in part A, mid..n-1 in part B out_a = fitz.open() try: out_a.insert_pdf(doc, from_page=0, to_page=mid - 1) out_a.save(dest_a) finally: out_a.close() out_b = fitz.open() try: out_b.insert_pdf(doc, from_page=mid, to_page=n - 1) out_b.save(dest_b) finally: out_b.close() meta = PdfSplitMeta( page_range_a=f"1-{mid}", page_range_b=f"{mid + 1}-{n}", total_pages=n, ) return meta, "" except Exception as e: return None, f"PDF split failed: {e}" finally: if doc is not None: try: doc.close() except Exception: pass