lib.i18n
Internacionalización: función _() para CLI y GUI.
Prioridad de idioma: config (~/.config/temario/temario.yaml) → TEMARIO_LANG (variable de entorno) → LANG del sistema → fallback (español, idioma fuente)
Uso:
from lib.i18n import _ # en cualquier módulo import lib.i18n as i18n; i18n.setup() # una vez al inicio de la app (main.py / __main__) print(_("hola"))
1# Copyright (C) 2026 David Vaquero <pepesan@gmail.com> 2# 3# This program is free software: you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation, either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16""" 17Internacionalización: función _() para CLI y GUI. 18 19Prioridad de idioma: config (~/.config/temario/temario.yaml) 20 → TEMARIO_LANG (variable de entorno) 21 → LANG del sistema 22 → fallback (español, idioma fuente) 23 24Uso: 25 from lib.i18n import _ # en cualquier módulo 26 import lib.i18n as i18n; i18n.setup() # una vez al inicio de la app (main.py / __main__) 27 print(_("hola")) 28""" 29 30import builtins 31import gettext 32import os 33from pathlib import Path 34 35_LOCALES_DIR = Path(__file__).parent.parent / 'locales' 36_DOMAIN = 'escriba' 37 38_gettext_func = lambda s: s # identidad hasta que setup() se llame 39 40 41def _(s: str) -> str: # noqa: E743 (nombre corto intencionado) 42 """Traduce s al idioma activo. No-op hasta que setup() sea llamado.""" 43 return _gettext_func(s) 44 45 46def _detect_lang() -> str | None: 47 """Detecta el idioma a usar: config → ESCRIBA_LANG → LANG del sistema.""" 48 try: 49 from lib.slides_config import get_language 50 lang = get_language() 51 if lang: 52 return lang 53 except Exception: 54 pass 55 if env := os.environ.get('ESCRIBA_LANG', '').strip(): 56 return env 57 system = os.environ.get('LANG', '').split('_')[0].split('.')[0].lower() 58 return system or None 59 60 61def setup(lang: str | None = None) -> None: 62 """Activa la traducción. Llamar una vez al inicio de la app.""" 63 global _gettext_func 64 if lang is None: 65 lang = _detect_lang() 66 t = gettext.translation( 67 _DOMAIN, 68 localedir=str(_LOCALES_DIR), 69 languages=[lang] if lang else None, 70 fallback=True, 71 ) 72 _gettext_func = t.gettext 73 builtins._ = _ # disponible globalmente para módulos que no importen i18n 74 75 76# Instalar identidad en builtins como fallback (antes de setup()) 77if not hasattr(builtins, '_'): 78 builtins._ = _
def
setup(lang: str | None = None) -> None:
62def setup(lang: str | None = None) -> None: 63 """Activa la traducción. Llamar una vez al inicio de la app.""" 64 global _gettext_func 65 if lang is None: 66 lang = _detect_lang() 67 t = gettext.translation( 68 _DOMAIN, 69 localedir=str(_LOCALES_DIR), 70 languages=[lang] if lang else None, 71 fallback=True, 72 ) 73 _gettext_func = t.gettext 74 builtins._ = _ # disponible globalmente para módulos que no importen i18n
Activa la traducción. Llamar una vez al inicio de la app.