import { parsePo, setBase, setActive, t } from '@datamoc/mw_games/i18n';
const po = [
'msgid "greeting"',
'msgstr "Bonjour, {name} !"',
'',
'msgid "apple"',
'msgid_plural "{n} apples"',
'msgstr[0] "une pomme"',
'msgstr[1] "{n} pommes"',
].join('\n');
setBase({ locale: 'en', direction: 'ltr', messages: { greeting: 'Hello, {name}!' } });
setActive(parsePo('fr', po));
console.log(t('greeting', { name: 'Ada' })); // 'Bonjour, Ada !'
console.log(t('apple', { count: 3, n: 3 })); // '{n} pommes'
Parses the useful, dependency-free subset of a gettext
.pofile into ani18nCatalog:msgid/msgstr,msgctxt,msgid_pluralwithmsgstr[N], and the header entry, which is read and dropped. Comments are ignored, and so are flags other than one: a#, fuzzyentry is treated as untranslated, which is what gettext's own tools mean by it, so the base language wins for that key rather than a translation a translator has not signed off on.Gettext's plural forms are positions (
msgstr[0],msgstr[1]), while aCatalogkeys them by CLDR category (whatIntl.PluralRules.selectreturns). The two agree on order for a CLDR-ordered catalog - English's two forms are one/other and Arabic's six are zero/one/two/few/many/other - so formNmaps to the Nth category the locale declares. A catalog with more forms than its locale declares throws rather than silently mislabelling one.An entry with an empty translation is left out, which is what gettext means by "untranslated" and what lets
t()fall back to the base language. Amsgidcarries no placeholder syntax of its own here: write the catalog's own{token}form in the.po, or run the strings throughFormatSpecseparately.