"""Rendu HTML de la vue « Modernisation lexicale » — Sprint 80. A.I.7 du plan d'évolution 2026. Suite directe ``picarones/core/lexical_modernization.py``. Pattern identique aux autres rendus (Sprints 41/43/62/67/72/74/75/76/77) : **server-side**, pas de JavaScript, anti-injection systématique. Vue --- Tableau trié par taux de modernisation décroissant : forme historique GT → forme(s) modernisée(s), occurrences GT, %. Couleur de cellule pour le %. """ from __future__ import annotations from html import escape as _e from typing import Optional from picarones.measurements.lexical_modernization import top_modernized_tokens from picarones.report.render_helpers import ( GRADIENT_TARGET_ORANGE, color_single_gradient, ) def _format_variants(variants: dict, max_show: int = 3) -> str: """Liste compacte des variants modernisés.""" items = sorted(variants.items(), key=lambda kv: -kv[1]) shown = items[:max_show] rest = len(items) - max_show parts = [ f"{_e(form)} ({count})" for form, count in shown ] if rest > 0: parts.append(f"+{rest}") return ", ".join(parts) def build_lexical_modernization_html( data: Optional[dict], labels: Optional[dict[str, str]] = None, *, top_n: int = 20, min_total: int = 1, ) -> str: """Construit la table HTML de modernisation lexicale. Retourne ``""`` si ``data is None`` ou si aucun token modernisé. """ if not data: return "" rows = top_modernized_tokens(data, n=top_n, min_total=min_total) if not rows: return "" labels = labels or {} title = labels.get( "lexmod_title", "Modernisation lexicale (top tokens)", ) note = labels.get( "lexmod_note", "Tokens GT que le moteur réécrit le plus souvent. " "Lecture : « maistre → maître modernisé dans 85 % des cas » " "indique de quoi corriger dans le prompt pour préserver " "l'orthographe historique.", ) gt_label = labels.get("lexmod_gt_label", "Forme historique GT") hyp_label = labels.get("lexmod_hyp_label", "Variantes OCR") n_label = labels.get("lexmod_n_label", "n GT") rate_label = labels.get("lexmod_rate_label", "% modernisé") parts = [ '
| ' f'{_e(col)} | ' ) parts.append("|||
|---|---|---|---|
| ' f'{_e(gt_token)} | ' f'' f'{variants_str} | ' f'{n_total} | ' f'' f'{rate * 100:.0f}% | ' f'