@@ -288,12 +288,17 @@ def clean_text_content(element, cross_references=None):
288288 elif child .tag .endswith ('ref' ):
289289 # Extract text content of <ref> tags
290290 ref_text = clean_text_content (child , cross_references )
291+ href = child .get ('href' )
291292
292293 # If cross_references is provided, try to create a markdown link
293- if cross_references :
294- href = child .get ('href' )
295- if href and href in cross_references :
296- # Create markdown link: [text](relative/path.md)
294+ if cross_references and href :
295+ # Se href è un URI Akoma, convertilo in URL normattiva.it
296+ if href .startswith ('/akn/' ):
297+ normattiva_url = akoma_uri_to_normattiva_url (href )
298+ if normattiva_url and normattiva_url in cross_references :
299+ ref_text = f"[{ ref_text } ]({ cross_references [normattiva_url ]} )"
300+ # Altrimenti, cerca direttamente nel mapping (per compatibilità)
301+ elif href in cross_references :
297302 ref_text = f"[{ ref_text } ]({ cross_references [href ]} )"
298303
299304 text_parts .append (ref_text )
@@ -1101,7 +1106,7 @@ def lookup_normattiva_url(search_query):
11011106 print (f"❌ Errore nella ricerca URL: { e } " , file = sys .stderr )
11021107 return None
11031108
1104- def convert_with_references (url , quiet = False , keep_xml = False , force_complete = False ):
1109+ def convert_with_references (url , output_dir = None , quiet = False , keep_xml = False , force_complete = False ):
11051110 """
11061111 Scarica e converte una legge con tutte le sue riferimenti, creando una struttura di cartelle.
11071112
@@ -1124,9 +1129,12 @@ def convert_with_references(url, quiet=False, keep_xml=False, force_complete=Fal
11241129 print ("❌ Impossibile estrarre parametri dalla legge principale" , file = sys .stderr )
11251130 return False
11261131
1127- # Crea nome cartella basato sui parametri della legge
1128- folder_name = f"{ params ['codiceRedaz' ]} _{ params ['dataGU' ]} "
1129- folder_path = os .path .join (os .getcwd (), folder_name )
1132+ # Crea nome cartella basato sui parametri della legge o usa directory specificata
1133+ if output_dir :
1134+ folder_path = os .path .abspath (output_dir )
1135+ else :
1136+ folder_name = f"{ params ['codiceRedaz' ]} _{ params ['dataGU' ]} "
1137+ folder_path = os .path .join (os .getcwd (), folder_name )
11301138
11311139 if not quiet :
11321140 print (f"📁 Creazione struttura in: { folder_path } " , file = sys .stderr )
@@ -1169,6 +1177,7 @@ def convert_with_references(url, quiet=False, keep_xml=False, force_complete=Fal
11691177 # Scarica e converte leggi citate
11701178 successful_downloads = 0
11711179 failed_downloads = 0
1180+ url_to_file_mapping = {} # Mappa URL originali ai percorsi dei file
11721181
11731182 for i , cited_url in enumerate (cited_urls , 1 ):
11741183 if not quiet :
@@ -1187,6 +1196,9 @@ def convert_with_references(url, quiet=False, keep_xml=False, force_complete=Fal
11871196 cited_filename = f"{ cited_params ['codiceRedaz' ]} _{ cited_params ['dataGU' ]} .md"
11881197 cited_md_path = os .path .join (refs_path , cited_filename )
11891198
1199+ # Mappa l'URL originale al percorso del file
1200+ url_to_file_mapping [cited_url ] = f"refs/{ cited_filename } "
1201+
11901202 # Scarica XML temporaneo per la legge citata
11911203 cited_xml_temp = os .path .join (folder_path , f"temp_{ cited_params ['codiceRedaz' ]} .xml" )
11921204 if download_akoma_ntoso (cited_params , cited_xml_temp , cited_session , quiet = True ):
@@ -1224,8 +1236,13 @@ def convert_with_references(url, quiet=False, keep_xml=False, force_complete=Fal
12241236 if not quiet :
12251237 print (f"❌ Errore elaborazione { cited_url } : { e } " , file = sys .stderr )
12261238
1227- # Costruisci mapping cross-references
1228- cross_references = build_cross_references_mapping (folder_path , cited_urls , successful_downloads )
1239+ # Rate limiting: wait 1 second between requests to be respectful to normattiva.it
1240+ if not quiet :
1241+ print (f"⏳ Attesa 1 secondo prima del prossimo download..." , file = sys .stderr )
1242+ time .sleep (1 )
1243+
1244+ # Costruisci mapping cross-references basato sugli URL originali
1245+ cross_references = build_cross_references_mapping_from_urls (url_to_file_mapping )
12291246
12301247 # Se abbiamo cross-references, riconverti la legge principale con i link
12311248 if cross_references :
@@ -1358,60 +1375,17 @@ def extract_akoma_uris_from_xml(xml_file_path):
13581375
13591376 return akoma_uris
13601377
1361- def build_cross_references_mapping ( folder_path , cited_urls , successful_downloads ):
1378+ def build_cross_references_mapping_from_urls ( url_to_file_mapping ):
13621379 """
1363- Costruisce un mapping da URI Akoma a percorsi relativi dei file markdown.
1380+ Costruisce un mapping da URL normattiva.it a percorsi relativi dei file markdown.
13641381
13651382 Args:
1366- folder_path: percorso della cartella principale
1367- cited_urls: lista di URL normattiva.it delle leggi citate
1368- successful_downloads: numero di download riusciti
1383+ url_to_file_mapping: dict che mappa URL normattiva.it ai percorsi dei file
13691384
13701385 Returns:
1371- dict: mapping da URI Akoma a percorso relativo del file markdown
1386+ dict: mapping da URL normattiva.it a percorso relativo del file markdown
13721387 """
1373- cross_references = {}
1374- refs_path = os .path .join (folder_path , "refs" )
1375-
1376- if successful_downloads > 0 and os .path .exists (refs_path ):
1377- for filename in os .listdir (refs_path ):
1378- if filename .endswith ('.md' ):
1379- # Estrai parametri dal nome file (es. "400_19880823.md")
1380- # Formato: codiceRedaz_dataGU.md
1381- parts = filename [:- 3 ].split ('_' ) # Rimuovi .md e splitta
1382- if len (parts ) == 2 :
1383- codice_redaz = parts [0 ]
1384- data_gu = parts [1 ]
1385-
1386- # Costruisci possibili URI Akoma basati sui parametri
1387- try :
1388- year = data_gu [:4 ]
1389- month = data_gu [4 :6 ]
1390- day = data_gu [6 :8 ]
1391- date_iso = f"{ year } -{ month } -{ day } "
1392-
1393- relative_path = f"refs/{ filename } "
1394-
1395- # URI principali per diversi tipi di atto
1396- uris_to_try = [
1397- f"/akn/it/act/legge/stato/{ date_iso } /{ codice_redaz } /!main" ,
1398- f"/akn/it/act/legge/stato/{ date_iso } /{ codice_redaz } " ,
1399- f"/akn/it/act/decreto-legge/stato/{ date_iso } /{ codice_redaz } /!main" ,
1400- f"/akn/it/act/decreto-legge/stato/{ date_iso } /{ codice_redaz } " ,
1401- f"/akn/it/act/decretoLegislativo/stato/{ date_iso } /{ codice_redaz } /!main" ,
1402- f"/akn/it/act/decretoLegislativo/stato/{ date_iso } /{ codice_redaz } " ,
1403- f"/akn/it/act/costituzione/stato/{ date_iso } /const/!main" ,
1404- f"/akn/it/act/costituzione/stato/{ date_iso } /const" ,
1405- ]
1406-
1407- # Aggiungi tutti i possibili URI al mapping
1408- for uri in uris_to_try :
1409- cross_references [uri ] = relative_path
1410-
1411- except :
1412- pass
1413-
1414- return cross_references
1388+ return url_to_file_mapping
14151389
14161390def create_index_file (folder_path , main_params , cited_urls , successful , failed ):
14171391 """
@@ -1529,8 +1503,9 @@ def main():
15291503 if not is_normattiva_url (input_source ):
15301504 print ("❌ --with-references può essere usato solo con URL normattiva.it" , file = sys .stderr )
15311505 sys .exit (1 )
1532- if output_file :
1533- print ("❌ --with-references non supporta output file singolo, crea una struttura di cartelle" , file = sys .stderr )
1506+ if output_file and not os .path .isdir (output_file ) and os .path .exists (output_file ):
1507+ print ("❌ --with-references richiede un nome di directory (non un file esistente)" , file = sys .stderr )
1508+ print ("💡 Esempio: akoma2md --with-references <url> [nome_cartella]" , file = sys .stderr )
15341509 sys .exit (1 )
15351510
15361511 # Sanitize output path if provided
@@ -1570,7 +1545,7 @@ def main():
15701545
15711546 # Handle --with-references mode
15721547 if with_references :
1573- success = convert_with_references (input_source , args .quiet , args .keep_xml , args .completo )
1548+ success = convert_with_references (input_source , output_file , args .quiet , args .keep_xml , args .completo )
15741549 if success :
15751550 sys .exit (0 )
15761551 else :
0 commit comments