"""Modèles de données partagés par l'application.""" from __future__ import annotations from dataclasses import dataclass from datetime import datetime @dataclass class Clip: """Un extrait de texte capturé sur une page web.""" text: str title: str url: str captured_at: datetime # Si True, cet extrait s'enchaîne directement dans le suivant (même # chapitre) : pas de nouveau titre/entrée de sommaire ni de saut de # page à l'export — voir group_into_chapters() ci-dessous et # main_window.py (bascule via l'icône entre deux extraits de la liste). linked_to_next: bool = False def preview(self, length: int = 60) -> str: """Retourne un aperçu court du texte, sur une seule ligne.""" flat = " ".join(self.text.split()) if len(flat) <= length: return flat return flat[: length - 1].rstrip() + "…" def group_into_chapters(clips: list[Clip]) -> list[list[int]]: """Regroupe les indices de `clips` en chapitres : une suite d'extraits consécutifs reliés par `linked_to_next` forme un seul chapitre (un seul titre/une seule entrée de sommaire à l'export). Un extrait non lié forme un chapitre à lui seul. Utilisé à la fois par pdf_builder.py (export) et par l'UI (main_window.py, preview_window.py) pour une définition unique et cohérente des regroupements. """ chapters: list[list[int]] = [] current: list[int] = [] for index, clip in enumerate(clips): current.append(index) if not clip.linked_to_next: chapters.append(current) current = [] if current: # défensif : n'arrive que si le dernier extrait est lié à "rien" chapters.append(current) return chapters