Next: , Previous: , Up: API  


1.4 (maak i18n)

The gettext workflow, packaged as maak builtins.

Keeping a program translated means running the same four GNU gettext tools in the same order – ‘xgettext’ to gather the strings, ‘msginit’ to start a language, ‘msgmerge’ to fold new strings into it, and ‘msgfmt’ to compile the catalogue the program actually loads. Every project ends up writing those invocations by hand in its maak file; this module writes them once.

The layout is the conventional one:

DIR/TEXTDOMAIN.pot the template DIR/LANG/LC_MESSAGES/TEXTDOMAIN.po one language DIR/LANG/LC_MESSAGES/TEXTDOMAIN.mo the compiled catalogue

so a project that follows the convention only names its DIR, its TEXTDOMAIN, and the LANGUAGES it ships.

1.4.1 Procedures

Procedure: i18n-compile language KEY: #:dir #:textdomain #:verbose?

Compile LANGUAGE’s .po file into the .mo catalogue the program loads.

Procedure: i18n-compile-all languages KEY: #:dir #:textdomain #:verbose?

Run ‘i18n-compile’ for every language of LANGUAGES, skipping missing files.

Procedure: i18n-extract KEY: #:dir #:textdomain #:directories #:extensions #:keywords #:copyright-holders #:package-name #:from-code #:update? #:verbose?

Extract translatable strings from source files into the .pot template.

DIRECTIONS is the list of directories to scan, EXTENSIONS the file types in them, and KEYWORDS the function names xgettext should treat as translatable (‘G_’ by default). With UPDATE? the strings are joined into an existing template instead of starting a fresh one, which keeps translator comments and previous line references.

(i18n-extract #:directories '("lib" "app/views"))
Procedure: i18n-init language KEY: #:dir #:textdomain #:verbose?

Create LANGUAGE’s .po file from the .pot template.

The language directory is created when missing, so a new translation starts with one call. LANGUAGE is a locale name such as nl_NL.

Procedure: i18n-init-all languages KEY: #:dir #:textdomain #:only-missing? #:verbose?

Run ‘i18n-init’ for every language of LANGUAGES.

With ONLY-MISSING? (the default) a language whose .po already exists is skipped, so the call can live in a task that is run repeatedly without clobbering translators’ work with a fresh template.

Procedure: i18n-language

Return the language the process should translate into.

The first of ‘LANGUAGE’, ‘LC_ALL’, ‘LC_MESSAGES’ and ‘LANG’ that is set, with its character encoding and any modifier stripped; when none is set, ‘en_US’ is assumed.

Procedure: i18n-locale-dir language KEY: #:dir

Return the catalogue directory of LANGUAGE inside DIR.

(i18n-locale-dir "nl_NL")
⇒ "po/nl_NL/LC_MESSAGES"
Procedure: i18n-merge language KEY: #:dir #:textdomain #:verbose?

Fold the current .pot template into LANGUAGE’s .po file, in place.

Procedure: i18n-merge-all languages KEY: #:dir #:textdomain #:verbose?

Run ‘i18n-merge’ for every language of LANGUAGES, skipping missing files.

Procedure: i18n-mo-file language KEY: #:dir #:textdomain

Return the path of LANGUAGE’s compiled machine object file (the one the program loads).

Procedure: i18n-po-file language KEY: #:dir #:textdomain

Return the path of LANGUAGE’s portable object file (the one a translator edits).

Procedure: i18n-pot-file KEY: #:dir #:textdomain

Return the path of the template TEXTDOMAIN.pot inside DIR.

Procedure: i18n-refresh languages KEY: #:dir #:textdomain #:directories #:extensions #:keywords #:copyright-holders #:package-name #:verbose?

Do the whole gettext cycle: extract, merge, then compile.

This is the one call a project normally puts in its maak file; the individual steps stay available for anything more unusual.

Procedure: i18n-source-globs directories KEY: #:extensions

Return the file patterns of DIRECTORIES that ‘xgettext’ should read.

A glob that matches nothing is handed to xgettext as itself, and xgettext refuses the whole invocation over the missing file – writing no template at all rather than the strings it did find. Only directories that exist are therefore asked for, so adding or removing a source tree is all a refresh ever needs.

(i18n-source-globs '("lib" "app/views"))
Procedure: i18n-translator KEY: #:dir #:textdomain #:language

Install the catalogue in DIR for TEXTDOMAIN and return a translate procedure.

The returned procedure takes one message and returns its translation, falling back to the original when the catalogue has no entry. LANGUAGE defaults to ‘i18n-language’.

(define G_ (i18n-translator #:dir "po" #:textdomain "maak"))
(G_ "Hello")

Next: (maak maak), Previous: (maak guix), Up: API