feat(rtl): rendu droite-a-gauche complet pour Word, PowerPoint, Excel et PDF
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m37s

- source unique RTL_LANGUAGES/is_rtl dans core/languages.py (fin des 3 copies)
- Word: bidi partout (corps, tableaux bidiVisual, notes/fin/commentaires,
  zones de texte, 6 zones d'en-tetes/pieds), insertion OOXML ordonnee,
  polices cs elargies aux 11 langues
- PowerPoint: alignements explicites preserves, notes du presentateur,
  indice de police <a:cs> insert a sa place
- Excel: feuilles affichees de droite a gauche, feuilles graphiques ignorees
- PDF: faconnage bidi (arabic-reshaper + python-bidi), polices par ecriture
  (arabe/hebreu), TTF enregistree pour le PDF recompose
- 46 tests nouveaux (tests/test_translators/test_rtl_layout.py), 253 au total
This commit is contained in:
2026-09-01 20:22:46 +02:00
parent fddd7b7428
commit f22f645fab
12 changed files with 1727 additions and 80 deletions

View File

@@ -7,7 +7,7 @@ prompts say "Translate to Tagalog" instead of "Translate to tl" — LLMs
translate noticeably better with full language names.
"""
from typing import Dict
from typing import Dict, Optional
LANGUAGE_NAMES: Dict[str, str] = {
"af": "Afrikaans",
@@ -135,3 +135,22 @@ def language_name(code: str) -> str:
if name is None:
name = LANGUAGE_NAMES.get(code.split("-")[0].lower(), code)
return name
# Languages written right-to-left. Single source of truth shared by every
# translator (Word, PowerPoint, Excel, PDF) — do not duplicate this set.
RTL_LANGUAGES: frozenset = frozenset(
{"ar", "he", "fa", "ur", "ku", "ps", "ug", "sd", "yi", "dv", "ckb"}
)
def is_rtl(code: Optional[str]) -> bool:
"""True when the language is written right-to-left.
Case and regional suffixes are ignored: "fa-IR", "AR" and "ar-EG" are
RTL, "fr" and "" are not. None is accepted (treated as not RTL).
"""
if not code:
return False
base = code.strip().replace("_", "-").split("-")[0].lower()
return base in RTL_LANGUAGES