# Kielet - GNU Gettext for Gleam [![Package Version](https://img.shields.io/hexpm/v/kielet)](https://hex.pm/packages/kielet) [![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/kielet/) Kielet is a [GNU Gettext](https://www.gnu.org/software/gettext/) implementation for Gleam. With Kielet, you can translate your Gleam or BEAM application without needing to change its source code or recompile it. Kielet implements translation functions for singular and plural forms and an MO file parser to read compiled translations. Gleam source code can be processed with the `xgettext` program to automatically generate the translation templates (POT files). ## Usage First add Kielet to your project: ```sh gleam add kielet ``` Then you can start annotating your source code to prepare it for translation (skip the file reading and language loading when you don't have languages yet): ```gleam import gleam/io import kielet.{gettext as g_, ngettext as n_} import kielet/context.{Context} import kielet/database import kielet/language import simplifile pub fn main() { // This example uses simplifile to read the MO data let assert Ok(mo_data) = simplifile.read_bits("./path/to/fi.mo") // Load language from MO file let assert Ok(finnish) = language.load("fi", mo_data) // Create language database let db = database.new() |> database.add_language(finnish) // Create translation context to choose active language let ctx = Context(db, "fi") // "Morjens, maailma!" io.println( g_(ctx, "Hello, world!") ) // "Ou jee, mulla on %s euroa" -- The correct plural form is chosen based on the amount provided io.println( n_(ctx, "Nice, I have %s euro", "Nice, I have %s euros", 15) ) } ``` When you have annotated your code, but have no translations, the original messages will be returned. Thus it's safe to add new strings to your program, the worst that can happen is that the original strings will be shown. To start translating your program, first extract the strings from your source code. You should read the documentation of the `xgettext` program to do this, but here is an example command that works for Gleam source code, when you have imported the functions as `g_` and `n_`: ```sh xgettext src/**/*.gleam --keyword=g_:2 --keyword=n_:2,3 -o - --copyright-holder='Your Name' --package-name='Your App' --package-version='X.Y.Z' --msgid-bugs-address='email@example.com' ``` Store this output into a template file with the `.pot` extension and then use a translation app such as [Poedit](https://poedit.net) to create language specific translation files. The output should be human readable PO files that you can add to your version tracking if wanted, and binary MO files that Kielet can read. ### String replacement Note that Kielet does not do any string replacement. It's convention to use `%s` to denote the number of items in a translatable string, but it's not enforced and has no special meaning. This means that the translated message will contain the `%s` unchanged, and it is up to you to replace it with the appropriate number, taking into account the target locale's number format. ### Plural-Forms header Kielet requires a compiled translation file to contain a `Plural-Forms` header to use plurals. There is no builtin database of plural form algorithms, so if such a header does not exist, all attempts at translating plurals will fail. Such a file can be used to translate singular messages, however. ## Gettext limitations Due to how Gettext is built, the source language (the language used in your source files) can only be a language with two plural forms. This means that there is a singular form, used when there is one item, and a plural form that is used for every other amount of items. Unfortunately Gettext does not support languages with more plural forms such as Arabic as the source language. They are supported as translation targets, though. If you do not have any usage of `ngettext` in your code, your source language can be any language. This may be a risky choice, though, since it's quite likely you will need plural forms in the future. ## Development ```sh gleam test # Run the tests ```