md2star.i18n module
Message catalogues for the parts of md2star a person reads.
Two surfaces speak to a human: the CLI’s diagnostics and the local GUI. They were English-only, which for a tool whose documentation ships in two languages was an odd place to stop.
The machinery is os_helper.Catalog, the loader shared across the AI
Helpers suite — stdlib gettext underneath, with .po sources under
md2star/data/locales/<lang>/LC_MESSAGES/ compiled to the .mo it reads.
No Babel, no new dependency, and no build-time toolchain either:
os_helper.compile_catalogs writes the .mo itself, because requiring GNU
gettext’s msgfmt to be installed would make a translated interface harder
to ship than the feature is worth.
What stays here is the policy, which is md2star’s and not the suite’s.
The CLI does not follow your shell locale, on purpose. It answers to
MD2STAR_LANG and nothing else. A converter that silently changes the
language of its own output because LANG says fr_FR is a converter that
breaks every script grepping it, and the diagnostics are as much a machine
interface as a human one. The GUI does negotiate Accept-Language, because
a browser asking for French is a person asking, not an environment variable.
The default is English, not French. Every other member of the suite serves
a French GUI by default; md2star’s CLI prints the language its caller asked
for and nothing else, so with no MD2STAR_LANG the answer must be the source
text. That is why this module keeps a policy layer rather than letting the call
sites reach for Catalog directly.
A message with no translation falls back to the English source — gettext’s own behaviour — so a partial catalogue leaves an interface that is partly translated rather than one that is broken.
- md2star.i18n.DOMAIN = 'md2star'
The gettext domain, and therefore the
.mofile’s stem.
- md2star.i18n.ENV_VAR = 'MD2STAR_LANG'
The one environment variable the CLI listens to. Deliberately ours rather than
LANG: see the module docstring.
- md2star.i18n.SOURCE_LANGUAGE = 'en'
The language the sources are written in, so it never needs a catalogue.
- md2star.i18n.candidates(tag)[source]
A language tag plus its base, so
fr-CAfinds thefrcatalogue.A thin alias for
os_helper.language_candidates(), kept because this name is what md2star’s own call sites and tests already use.
- md2star.i18n.catalog()[source]
The suite’s shared catalogue loader, bound to this package.
default_languageis the source language, which is what makes an absentMD2STAR_LANGprint English rather than French. The rest of the suite defaults its GUIs to French; a CLI that answers to its caller cannot.- Return type:
Catalog
- md2star.i18n.gettext(message)[source]
Translate message for the CLI’s ambient language.
Named to read as
_()at the call site:from .i18n import gettext as _ print(_("Wrote: %s") % path)
- md2star.i18n.locales_dir()[source]
Where the compiled catalogues live, inside the installed package.
- Return type:
- md2star.i18n.negotiate(header)[source]
Best language from an
Accept-Languageheader, orNone.Honours
qweights and falls back to a base language, so a browser asking forfr-CA;q=0.9, en;q=0.8gets thefrcatalogue. ReturnsNonewhen the best match is English or when nothing offered has a catalogue — both of which mean “leave the source text alone”.
- md2star.i18n.ngettext(singular, plural, n)[source]
Plural-aware lookup —
npicks the form the language actually uses.
- md2star.i18n.reset_cache()[source]
Forget every resolved catalogue, so the next lookup reads afresh.
The language is resolved from the environment on each call, but the catalogue behind it is cached — twice, once for the handle and once per language inside it. A test that writes a new
.pomid-run, or changes which languages exist, needs both cleared or it reads the old answer. ChangingMD2STAR_LANGalone does not: that is read every time.- Return type:
None
- md2star.i18n.translator(tag=None)[source]
The catalogue for tag, or a pass-through when there is none.
A tag with no catalogue yields a pass-through rather than a fallback language: here “no catalogue” means English, which is the source, so returning each message unchanged is exactly the right answer.
- Parameters:
tag (str | None)
- Return type: