#!/usr/bin/env python3 """ Parametri della pipeline chunks: chunker.py (+ md_optimizer interno) + verify/fix. La pipeline è unificata: chunker.py esegue prima l'ottimizzazione del Markdown (Stage 1, equivalente a md_optimizer.py) e poi il chunking (Stage 2). I parametri sono pensati per essere generici rispetto agli output di MinerU: i file *_content_list_v2.json e *_model.json hanno sempre la stessa struttura, indipendentemente dal documento sorgente. """ # ─── Stage 1 — md_optimizer (pulizia Markdown) ─────────────────────────────── # Tipi MinerU da ignorare completamente. NOISE_TYPES: set[str] = { "page_header", "page_number", "page_footer", "index", "page_aside_text", } # Paragrafi promossi a H3 se testo ≤ H3_MAX_CHARS e matcha H3_DETECTION_RE. # Regex generica: riga che inizia con numero seguito da punto e spazio. # Per disabilitare la promozione a H3: imposta H3_DETECTION_RE = r"(?!)" H3_DETECTION_RE: str = r"^\d+\.\s+\S" H3_MAX_CHARS: int = 120 # Se True, i blocchi immagine non vengono inclusi nel Markdown. SKIP_IMAGES: bool = True # Heading le cui sezioni vengono rimosse completamente (titolo + tutto il contenuto). # Match case-insensitive: il testo dell'heading deve essere uguale o iniziare # con uno dei valori seguenti. # Nota: specifici per documento — impostare set vuoto per documenti non italiani # o senza sezioni di frontmatter note. FRONTMATTER_HEADINGS: set[str] = { "sommario", "indice", "autori", "abbreviazioni", "atti normativi", "specifici provvedimenti normativi", "abbreviazioni generiche", } # Numero minimo di heading consecutivi senza testo per riconoscere un TOC. # Abbassare se il documento ha molti capitoli corti senza sottosezioni. MIN_TOC_HEADINGS: int = 5 # Caratteri minimi di testo reale sotto un heading perché sia considerato # "contenuto vero" (non frontespizio/copyright). # Impostare >= lunghezza massima del testo di copyright/copertina nel documento. MIN_CONTENT_CHARS: int = 2500 # Pattern per riconoscere prefissi di capitolo in blocchi paragraph. # MinerU talvolta produce il numero/identificatore di capitolo come paragraph # anziché come title L1 (comportamento non uniforme). Questi pattern permettono # di bufferizzare tali paragrafi e fonderli col titolo L1 successivo. # Impostare lista vuota [] per disabilitare. CHAPTER_PREFIX_PATTERNS: list[str] = [ r"^(CAPITOLO|PARTE)\s+(\d+|[IVXLCDM]+)\b", # italiano r"^(CHAPTER|PART|SECTION)\s+(\d+|[IVXLCDM]+)\b", # inglese r"^(CHAPITRE|PARTIE)\s+(\d+|[IVXLCDM]+)\b", # francese r"^(KAPITEL|TEIL)\s+(\d+|[IVXLCDM]+)\b", # tedesco ] # Pattern testuali (regex) per riconoscere paragrafi "sommario interno" da saltare. # Usati come fallback quando _model.json non assegna label "abstract". # Generici: un pattern per paragrafo che inizia con indice/sommario di sezione. # Per disabilitare: impostare lista vuota []. SOMMARIO_PATTERNS: list[str] = [ r"^SOMMARIO\s*:", # italiano r"^SUMMARY\s*:", # inglese r"^RÉSUMÉ\s*:", # francese r"^ÍNDICE\s*:", # spagnolo/portoghese r"^INHALT\s*:", # tedesco ] # ─── _model.json label sets ─────────────────────────────────────────────────── # Label di layout da saltare completamente. MODEL_SKIP_LABELS: set[str] = { "header", "number", "footer_image", "ocr_text", "aside_text", } # Label che identifica indici/sommari interni (da saltare). MODEL_ABSTRACT_LABELS: set[str] = {"abstract"} # ─── Stage 2 — chunker ──────────────────────────────────────────────────────── # Lunghezza massima di un chunk (caratteri, prefisso incluso). # Paragrafi che superano questo limite vengono spezzati a confine di frase. # Una singola frase che supera MAX_CHARS viene emessa intera (non si spezza mai). MAX_CHARS: int = 1200 # Lunghezza minima attesa (warning in verify_chunks, non blocker). MIN_CHARS: int = 80 # Frasi di overlap: l'ultima frase del chunk N viene preposta al chunk N+1. OVERLAP_SENTENCES: int = 1 # Regex per rilevare il confine di fine frase per lo split. # Split solo prima di lettera maiuscola o virgolette — evita split su abbreviazioni. SENTENCE_SPLIT_RE: str = r"(?<=[.!?»])\s+(?=[A-ZÀÈÉÌÒÙ\"])" # ─── verify_chunks.py / fix_chunks.py ───────────────────────────────────────── # fix_chunks spezza un chunk too_long solo se supera MAX_CHARS × questo fattore. SPLIT_THRESHOLD_FACTOR: float = 1.5 MATH_SYMS_MIN: int = 3 PROTECT_TABLES: bool = True PROTECT_MATH: bool = True FIX_MAX_ITERATIONS: int = 3