Files
rag-from-scratch/conversione/_pipeline/_apply.py
T

111 lines
6.8 KiB
Python
Raw Normal View History

2026-04-30 15:26:52 +02:00
"""Orchestratore: applica le trasformazioni in ordine semantico."""
import re
from functools import partial
from ._encoding import (
_t_fix_symbol_font, _t_fix_accents,
_t_fix_multiplication, _t_fix_micro,
)
from ._artifacts import (
_t_remove_images, _t_fix_br, _t_fix_tabsep, _t_remove_footnotes,
_t_remove_formula_labels, _t_remove_dotleaders, _t_remove_recurring_lines,
_t_fix_math_symbols, _t_remove_watermarks, _t_remove_urls,
_t_remove_page_markers, _t_remove_page_numbers, _t_remove_separators,
2026-04-30 15:26:52 +02:00
)
from ._headers import (
_t_fix_header_concat, _t_extract_capitolo,
_t_normalize_numbered_headings, _t_normalize_header_levels,
_t_remove_header_bold, _t_normalize_allcaps_headers, _t_demote_h1,
2026-04-30 15:26:52 +02:00
)
from ._structure import (
_t_remove_toc, _t_remove_orphan_toc, _t_allcaps_to_headers,
_t_numbered_sections, _t_promote_chapter_headers,
_t_extract_math, _t_extract_articles,
2026-04-30 15:26:52 +02:00
)
from ._text import (
_t_merge_paragraphs, _t_normalize_whitespace, _t_collapse_blank_lines,
_t_restore_poetry_lines, _t_demote_verse_headers,
)
from ._finish import (
_t_remove_empty_headers, _t_merge_title_headers,
_t_remove_garbage_headers, _t_math_header_demotion,
_t_remove_frontmatter,
)
def apply_transforms(text: str, on_step=None) -> tuple[str, dict]:
2026-04-30 15:26:52 +02:00
"""
Applica le trasformazioni strutturali al Markdown grezzo.
Restituisce (testo_modificato, statistiche).
L'ordine è semantico: encoding → artefatti → struttura header →
costruzione struttura → testo → rifinitura.
on_step(i, total, label) — callback opzionale chiamato dopo ogni step.
2026-04-30 15:26:52 +02:00
"""
_has_ex = bool(re.search(r"\b(Esercizi|Exercises|Problems|Homework)\b", text, re.IGNORECASE))
# (stat_key, fn, label)
_transforms: list[tuple[str | None, object, str]] = [
2026-04-30 15:26:52 +02:00
# 1. Encoding
("n_simboli_pua_corretti", _t_fix_symbol_font, "encoding PUA Symbol"),
("n_accenti_corretti", _t_fix_accents, "accenti backtick LaTeX"),
("n_moltiplicazioni_corrette", _t_fix_multiplication, "simbolo moltiplicazione"),
("n_micro_corretti", _t_fix_micro, "simbolo micro SI"),
2026-04-30 15:26:52 +02:00
# 2. Pulizia artefatti
("n_page_markers_rimossi", _t_remove_page_markers, "rimozione page markers PDF"),
("n_separatori_rimossi", _t_remove_separators, "rimozione separatori underscore"),
("n_immagini_rimosse", _t_remove_images, "rimozione immagini"),
("n_br_rimossi", _t_fix_br, "fix <br> inline"),
("n_tabsep_rimossi", _t_fix_tabsep, "fix separatori tabella"),
("n_note_rimosse", _t_remove_footnotes, "rimozione footnote"),
("n_simboli_math_rimossi", _t_fix_math_symbols, "rimozione box math"),
("n_formule_rimossi", _t_remove_formula_labels, "rimozione label formula"),
("n_dotleader_rimossi", _t_remove_dotleaders, "rimozione dot-leader TOC"),
("n_righe_ricorrenti_rimosse", _t_remove_recurring_lines, "rimozione righe ricorrenti"),
("n_numeri_pagina_rimossi", _t_remove_page_numbers, "rimozione numeri pagina isolati"),
2026-04-30 15:26:52 +02:00
# 3. Struttura header
("n_header_concat_fixati", _t_fix_header_concat, "fix header+corpo concatenati"),
(None, _t_extract_capitolo, "estrazione Capitolo inline"),
("n_header_numerati_normalizzati", _t_normalize_numbered_headings, "normalizzazione livelli numerati"),
(None, _t_normalize_header_levels, "normalizzazione livelli ####→###"),
(None, _t_demote_h1, "demozione #→## (sezioni principali)"),
(None, _t_remove_header_bold, "rimozione bold negli header"),
(None, _t_normalize_allcaps_headers, "normalizzazione ALL-CAPS header"),
2026-04-30 15:26:52 +02:00
# 4. Costruzione struttura
("toc_rimosso", _t_remove_toc, "rimozione TOC"),
("n_toc_orfani_rimossi", _t_remove_orphan_toc, "rimozione voci TOC orfane"),
("n_header_allcaps", _t_allcaps_to_headers, "ALL-CAPS → ##"),
("n_sezioni_numerate", partial(_t_numbered_sections, has_exercises=_has_ex), "sezioni numerate → ###"),
("n_capitoli_promossi", _t_promote_chapter_headers, "promozione capitoli ### → ##"),
("n_ambienti_matematici", _t_extract_math, "estrazione ambienti matematici"),
("n_articoli_estratti", _t_extract_articles, "estrazione articoli → ###"),
2026-04-30 15:26:52 +02:00
# 5. Testo
("n_paragrafi_uniti", _t_merge_paragraphs, "merge paragrafi spezzati"),
(None, _t_normalize_whitespace, "normalizzazione whitespace"),
(None, _t_collapse_blank_lines, "riduzione righe vuote"),
("n_versi_ripristinati", _t_restore_poetry_lines, "ripristino versi poesia"),
("n_header_verso_demotati", _t_demote_verse_headers, "demozione header-verso"),
("n_url_rimossi", _t_remove_urls, "rimozione URL"),
2026-04-30 15:26:52 +02:00
# 6. Rifinitura
(None, lambda t: (re.sub(r"(?m)^(#{1,6}.+?)\s+pag\.\s*\d{1,4}\s*$", r"\1", t), 0), "strip pag.N dagli header"),
(None, _t_remove_empty_headers, "rimozione header vuoti"),
("n_titoli_uniti", _t_merge_title_headers, "merge titoli isolati"),
(None, lambda t: (re.sub(r"(?m)^(#{1,6}.+?)\s*\|\s*\d{1,3}\s*$", r"\1", t), 0), "fix header|pagina"),
("n_garbage_headers_rimossi", _t_remove_garbage_headers, "rimozione garbage header"),
("n_formula_headers_demotati", _t_math_header_demotion, "demozione formula-header"),
("n_frontmatter_rimossi", _t_remove_frontmatter, "rimozione frontmatter"),
("n_watermark_rimossi", _t_remove_watermarks, "rimozione watermark"),
2026-04-30 15:26:52 +02:00
]
total = len(_transforms)
2026-04-30 15:26:52 +02:00
stats: dict = {}
for i, (stat_key, fn, label) in enumerate(_transforms, 1):
2026-04-30 15:26:52 +02:00
text, n = fn(text)
if stat_key:
stats[stat_key] = stats.get(stat_key, 0) + n
if on_step:
on_step(i, total, label)
2026-04-30 15:26:52 +02:00
stats["toc_rimosso"] = bool(stats.get("toc_rimosso", 0))
return text, stats