"""Moteur Step & Repeat : dupliquer une page plusieurs fois sur une feuille.""" from pypdf import PdfReader, PdfWriter, PageObject, Transformation from .pdf_utils import get_page_size, smart_crop_marks import math def step_and_repeat(input_path, output_path, sheet_size=(841.89, 595.28), copies_h=None, copies_v=None, spacing_h=0, spacing_v=0, crop_marks=False): """Dupliquer chaque page sur une feuille. copies_h, copies_v: nombre de copies horizontales/verticales (None = auto) spacing_h, spacing_v: espacement en points """ reader = PdfReader(input_path) sheet_w, sheet_h = sheet_size writer = PdfWriter() for page in reader.pages: page_w, page_h = get_page_size(page) # Auto-calcul du nombre de copies if copies_h is None: copies_h_calc = max(1, int((sheet_w + spacing_h) / (page_w + spacing_h))) else: copies_h_calc = copies_h if copies_v is None: copies_v_calc = max(1, int((sheet_h + spacing_v) / (page_h + spacing_v))) else: copies_v_calc = copies_v # Centrage sur la feuille total_w = copies_h_calc * page_w + (copies_h_calc - 1) * spacing_h total_h = copies_v_calc * page_h + (copies_v_calc - 1) * spacing_v start_x = (sheet_w - total_w) / 2 start_y = (sheet_h - total_h) / 2 sheet = PageObject.create_blank_page(width=sheet_w, height=sheet_h) grid_positions = [] for row in range(copies_v_calc): for col in range(copies_h_calc): x = start_x + col * (page_w + spacing_h) y = start_y + (copies_v_calc - 1 - row) * (page_h + spacing_v) overlay = PageObject.create_blank_page(width=sheet_w, height=sheet_h) overlay.merge_page(page) overlay.add_transformation(Transformation().translate(x, y)) sheet.merge_page(overlay) grid_positions.append((col, row)) if crop_marks and grid_positions: marks = smart_crop_marks( sheet_w, sheet_h, grid_positions, page_w + spacing_h, page_h + spacing_v, start_x, sheet_h - start_y - total_h ) sheet.merge_page(marks) writer.add_page(sheet) with open(output_path, "wb") as f: writer.write(f) return output_path