{"id":18301364,"url":"https://github.com/lvgl/lv_i18n","last_synced_at":"2025-04-07T16:18:46.247Z","repository":{"id":40401776,"uuid":"169691498","full_name":"lvgl/lv_i18n","owner":"lvgl","description":"Internationalization (i18n) for LVGL","archived":false,"fork":false,"pushed_at":"2024-10-29T13:21:49.000Z","size":316,"stargazers_count":59,"open_issues_count":7,"forks_count":17,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-29T16:03:13.477Z","etag":null,"topics":["i18n","localization","lvgl","multilanguage"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lvgl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/template_data.yml","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-08T05:54:01.000Z","updated_at":"2024-10-29T13:21:54.000Z","dependencies_parsed_at":"2024-01-23T22:08:19.717Z","dependency_job_id":"9f4b452b-210e-4c29-9972-a1c5f89d35b7","html_url":"https://github.com/lvgl/lv_i18n","commit_stats":null,"previous_names":["littlevgl/lv_i18n"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_i18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_i18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_i18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lvgl%2Flv_i18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lvgl","download_url":"https://codeload.github.com/lvgl/lv_i18n/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247685628,"owners_count":20979085,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["i18n","localization","lvgl","multilanguage"],"created_at":"2024-11-05T15:15:27.313Z","updated_at":"2025-04-07T16:18:46.229Z","avatar_url":"https://github.com/lvgl.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"lv_i18n - Internationalization for LittlevGL\n============================================\n\n[![Build Status](https://github.com/lvgl/lv_i18n/actions/workflows/.github/workflows/ci.yml/badge.svg)](https://github.com/lvgl/lv_i18n/actions/workflows/ci.yml)\n[![NPM version](https://img.shields.io/npm/v/lv_i18n.svg?style=flat)](https://www.npmjs.org/package/lv_i18n)\n\nLightweight [gettext](https://www.gnu.org/software/gettext/) replacement\ntools for C. Add multi-language support to your embedded projects with ease.\n\n\n## Quick overview\n\n1. Mark up the text in your C files as `_(\"some text\")` (singular) and `_p(\"%d item\", item_cnt)` (plural)\n2. Create template `yml` files for the translations you are interested in\n3. Run `extract` to fill the `yml` files with the texts in `_()` and `_p()`\n4. Add the translations into the `yml` files\n5. Run `compile` to convert the `yml` files to a C and H file. They will contain the translations and all the background functions you need.\n6. Be sure your fonts contain the required characters. See [the docs here](https://docs.lvgl.io/latest/en/html/overview/font.html) for more details.\n\n## Install/run the script\n\n[node.js](https://nodejs.org/en/download/) required.\n\nGlobal install of the last version, execute as \"lv_i18n\"\n\n```sh\nnpm i lv_i18n -g\n```\n\n**Alternatives:**\n\nInstall from github's repo, master branch\n\n```sh\nnpm i littlevgl/lv_i18n -g\n```\n\nIf you wish local install for your project, do in project root:\n\n```sh\nnpm init private\nnpm i lv_i18n -s\n# now available at ./node_modules/.bin/lv_i18n\n```\n\nThen commit `package.json` \u0026 put `/node_modules` into `.gitignore`. Next time\nuse just `npm i` to install.\n\n**run via [npx](https://www.npmjs.com/package/npx)**\n\n`node.js` has built-in [npx](https://www.npmjs.com/package/npx) utility to\nexecute packages \"without install\":\n\n```sh\n# run from github master\nnpx github:littlevgl/lv_i18n -h\n# run from npm registry\nnpx lv_i18n -h\n```\n\n\n## Mark up the text in your code\n\n```c\n#include \"lv_i18n/lv_i18n.h\"  /*Assuming you have the translations here. (See below)*/\n\n/* Load translations \u0026 default locale (usually, done once) */\nlv_i18n_init(lv_i18n_language_pack);\n\n/* Set active locale (can be switched anytime) */\nlv_i18n_set_locale(\"ru-RU\");\n\n/* The translation of \"title1\" will be returned according to the selected locale.\n * (\"title1\" is only a unique ID of the text.) Example:\n * en-GB: \"Main menu\"\n * ru_RU: \"Главное меню\"\n */\ngui_set_text(label, _(\"title1\"));\n\n/* According to `user_cnt` different text can be returned\n * en-GB `user_cnt == 1` : \"One user is logged in\"\n *        `user_cnt == 6` : \"%d users are logged in\"  \n */\nchar buf[64];\nsprintf(buf, _p(\"user_logged_in\", user_cnt)), user_cnt);  /*E.g. buf == \"7 users are logged in\"*/\ngui_set_text(label, buf);\n```\n\n`_` and `_p` are normal functions. They just have this short name to enable fast typing of texts.\n\nRules of getting the translation:\n- If the translation is not available on the selected locale then the default language will be used instead\n- If the translation is not available on the default locale the text ID (\"title1\" in the example) will be returned\n\n\n## Create template yml files for the translations\n\nFor each translation, you need to create a `yml` file with \"language code\" name. For example:\n\n- en-GB.yml\n- ru-RU.yml\n\nHere is a [list](https://www.andiamo.co.uk/resources/iso-language-codes/) of the language and locale codes.\n\nAdd the `locale-name: ~` line to the `yml` files. Replace \"locale-name\" with the actual language code.   \nE.g.: `en-GB: ~` or simply `en: ~`\n\nTechnically you can have one `yml` file where you list all language codes you need but its more modular to separate them.\n\n\n## Run extract to fill the yml files\n\nRun `extract` like this (assuming your source files are in the `src` folder and the `yml` files in the translations folder):\n\n```sh\nlv_i18n extract -s 'src/**/*.+(c|cpp|h|hpp)' -t 'translations/*.yml'\n```\n\nIt will fill the `yml` files the texts marked with `_` and  `_p`.\nFor example:\n\n```yml\nen-GB:\n  title1: ~\n  user_logged_in:\n    one: ~\n    other: ~\n```\n\n\n## Add the translations into the yml files\n\nThe naming conventions in the `yml` files follow the rules of [CLDR](https://cldr.unicode.org/translation/displaynames/languagelocale-names) so most of the translation offices will know them.\n\nExample:\n\n```yml\n'en-GB':\n  title1: Main menu\n  user_logged_in:\n    one: One user is logged in\n    other: '%d users are logged in'\n```\n\nIf translators want to know where a message comes from, then use `lv_i18n extract --dump-sourceref sr.json ...` to generate the file `sr.json` containing file names and line number of each message.\n\n## Run compile to convert the yml files to a C and H file\n\nOnce you have the translations in the `yml` files you only need to run the `compile` to generate a C and H files from the `yml` files. No other library will be required to get the translation with `_()` and `_p`.\n\nRunning `compile`:\n\n```sh\nlv_i18n compile -t 'translations/*.yml' -o 'src/lv_i18n'\n```\n\nThe default locale is `en-GB` but you change it with `-l 'language-code'`.\n\nYou can use `--optimize` to generate optimized C code. Without this, finding the corresponding translation by `lv_i18n_get_text()` is done by searching through all keys until the right one is found. This can eat up a lot of CPU espcially if the list is long (aka O(n)). Using `--optimize` changes this behaviour by using an integer index into the list of strings resulting in an immediate return of the right string (aka O(1)). As the index is computed at compile time, you need a compiler, which is able to evaluate `strcmp()` with constants at compile time. All modern compilers, like gcc and clang are able to do this. If you want to check, whether your compiler is able to handle this optimization, you can use the following code to check this:\n\n```c\nint main()\n{\n  return strcmp(\"a\", \"a\");\n}\n```\n\nIf this compiles without needing `#include \u003cstring.h\u003e` and `nm -u a.out` does not output `strcmp` as being undefined, then the compiler optimizes the code and is able to handle `--optimize`.\n\n## Follow modifications in the source code\nTo change a text id in the `yml` files use:\n```sh\nlv_i18n rename -t src/i18n/*.yml --from 'Hillo wold' --to 'Hello world!'\n```\n\n## Example application\n\nYou can find a complete example application inside the `example/`\ndirectory. Please see [Example README](example/README.md) for more\ninformation.\n\n## C API\n\n#### int lv_i18n_init(const lv_i18n_language_pack_t * langs)\nAttach generated translations to be used by `lv_i18n_get_text()`.\n\n- _return_ - 0 on success, -1 on fail.\n\n___\n\n#### int lv_i18n_set_locale(const char * l_name)\nSet locale to be used by `lv_i18n_get_text()`.  \n\n- _l_name_ - locale name (`en-GB`, `ru-RU`).\n- _returns_ - 0 on success, -1 if locale not found.\n\n___\n\n#### const char * lv_i18n_get_text(const char * msg_id)\nMapped to `_(...)` or `_t(...)` via `#define`  \n\nGet translated text. If not translated, return fallback (try default locale\nfirst, then input param if default not exists)  \n- _msg_id_ - The ID of a text to translate (e.g. `\"title1\"`)  \n- _return_ - pointer to the traslation  \n\n___\n\n#### char* lv_i18n_get_text_plural(char* msg_id, int32_t plural)\nMapped to `_p(...)` or `_tp(...)` via `#define`\n\nGet the plural form of translated text. Use current locale to select plural\nalgorithm. If not translated, fallback to default locale first, then to input\nparam.\n\n- _msg_id_ - The ID of a text to translate (e.g. `\"title1\"`)  \n- _plural_ - number of items to decide which plural for to use  \n- _return_ - pointer to the traslation  \n\n## References:\n\nTo understand i18n principles better, you may find useful links below:\n\n- [gettext](https://www.gnu.org/software/gettext/)\n- [Rails Internationalization (I18n) API](https://guides.rubyonrails.org/i18n.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flvgl%2Flv_i18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flvgl%2Flv_i18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flvgl%2Flv_i18n/lists"}