{"id":16971743,"url":"https://github.com/juancarlospaco/nim-nimterlingua","last_synced_at":"2026-01-04T13:54:56.470Z","repository":{"id":55916674,"uuid":"167878855","full_name":"juancarlospaco/nim-nimterlingua","owner":"juancarlospaco","description":"Internationalization at Compile Time for Nim","archived":false,"fork":false,"pushed_at":"2022-05-19T14:48:19.000Z","size":35,"stargazers_count":41,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-26T14:48:40.722Z","etag":null,"topics":["compile-time","gettext","gettext-library","i18n","internationalization","localization","nim","nim-lang","po-editor","speed","translation"],"latest_commit_sha":null,"homepage":"https://gist.github.com/juancarlospaco/37da34ed13a609663f55f4466c4dbc3e","language":"Nim","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/juancarlospaco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"custom":["https://gist.github.com/juancarlospaco/37da34ed13a609663f55f4466c4dbc3e"]}},"created_at":"2019-01-28T01:17:06.000Z","updated_at":"2025-01-24T22:59:30.000Z","dependencies_parsed_at":"2022-08-15T09:20:45.572Z","dependency_job_id":null,"html_url":"https://github.com/juancarlospaco/nim-nimterlingua","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juancarlospaco%2Fnim-nimterlingua","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juancarlospaco%2Fnim-nimterlingua/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juancarlospaco%2Fnim-nimterlingua/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juancarlospaco%2Fnim-nimterlingua/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/juancarlospaco","download_url":"https://codeload.github.com/juancarlospaco/nim-nimterlingua/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244860611,"owners_count":20522466,"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":["compile-time","gettext","gettext-library","i18n","internationalization","localization","nim","nim-lang","po-editor","speed","translation"],"created_at":"2024-10-14T00:54:19.615Z","updated_at":"2026-01-04T13:54:56.421Z","avatar_url":"https://github.com/juancarlospaco.png","language":"Nim","funding_links":["https://gist.github.com/juancarlospaco/37da34ed13a609663f55f4466c4dbc3e"],"categories":[],"sub_categories":[],"readme":"# Nimterlingua\n\n- Internationalization and localization at Compile Time for Nim.\n- 1 Macro to replace strings in-place at compile time with 0 cost at runtime.\n- Translate unmodified code from 1 INI file. Replace Emojis and Unicode in-place.\n- High performance with low resources, everything is done compile-time only!.\n\n\n# Use\n\n**translations.cfg:**\n```ini\n# This is a comment.\n[cat]\nES_AR = gato\nPT_BR = minino\n\n\n\n[dog]\nES_AR = perro\nPT_BR = cão\n\n; You can replace Emojis. This is a comment.\n[:crown:]\nES_AR = 👑\nPT_BR = 👑\n\n\n```\n\n**Nim:**\n\n```nim\nimport nimterlingua\n\nnimterlingua()\necho \"cat\"\necho \"dog\"\necho \":crown:\"\n```\n\n**Compile:**\n```\nnim c -r -d:ES_AR -d:iniFile=\"translations.cfg\" yourfile.nim\n```\n\nor\n\n```\nnim c -r -d:PT_BR -d:iniFile=\"translations.cfg\" yourfile.nim\n```\n\n\n**NimScript:**\n\n```nim\nimport nimterlingua\n\nnimterlingua()\necho \"cat\"\necho \"dog\"\necho \":crown:\"\n```\n\n\n**Run:**\n```\nnim e -d:ES_AR -d:iniFile=\"translations.cfg\" yourfile.nims\n```\n\nor\n\n```\nnim e -d:PT_BR -d:iniFile=\"translations.cfg\" yourfile.nims\n```\n\n\n**NodeJS:**\n\n```nim\nimport nimterlingua\n\nnimterlingua()\necho \"cat\"\necho \"dog\"\necho \":crown:\"\n```\n\n**Compile:**\n```\nnim js -d:nodejs -d:ES_AR -d:iniFile=\"translations.cfg\" yourfile.nim\n```\n\nor\n\n```\nnim js -d:nodejs -d:PT_BR -d:iniFile=\"translations.cfg\" yourfile.nim\n```\n\n\n# Example\n\n```nim\n$ cd example\n$ nim c -r -d:ES_AR -d:iniFile=\"translations.cfg\" bohemian_rhapsody.nim\n\nbohemian_rhapsody.nim(5, 11) Hint: ES_AR0(\"Is this the real life?\") --\u003e '\"Es la vida real?\"' [Pattern]\nbohemian_rhapsody.nim(6, 11) Hint: ES_AR1(\"Is this just fantasy?\") --\u003e '\"Es sólo fantasía?\"' [Pattern]\nbohemian_rhapsody.nim(7, 11) Hint: ES_AR2(\"Caught in a landslide\") --\u003e '\"Atrapado en un derrumbe\"' [Pattern]\nbohemian_rhapsody.nim(13, 9) Hint: ES_AR3(\"No escape from reality\") --\u003e '\"Sin escape de la realidad\"' [Pattern]\nbohemian_rhapsody.nim(14, 9) Hint: ES_AR4(\"Open your eyes\") --\u003e '\"Abre tus ojos\"' [Pattern]\nbohemian_rhapsody.nim(15, 11) Hint: ES_AR5(\"Look up to the skies and see\") --\u003e '\"Mira a los cielos y observa\"' [Pattern]\nbohemian_rhapsody.nim(21, 7) Hint: ES_AR6(\"I\\'m just a poor boy, I need no sympathy\") --\u003e '\"Sólo soy un chico pobre, no necesito simpatía\"' [Pattern]\nbohemian_rhapsody.nim(22, 7) Hint: ES_AR7(\"Because I\\'m easy come, easy go\") --\u003e '\"Porque fácil vengo, fácil me voy\"' [Pattern]\nbohemian_rhapsody.nim(23, 7) Hint: ES_AR8(\"A little high, little low\") --\u003e '\"Un poco alto, un poco bajo\"' [Pattern]\nbohemian_rhapsody.nim(28, 6) Hint: ES_AR9(\"Anyway the wind blows, doesn\\'t really matter to me, to me\") --\u003e '\"De todos modos el viento sopla, realmente no me importa, a mi\"' [Pattern]\nbohemian_rhapsody.nim(29, 11) Hint: ES_AR10(\"Mama, just killed a man\") --\u003e '\"Mamá, maté a un hombre\"' [Pattern]\nbohemian_rhapsody.nim(32, 3) Hint: ES_AR11(\"Put a gun against his head\") --\u003e '\"Puse una pistola en su cabeza\"' [Pattern]\nbohemian_rhapsody.nim(36, 3) Hint: ES_AR12(\"Pulled my trigger, now he\\'s dead\") --\u003e '\"Jalé el gatillo, ya está muerto\"' [Pattern]\nbohemian_rhapsody.nim(42, 9) Hint: ES_AR15(\"Mama, ooo, Didn\\'t mean to make you cry\") --\u003e '\"Mamá, ooo, No quise hacerte llorar\"' [Pattern]\nbohemian_rhapsody.nim(44, 6) Hint: ES_AR16(\"If I\\'m not back again this time tomorrow\") --\u003e '\"Si no regreso mañana a esta hora\"' [Pattern]\nbohemian_rhapsody.nim(45, 6) Hint: ES_AR17(\"Carry on, carry on, as if nothing really matters\") --\u003e '\"Continúa, continúa, como si nada realmente importara\"' [Pattern]\n\n\nEs la vida real?\nEs sólo fantasía?\nAtrapado en un derrumbe\nSin escape de la realidad\nAbre tus ojos\nMira a los cielos y observa\nSólo soy un chico pobre, no necesito simpatía\nPorque fácil vengo, fácil me voy\nUn poco alto, un poco bajo\nDe todos modos el viento sopla, realmente no me importa, a mi\nMamá, maté a un hombre\nPuse una pistola en su cabeza\nJalé el gatillo, ya está muerto\nSi no regreso mañana a esta hora\nContinúa, continúa, como si nada realmente importara\n\n```\n\n\n### under the hood\n\n\u003cdetails\u003e\n  \u003csummary\u003eHow does it works internally?.\u003c/summary\u003e\n\n```nim\n# expandMacros:\n\nwhen defined(ES_AR):\n  template ES_AR0{(\"cat\"){texts}}(texts: string{lit, noalias}): string =\n    ## Compile with -d:ES_AR to auto translate at compile time to ES_AR Lang ISO code.\n    when texts == \"cat\": \"gato\" else: \"cat\"\n\nwhen defined(PT_BR):\n  template PT_BR1{(\"cat\"){texts}}(texts: string{lit, noalias}): string =\n    ## Compile with -d:PT_BR to auto translate at compile time to PT_BR Lang ISO code.\n    when texts == \"cat\": \"minino\" else: \"cat\"\n\n```\n\n\u003c/details\u003e\n\n\n# Nimterlingua Vs GetText\n\n| Nimterlingua                         | GetText                               |\n|--------------------------------------|---------------------------------------|\n| No `*.po` files                      | You need to write   `*.po` files      |\n| No `*.pot` files                     | You need to extract `*.pot` files     |\n| No `*.mo` files                      | You need to compile `*.mo` files      |\n| No `*.gmo` files                     | You need to compile `*.gmo` files     |\n| Only `nim`                           | `xgettext`, `msginit`, `msgfmt`, etc  |\n| Any editor, `*.INI` format           | Requires `poedit` for fluent workflow |\n| Unmodified code can be translated    | Requires refactor adding gettext functions |\n| `\"cat\"`                              | `gettext(\"cat\")` or `_(\"cat\")`        |\n| No GetText dependency                | GetText libs as dependency            |\n| 0 cost at runtime performance        | [Slows runtime performance (even on C)](https://stackoverflow.com/questions/18268608/performance-overhead-of-the-gettext-internationalization-system-in-c-c)     |\n| `*.INI` is easy to delegate to people | `*.po` format complex for non-tech people |\n| Chill Lazy Dev                       | Time consuming beyond translation itself   |\n\n**GetText**\n```pot\n#. TRANSLATORS: Thank you for contributing to this project.\n#: src/name.c:36\nmsgid \"cat\"\nmsgstr \"gato\"\n\n```\n\n**Nimterlingua**\n```ini\n[cat]\nES_AR = gato\n```\n\n# Beyond Translation\n\nIts designed for translation, but it does not force anything on you,\nyou can be creative and explore other possible uses.\n\nIt replaces in-place any arbitrary `string` with any arbitrary `string` you want at compile time with 0 cost at runtime without touching the code.\n\n_Let us know if you built something cool with it!._\n\n\n# FAQ\n\n- Its not possible to have different languages in 1 Nim program?.\n\nUse a period (dot), exclamation, space, emoji or something, the string will not match anymore.\n\n```ini\n[cat]\nES_AR = gato\n```\n\n```nim\nif useSpanish: \"cat\" else: \"cat.\"\n```\n\n`\"cat\"` get translated to Spanish, `\"cat.\"` remains English, because of period.\n\nYou choose languages with `if` or `case` or similar on your code.\n\nOr use NimScript or NodeJS to get a JSON or CSV or similar format and get the data from there.\n\n\n- I get `nimterlingua.nim(17, 29) Error: cannot open file: translations.cfg` ?\n\ncompile with `-d:iniFile=\"path to your translations.cfg\"`\n\n- Is there a Minimal Basic example?.\n\nhttps://github.com/juancarlospaco/nim-nimterlingua/blob/master/example/minimal.nims\n\n- How do you use this with Python or NodeJS or JavaScript?.\n\nhttps://github.com/juancarlospaco/nim-nimterlingua/blob/master/example/minimal.nims\n\n- This works with NodeJS and JavaScript?.\n\nYes.\n\n- My Translated text contains `=` will make it fail?.\n\nUse `splitter=\":\"`, then use it as splitter separator.\n\n```ini\n[cat]\nES_AR : gato\n```\n\n- How to make an INI for a lot of languages?.\n\n```ini\n[cat]\nES_AR = gato\nPT_BR = minino\nRU    = kot\nFR    = chat\n# A lot of languages here...\n```\n\n- This is not the same as Search\u0026Replace of any Editor?.\n\nNo.\nBecause it actually fully understands the code,\ntypical Search\u0026Replace of Editor can break comments, names, variables, etc.\n\n\n# Stars\n\n![](https://starchart.cc/juancarlospaco/nim-nimterlingua.svg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuancarlospaco%2Fnim-nimterlingua","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuancarlospaco%2Fnim-nimterlingua","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuancarlospaco%2Fnim-nimterlingua/lists"}