from __future__ import annotations from pathlib import Path from pptx import Presentation from src.utils.validators import validate_template class PlaceholderMapper: def __init__(self, template_path: str | Path | None = None): self.template_path = Path(template_path) if template_path else None self.presentation = None if self.template_path: self.load_template(self.template_path) def load_template(self, template_path: str | Path): validated_path = validate_template(template_path) self.template_path = validated_path self.presentation = Presentation(str(validated_path)) return self.presentation def map_layout_types(self) -> list[str]: if not self.presentation: raise ValueError("Template not loaded.") return [layout.name for layout in self.presentation.slide_layouts] def map_placeholders(self, layout_index: int = 0) -> dict[str, str]: if not self.presentation: raise ValueError("Template not loaded.") layout = self.presentation.slide_layouts[layout_index] mapped = {} for placeholder in layout.placeholders: placeholder_name = getattr(placeholder, "name", None) placeholder_type = getattr(placeholder.placeholder_format, "type", None) if placeholder_name: mapped[str(placeholder_type).lower()] = placeholder_name return mapped def choose_layout_index( layout_type: str, style_profile: dict, total_layouts: int, ) -> int: preferred = style_profile.get("preferred_layout_indices", {}) if style_profile else {} idx = preferred.get(layout_type, 1) if total_layouts <= 0: return 0 return max(0, min(int(idx), total_layouts - 1)) def map_placeholders(template_placeholders: list[dict]) -> dict[str, list[str]]: """Backward-compatible helper.""" mapped_placeholders: dict[str, list[str]] = {} for placeholder in template_placeholders: layout_type = placeholder.get("layout_type", "unknown") placeholder_name = placeholder.get("name", "") mapped_placeholders.setdefault(layout_type, []).append(placeholder_name) return mapped_placeholders def get_placeholder_mapping(template: str | Path) -> list[dict[str, str]]: mapper = PlaceholderMapper(template) placeholders = mapper.map_placeholders(0) return [ {"layout_type": "title", "name": placeholders.get("center title", "Title Placeholder")}, {"layout_type": "content", "name": placeholders.get("object", "Content Placeholder")}, ]