2026-05-11 14:46:16 +02:00
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Missione
Ricostruire la struttura logica di PDF digitali e serializzarla in Markdown **stabile e valido per la vettorizzazione RAG ** , senza LLM né OCR. Il Markdown è solo il formato di output finale — la pipeline deve operare su una rappresentazione intermedia strutturata.
**Non supportato: ** PDF scansionati (immagini), PDF protetti da password.
---
2026-04-13 08:02:48 +02:00
2026-04-15 11:38:45 +02:00
## Regole invarianti
2026-04-13 08:02:48 +02:00
2026-04-15 11:38:45 +02:00
- **Lingua:** Rispondi sempre in italiano.
2026-04-20 11:05:20 +02:00
- **Venv:** Usa `.venv/bin/python` o `source .venv/bin/activate` . Mai `pip` /`python` di sistema.
2026-05-11 14:46:16 +02:00
- **`raw.md` immutabile:** Non modificare mai `raw.md` . La copia di lavoro è sempre `clean.md` .
- **Niente LLM nella pipeline:** tutta la logica deve essere rule-based e riproducibile.
---
## Setup
``` bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
Dipendenze principali:
- **PyMuPDF** (`fitz` ) — estrazione primaria con metadati font e coordinate
- **pdfplumber** — ricostruzione tabelle (opzionale, non per parsing generico)
---
## Comandi
``` bash
# Converti un PDF (posizionalo prima in sources/<nome>.pdf)
.venv/bin/python conversione/ --stem <nome>
# Forza riesecuzione (sovrascrive clean.md esistente)
.venv/bin/python conversione/ --stem <nome> --force
# Tutti i PDF in sources/
.venv/bin/python conversione/
# Validazione batch
.venv/bin/python conversione/ validate
.venv/bin/python conversione/ validate <stem> --detail
# Rimuove l'output di uno stem
bash conversione/clear.sh <nome>
# Test suite
.venv/bin/python -m pytest tests/
```
`--stem` = nome file PDF senza estensione.
2026-04-13 08:02:48 +02:00
2026-04-15 11:38:45 +02:00
---
2026-05-11 14:46:16 +02:00
## Architettura
### Principio fondamentale
La pipeline **non converte direttamente PDF → Markdown ** .
2026-04-15 11:38:45 +02:00
```
2026-05-11 14:46:16 +02:00
PDF → Structured Document Tree → Markdown
2026-04-15 11:38:45 +02:00
```
2026-05-11 14:46:16 +02:00
Il Markdown è generato solo dall'albero documentale. Non dal testo grezzo.
### Modello dati intermedio
``` python
class Block :
text : str
page : int
bbox : tuple
font_size : float
font_name : str
is_bold : bool
block_type : str # "header" | "paragraph" | "list" | "table" | "code"
class Section :
title : str
level : int # 1, 2, 3
content : list [ Block ]
children : list [ Section ]
```
2026-04-13 08:02:48 +02:00
2026-05-11 14:46:16 +02:00
Il Markdown si genera **solo ** da `Section` . Mai da `Block` direttamente.
2026-04-15 11:38:45 +02:00
---
2026-04-13 08:02:48 +02:00
2026-05-11 14:46:16 +02:00
### I 9 stadi della pipeline
#### Stage 1 — Metadata Extraction
2026-04-15 11:38:45 +02:00
2026-05-11 14:46:16 +02:00
Usa `page.get_text("dict")` (o `"rawdict"` ) di PyMuPDF. **Non usare estrazione plain text. **
2026-04-15 11:38:45 +02:00
2026-05-11 14:46:16 +02:00
Per ogni span estrai: testo, font size, font name, flags, bbox, numero di pagina.
Estrai anche: TOC del documento, bookmark, dimensioni pagina.
2026-04-15 11:38:45 +02:00
2026-05-11 14:46:16 +02:00
#### Stage 2 — Layout Analysis
Identifica i blocchi strutturali preservando l'ordine di lettura:
headers, paragrafi, liste, tabelle, code block, interruzioni di pagina.
#### Stage 3 — Font Analysis
Inferisce la gerarchia visiva **per documento ** (non hardcoded):
- calcola il font size dominante del corpo
- raggruppa i font size in cluster
- identifica i candidati header per dimensione
#### Stage 4 — Header Detection
Segnali combinati (tutti richiesti):
- font size > corpo testo
- boldness / semibold
- numerazione (`^\d+(\.\d+)*\s+` )
- spaziatura verticale sopra/sotto
- lunghezza riga corta
#### Stage 5 — Hierarchy Inference
Priorità delle regole (in ordine):
1. **Numerazione ** — `1` → H1, `1.1` → H2, `1.1.1` → H3 (ha precedenza sul font size)
2. **TOC del PDF ** — se presente, è autoritativo; allineare i header rilevati alla sua gerarchia
3. **Font size clustering ** — fallback se né numerazione né TOC esistono
#### Stage 6 — Document Tree Reconstruction
Costruisce l'albero `Section` con relazioni parent-child, ordinamento e nesting. Ogni nodo contiene titolo, livello, contenuto e figli.
#### Stage 7 — Markdown Generation
Serializza l'albero in Markdown valido:
- Header: `#` /`##` /`###` senza salti di livello
- Liste: preserva nesting ordered/unordered
- Tabelle: GitHub-compatible; fallback testo strutturato
- Code block: fenced con language tag dove rilevabile
#### Stage 8 — Hierarchy Normalization
Ripara le inconsistenze strutturali:
- salti di livello invalidi (`# A` → `#### B` diventa `# A` → `## B` )
- header vuoti (rimuovi o mergia)
- header consecutivi duplicati (collassa)
- nesting rotto
#### Stage 9 — Structural Validation
Valida il Markdown finale:
- nessun salto di livello heading
- nessuna sezione vuota
- liste correttamente annidate
- tabelle con colonne consistenti
- ordine uguale al PDF sorgente
2026-04-15 11:38:45 +02:00
---
2026-04-13 08:02:48 +02:00
2026-05-11 14:46:16 +02:00
## Cosa rende un Markdown perfetto per la vettorizzazione
- **Struttura semantica:** ogni header è un confine naturale di chunk; ogni sezione è un'unità concettuale.
- **Gerarchia corretta:** h1/h2/h3 riflettono la struttura logica, non il layout tipografico.
- **Testo pulito:** nessun artefatto di encoding, footnote superscript, `<br>` , dot-leader, PUA.
- **Paragrafi interi:** nessuna frase troncata da salto pagina.
- **Output deterministico:** stessa pipeline su stesso PDF produce sempre lo stesso output.
---
## Linee guida per sviluppare la pipeline
- Ogni stage deve essere **indipendentemente testabile ** .
- Le regex per header numbering e simili vanno compilate in `_constants.py` , mai inline.
- PyMuPDF è il parser primario. pdfplumber si usa solo per tabelle complesse.
- Ogni stage deve ricevere l'output del precedente come struttura tipizzata, non testo grezzo.
- Prima di aggiungere un nuovo segnale di detection (Stage 4), validarlo su almeno 3 PDF diversi.
### Categorie di test richieste
| Categoria | Input | Validazione attesa |
|-----------|-------|-------------------|
| Header reconstruction | PDF con H1/H2/H3 numerati | gerarchia corretta, no level skip |
| TOC alignment | PDF con bookmark/TOC | markdown allineato al TOC |
| Mixed font sizes | Font inconsistenti, bold nel corpo | body non classificato come header |
| Broken layout | Header multi-riga, spacing irregolare | header mergiati, markdown valido |
| Tables | Tabelle nel PDF | markdown table con colonne preservate |
| Lists | Liste ordered/unordered annidate | nesting corretto |
| Large documents | PDF tecnico voluminoso | output deterministico, memoria stabile |
| Invalid hierarchy repair | `# A` + `#### B` artificiale | riparazione automatica in `# A` + `## B` |
---
## Pipeline attuale
La pipeline in `conversione/_pipeline/` (basata su trasformazioni testo con `_apply.py` ) è **deprecata ** e deve essere sostituita dall'architettura a 9 stadi descritta sopra. Durante la migrazione:
2026-04-15 11:38:45 +02:00
2026-05-11 14:46:16 +02:00
- separare estrazione da ricostruzione
- introdurre strutture intermedie esplicite (`Block` , `Section` )
- rimuovere l'architettura parser-centrica
- ogni stage deve essere indipendente e testabile
2026-04-15 11:38:45 +02:00
---
2026-04-20 11:05:20 +02:00
## Skills custom
2026-04-15 11:38:45 +02:00
2026-05-11 14:46:16 +02:00
- `/prepare-md <path|stem>` — corregge `clean.md` quando la pipeline non basta: sillabazione, artefatti residui, header malformati, gerarchia incoerente.