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
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:
@@ -23,6 +23,7 @@ from openpyxl.cell.cell import Cell
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
from services.providers.base import TranslationProvider
|
||||
from core.languages import is_rtl
|
||||
|
||||
|
||||
from core.logging import get_logger
|
||||
@@ -354,6 +355,26 @@ class ExcelTranslator:
|
||||
except Exception as e:
|
||||
_log_error("excel_sheet_images_failed", sheet_name=sheet_name, error=str(e))
|
||||
|
||||
# RTL targets: flip the sheet view so every sheet reads
|
||||
# right-to-left (column A renders rightmost). Content and
|
||||
# formatting are untouched — only the reading direction.
|
||||
# Chartsheets have no `sheet_view` and must never break the
|
||||
# save: each sheet is guarded individually.
|
||||
if is_rtl(target_language):
|
||||
flipped = 0
|
||||
for sheet_name in workbook.sheetnames:
|
||||
ws = workbook[sheet_name]
|
||||
try:
|
||||
if getattr(ws, "sheet_view", None) is not None:
|
||||
ws.sheet_view.rightToLeft = True
|
||||
flipped += 1
|
||||
except Exception as e:
|
||||
_log_error(
|
||||
"excel_rtl_view_failed", sheet=sheet_name, error=str(e)
|
||||
)
|
||||
if flipped:
|
||||
_log_info("excel_rtl_view_applied", sheets=flipped)
|
||||
|
||||
try:
|
||||
workbook.save(output_path)
|
||||
except Exception as e:
|
||||
@@ -580,7 +601,14 @@ class ExcelTranslator:
|
||||
) -> None:
|
||||
"""Collect all translatable text from worksheet cells, cell comments,
|
||||
and cell hyperlinks (URLs are preserved as-is, but their display
|
||||
labels are translated)."""
|
||||
labels are translated).
|
||||
|
||||
Chartsheets are skipped: they have no cell grid (no iter_rows)
|
||||
— their text lives in the chart XML, collected separately from
|
||||
the ZIP.
|
||||
"""
|
||||
if not hasattr(worksheet, "iter_rows"):
|
||||
return
|
||||
for row in worksheet.iter_rows():
|
||||
for cell in row:
|
||||
if cell.value is not None:
|
||||
|
||||
Reference in New Issue
Block a user