GNU gettext Catalog I/O (.po / .mo)
The repo has i18n_test (pseudo-localisation, catalog placeholder checks) and
message_format (ICU rendering) but no reader for the de-facto translation
format — GNU gettext .po / .mo. This parses .po text (contexts,
plurals, multi-line strings, escapes, the Plural-Forms header), compiles the
binary .mo (the same little-endian format Python’s own gettext reads) and
exposes gettext / ngettext / pgettext lookups.
Pure standard library (re / struct / gettext.c2py for the plural
expression); imports no PySide6. Parsing and compilation are pure data
in / data out, so they are fully deterministic in CI.
Headless API
from je_auto_control import parse_po, read_mo, GettextCatalog
catalog = parse_po(po_text)
catalog.gettext("Hello") # 'Hola'
catalog.ngettext("file", "files", 3) # 'archivos'
catalog.pgettext("menu", "Open") # 'Abrir'
mo_bytes = catalog.compile_mo("out/messages.mo") # or .to_mo_bytes()
same = read_mo(mo_bytes) # round-trips, incl. plural rules
# build one by hand
cat = GettextCatalog()
cat.add("apple", ["pomme", "pommes"], plural_id="apples")
gettext returns the translation (or the source msgid when untranslated);
ngettext evaluates the catalog’s Plural-Forms expression (via
gettext.c2py) to pick the right form for n; pgettext adds a
disambiguation context. to_mo_bytes / compile_mo emit a standards-
compliant .mo that Python’s own gettext.GNUTranslations can load, and
read_mo / read_mo_file parse one back (little- or big-endian).
Executor commands
AC_gettext_translate parses an inline .po string and returns {text}
for a msgid (optional context); AC_gettext_ngettext returns the
plural-correct {text} for a count n. Both are exposed as MCP tools
(ac_gettext_translate / ac_gettext_ngettext) and as Script Builder
commands under Data.