2026-10-09 19:06:40 +02:00
"""Genera wiki/figures/<id>.md da raw/immagini.json. Nessun riassunto: ogni campo del catalogo viene riportato.
Uso: python scripts/gen_figures.py (rigenera tutto; le note sono derivate, non si modificano a mano)."""
import json
from pathlib import Path
root = Path ( __file__ ) . resolve () . parent . parent
cat = json . loads (( root / "raw/immagini.json" ) . read_text ( encoding = "utf8" ))
out = root / "wiki/figures"
out . mkdir ( parents = True , exist_ok = True )
2026-10-20 13:59:21 +02:00
# --- pagine della wiki che usano ciascuna figura (link [[fig-...]] o embed del file), per la navigazione inversa ---
import re as _re0
_file2id = { pn [ "file" ][: - 4 ]: f [ "id" ] for k in ( "figures" ,) for f in cat [ k ] for pn in f [ "panels" ]}
_file2id . update ({ pn [ "file" ][: - 4 ]: f [ "id" ] for f in cat . get ( "riassunto" , {}) . get ( "figures" , []) for pn in f [ "panels" ]})
used_by = {}
for _p in sorted (( root / "wiki" ) . rglob ( "*.md" )):
if "figures" in _p . parts or _p . name in ( "figure-indice.md" , "bibliografia.md" ):
continue
_t = _p . read_text ( encoding = "utf8" ) . split ( "---" , 2 )[ - 1 ]
_ids = set ( _re0 . findall ( r "\[\[((?:ris-)?fig-[\w-]+)" , _t ))
_ids |= { _file2id [ h ] for h in _re0 . findall ( r "!\[\[immagini/([0-9a-f] {64} )" , _t ) if h in _file2id }
for _i in _ids :
used_by . setdefault ( _i , set ()) . add ( _p . stem )
def usage ( fid ):
pages = sorted ( used_by . get ( fid , ()))
return [ "## Pagine che la usano" , " · " . join ( f "[[ { x } ]]" for x in pages ) if pages else "nessuna" , "" ]
2026-10-09 19:06:40 +02:00
def q ( s ):
return json . dumps ( str ( s ), ensure_ascii = False )
def lst ( xs ):
return "[" + ", " . join ( q ( x ) for x in xs ) + "]"
for f in cat [ "figures" ]:
loc , qual = f [ "location" ], f [ "quality" ]
f [ "label" ] = f . get ( "label" ) or f [ "id" ] # figure senza numero stampato
v = qual . get ( "verification" ) or {}
tesi_loc = f "§ { loc [ 'section' ] } r. { loc [ 'md_line' ] } "
fm = [
"---" ,
f "title: { q ( ' - ' . join ( x for x in ( f [ 'label' ], f . get ( 'title' ) or f . get ( 'caption_printed' )) if x )) } " ,
"type: figure" ,
f "id: { f [ 'id' ] } " ,
f "tipo: { f [ 'type' ] } " ,
f "capitolo: { q ( loc [ 'chapter' ]) } " ,
f "sezione: { q ( loc [ 'section' ]) } " ,
f "tesi_loc: { q ( tesi_loc ) } " ,
f "composti: { lst ( f . get ( 'compounds' , [])) } " ,
f "concetti: { lst ( f . get ( 'concepts' , [])) } " ,
f "keywords: { lst ( f . get ( 'keywords' , [])) } " ,
f "confidence: { qual [ 'confidence' ] } " ,
f "flags: { lst ( qual . get ( 'flags' , [])) } " ,
f "verifica: { v . get ( 'verdict' , 'n/d' ) } " ,
"derivata: true" ,
"---" ,
"" ,
]
body = [ f "# { f [ 'label' ] } " , "" ]
body += [ f "**Didascalia stampata (testo della tesi):** { f . get ( 'caption_printed' ) or 'n/d' } " , "" ]
cap = f ", didascalia r. { loc [ 'caption_md_line' ] } " if loc . get ( "caption_md_line" ) else ""
body += [ f "_Posizione: tesi.md { tesi_loc } (sezione { loc [ 'section' ] } { loc [ 'section_title' ] } ) { cap } _" , "" ]
2026-10-09 19:21:52 +02:00
if "caption_mismatch" in qual . get ( "flags" , []):
body += [ "> ⚠ Flag `caption_mismatch`: la didascalia stampata qui sopra è quella attribuita dal catalogo e potrebbe non descrivere l'immagine (vedi «Didascalia generata» e «Da verificare»)." , "" ]
2026-10-09 19:06:40 +02:00
body += [ "> Sotto: contenuto generato guardando l'immagine, non verificato una per una." , "" ]
body += [ f "**Didascalia generata:** { f [ 'caption' ] } " , "" ]
for p in f [ "panels" ]:
body += [ p [ "embed" ], "" ]
body += [ f "- Pannello: { p [ 'panel' ] or 'unico' } · file ` { p [ 'file' ] } ` · { p [ 'width' ] } × { p [ 'height' ] } · confidence { p [ 'confidence' ] } " ]
body += [ f "- Descrizione: { p [ 'description' ] } " ]
body += [ "- Testo visibile: " + ( " · " . join ( p [ "visible_text" ]) or "n/d" )]
if p . get ( "quality_flags" ):
body += [ "- Flag: " + ", " . join ( p [ "quality_flags" ])]
body += [ "" ]
if f . get ( "text_context" ):
body += [ "## Contesto nel testo" , f [ "text_context" ], "" ]
if f . get ( "cited_in_md_lines" ):
body += [ "Citata in tesi.md alle righe: " + ", " . join ( map ( str , f [ "cited_in_md_lines" ])), "" ]
if qual . get ( "review_notes" ):
body += [ "## Da verificare" , qual [ "review_notes" ], "" ]
if v . get ( "issues" ):
body += [ "Esito revisione indipendente: " + "; " . join ( v [ "issues" ]), "" ]
2026-10-20 13:59:21 +02:00
body += usage ( f [ "id" ])
2026-10-09 19:06:40 +02:00
body += [ "## Collegamenti" , "- [[tesi]]" , "" ]
( out / f " { f [ 'id' ] } .md" ) . write_text ( " \n " . join ( fm + body ), encoding = "utf8" )
2026-10-20 13:50:48 +02:00
# --- figure del riassunto di tesi (chiave "riassunto" di immagini.json): note ris-fig-NN.md ---
ris = cat . get ( "riassunto" , {}) . get ( "figures" , [])
for f in ris :
qual = f [ "quality" ]
fm = [
"---" ,
f "title: { q ( ' - ' . join ( x for x in ( f [ 'label' ], f . get ( 'title' )) if x )) } " ,
"type: figure" ,
f "id: { f [ 'id' ] } " ,
f "tipo: { f [ 'type' ] } " ,
'documento: "riassunto"' ,
f "tesi_loc: { q ( 'riassunto r.' + str ( f [ 'location' ][ 'md_line' ])) } " ,
f "composti: { lst ( f . get ( 'compounds' , [])) } " ,
f "concetti: { lst ( f . get ( 'concepts' , [])) } " ,
f "keywords: { lst ( f . get ( 'keywords' , [])) } " ,
f "confidence: { qual [ 'confidence' ] } " ,
f "flags: { lst ( qual . get ( 'flags' , [])) } " ,
"derivata: true" ,
"---" ,
"" ,
]
loc = f [ "location" ]
body = [ f "# { f [ 'label' ] } (riassunto di tesi)" , "" ]
body += [ f "**Didascalia stampata (testo del riassunto):** { f [ 'caption_printed' ] } " , "" ]
body += [ f "_Posizione: riassunto_tesi.md r. { loc [ 'md_line' ] } , didascalia r. { loc [ 'caption_md_line' ] } _" , "" ]
body += [ "> Sotto: contenuto generato guardando l'immagine, non verificato una per una." , "" ]
body += [ f "**Didascalia generata:** { f [ 'caption' ] } " , "" ]
for p in f [ "panels" ]:
body += [ p [ "embed" ], "" ]
body += [ f "- Pannello: { p [ 'panel' ] or 'unico' } · file ` { p [ 'file' ] } ` · { p [ 'width' ] } × { p [ 'height' ] } · confidence { p [ 'confidence' ] } " ]
body += [ f "- Descrizione: { p [ 'description' ] } " ]
body += [ "- Testo visibile: " + ( " · " . join ( p [ "visible_text" ]) or "n/d" )]
if p . get ( "quality_flags" ):
body += [ "- Flag: " + ", " . join ( p [ "quality_flags" ])]
body += [ "" ]
if f . get ( "text_context" ):
body += [ "## Contesto nel testo" , f [ "text_context" ], "" ]
if f . get ( "cited_in_md_lines" ):
body += [ "Citata in riassunto_tesi.md alle righe: " + ", " . join ( map ( str , f [ "cited_in_md_lines" ])), "" ]
if f . get ( "thesis_equivalents" ):
body += [ "## Corrispondenze nella tesi" ]
body += [ f "- [[ { e [ 'id' ] } ]] — { e [ 'relation' ] } (verifica: { e [ 'verified' ] } )" for e in f [ "thesis_equivalents" ]] + [ "" ]
if qual . get ( "review_notes" ):
body += [ "## Da verificare" , qual [ "review_notes" ], "" ]
2026-10-20 13:59:21 +02:00
body += usage ( f [ "id" ])
2026-10-20 13:50:48 +02:00
body += [ "## Collegamenti" , "- [[riassunto-tesi]] · [[riassunto-vs-tesi]]" , "" ]
( out / f " { f [ 'id' ] } .md" ) . write_text ( " \n " . join ( fm + body ), encoding = "utf8" )
2026-10-09 19:06:40 +02:00
print ( f " { len ( cat [ 'figures' ]) } note in { out } " )
2026-10-20 13:50:48 +02:00
print ( f " { len ( ris ) } note del riassunto in { out } " )
2026-10-15 08:48:35 +02:00
# --- wiki/figure-indice.md: indice derivato (sezione -> figure) ---
import re as _re
def _clean ( s ):
return _re . sub ( r "<[^>]+>" , "" , s or "" ) . strip ()
idx = [ "---" , "title: Indice delle figure" , "type: overview" , "tags: [figure, indice, navigazione]" ,
"created: 2026-10-15" , "updated: 2026-10-15" , 'tesi_loc: "r.73-1301 (didascalie)"' , "derivata: true" , "status: draft" , "---" , "" ,
"# Indice delle figure" , "" ,
2026-10-20 13:50:48 +02:00
f "Le { len ( cat [ 'figures' ]) } figure del catalogo raggruppate per sezione della tesi, più le { len ( cat . get ( 'riassunto' , {}) . get ( 'figures' , [])) } del riassunto di tesi in fondo (generata da `raw/immagini.json`: non modificare a mano). "
2026-10-15 08:48:35 +02:00
"Ogni voce rimanda alla nota della figura; ⚠ = figura con flag o note di revisione. Matrice campioni × tecniche: [[campioni]]; tabelle: [[tabelle-indice]]." , "" ]
by_sec = {}
for f in cat [ "figures" ]:
by_sec . setdefault ( f [ "location" ][ "section" ], []) . append ( f )
for s in cat [ "sections" ]:
figs = by_sec . get ( s [ "number" ], [])
if not figs :
continue
idx += [ f "## § { s [ 'number' ] } { _clean ( s [ 'title' ]) } " ]
for f in figs :
warn = " ⚠" if ( f [ "quality" ] . get ( "flags" ) or f [ "quality" ] . get ( "review_notes" )) else ""
if f [ "number" ]:
idx . append ( f "- [[ { f [ 'id' ] } |Fig. { f [ 'number' ] } ]] — { _clean ( f [ 'title' ]) } _( { f [ 'type' ] } )_ { warn } " )
else :
idx . append ( f "- [[ { f [ 'id' ] } |schema]] — { _clean ( f [ 'caption' ]) } _( { f [ 'type' ] } )_ { warn } " )
idx . append ( "" )
2026-10-20 13:50:48 +02:00
if ris :
idx += [ "## Riassunto di tesi" , "" ]
for f in ris :
warn = " ⚠" if ( f [ "quality" ] . get ( "flags" ) or f [ "quality" ] . get ( "review_notes" )) else ""
idx . append ( f "- [[ { f [ 'id' ] } |Fig. { f [ 'number' ] } ]] — { _clean ( f [ 'title' ]) } _( { f [ 'type' ] } )_ { warn } " )
idx . append ( "" )
2026-10-15 08:48:35 +02:00
idx += [ "## Collegamenti" , "- [[index]] · [[tesi]] · [[campioni]] · [[tabelle-indice]]" , "" ]
( root / "wiki/figure-indice.md" ) . write_text ( " \n " . join ( idx ), encoding = "utf8" )
print ( "figure-indice.md generato" )