├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── config.yml └── workflows │ ├── add-stars.yml │ ├── antispamm.yml │ ├── stale.yml │ └── welcome-new-users.yml ├── .gitignore ├── LICENSE ├── README.md ├── example ├── bohemian_rhapsody.nim ├── bohemian_rhapsody.nim.cfg ├── minimal.nims └── translations.cfg ├── nimterlingua.nimble └── src ├── nimterlingua.nim └── translations.cfg /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://gist.github.com/juancarlospaco/37da34ed13a609663f55f4466c4dbc3e"] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: "BUG Report" 2 | description: "Create a new Bug report." 3 | title: "[bug] " 4 | labels: ["unconfirmed"] 5 | assignees: ["juancarlospaco"] 6 | body: 7 | 8 | - type: markdown 9 | attributes: 10 | value: | 11 | - **Remember to :star: Star the project on GitHub!.** 12 | - **Please provide a minimal code example that reproduces the :bug: Bug!.** 13 | Reports with full repro code and descriptive detailed information will be fixed faster. 14 | - [Please, keep in mind there is ZERO FUNDING for the project!, we have no sponsors, no company behind, no dev team, 15 | :heart: Send crypto today to speed up development!](https://gist.github.com/juancarlospaco/37da34ed13a609663f55f4466c4dbc3e) 16 | 17 | - type: dropdown 18 | id: architecture 19 | attributes: 20 | label: Architecture 21 | description: What is your Hardware Architecture? 22 | options: 23 | - x86_64 (Default) 24 | - x86_32 (32Bit) 25 | - ARM_64 (64Bit) 26 | - ARM_32 (32Bit) 27 | - AVR (Arduino, ESP32) 28 | - RISC (RISC-V) 29 | - Others (Unkown) 30 | validations: 31 | required: true 32 | 33 | - type: dropdown 34 | id: os 35 | attributes: 36 | label: Operating System 37 | description: What is your Operating System? 38 | options: 39 | - Linux 40 | - Windows 41 | - Mac OSX 42 | - Android 43 | - BSD 44 | - FreeDOS 45 | - ReactOS 46 | - Others (Unkown) 47 | validations: 48 | required: true 49 | 50 | - type: dropdown 51 | id: disk 52 | attributes: 53 | label: Disk 54 | description: What is your main Disk Storage? 55 | options: 56 | - SSD (Solid) 57 | - HDD (SATA, IDE, Mechanical) 58 | - NVME (M2, MSATA) 59 | - Others (USB) 60 | validations: 61 | required: true 62 | 63 | - type: dropdown 64 | id: ram 65 | attributes: 66 | label: Memory 67 | description: What is your total RAM Memory capacity? 68 | options: 69 | - 1 Gigabytes 70 | - 2 Gigabytes 71 | - 4 Gigabytes 72 | - 8 Gigabytes 73 | - 16 Gigabytes 74 | - 32 Gigabytes 75 | - 64 Gigabytes 76 | - 128 Gigabytes 77 | - 256 Gigabytes 78 | - 512 Gigabytes 79 | - Others (Unkown) 80 | validations: 81 | required: true 82 | 83 | - type: dropdown 84 | id: cores 85 | attributes: 86 | label: CPU Cores 87 | description: What is your total CPU Cores count? 88 | options: 89 | - 1 CPU Cores 90 | - 2 CPU Cores 91 | - 4 CPU Cores 92 | - 8 CPU Cores 93 | - 16 CPU Cores 94 | - 32 CPU Cores 95 | - 64 CPU Cores 96 | - 128 CPU Cores 97 | - 256 CPU Cores 98 | - 512 CPU Cores 99 | - Others (Unkown) 100 | validations: 101 | required: true 102 | 103 | - type: dropdown 104 | id: internet 105 | attributes: 106 | label: Internet Connection 107 | description: What is your Internet connection? 108 | options: 109 | - Optical Fiber (very fast) 110 | - DSL (aDSL, DSL, etc) 111 | - Wifi (WLAN, Wireless) 112 | - LAN (RJ45, Local, etc) 113 | - Satellite (StarLink, etc) 114 | - Mobile (4G, 3G, Edge, etc) 115 | - Offline (No Internet) 116 | - Others (Unkown) 117 | validations: 118 | required: true 119 | 120 | - type: dropdown 121 | id: browser 122 | attributes: 123 | label: Web browser 124 | description: What is your web browser? 125 | options: 126 | - Chrome/Chromium 127 | - Firefox/Firefox Fork 128 | - Apple Safari 129 | - Microsoft Edge 130 | - KDE (Konqueror, Falkon, etc) 131 | - Others (Unkown) 132 | validations: 133 | required: true 134 | 135 | - type: dropdown 136 | id: antivirus 137 | attributes: 138 | label: AntiVirus 139 | description: Do you use an Anti-Virus? 140 | options: 141 | - "Yes" 142 | - "No" 143 | - Others (Unkown) 144 | validations: 145 | required: true 146 | 147 | - type: dropdown 148 | id: device 149 | attributes: 150 | label: Device 151 | description: What kind of computer is it? 152 | options: 153 | - Desktop PC 154 | - Server PC 155 | - Docker/Qemu (Container) 156 | - VirtualBox/Vagrant (Virtual Machine) 157 | - Embedded/IOT 158 | - Arduino/ESP32 Kit 159 | - SmartTV/SmartDisplay 160 | - Drone/Robot 161 | - ASIC/FPGA/Crypto-mining hardware 162 | - PLC/Industrial/heavy machine 163 | - Point Of Sale/Kiosk/ATM 164 | - Car/Self-Driving/On-Board Computer 165 | - Electric scooter/Electric bike 166 | - Satellite/MicroSatellite 167 | - Military machine 168 | - Others (Unkown) 169 | validations: 170 | required: true 171 | 172 | - type: dropdown 173 | id: country 174 | attributes: 175 | label: Where are you from? 176 | options: 177 | - Afghanistan 178 | - Albania 179 | - Algeria 180 | - Andorra 181 | - Angola 182 | - Antigua 183 | - Argentina 184 | - Armenia 185 | - Australia 186 | - Austria 187 | - Azerbaijan 188 | - Bahamas 189 | - Bahrain 190 | - Bangladesh 191 | - Barbados 192 | - Belarus 193 | - Belgium 194 | - Belize 195 | - Benin 196 | - Bhutan 197 | - Bolivia 198 | - Bosnia Herzegovina 199 | - Botswana 200 | - Brazil 201 | - Brunei 202 | - Bulgaria 203 | - Burkina 204 | - Burundi 205 | - Cambodia 206 | - Cameroon 207 | - Canada 208 | - Cape Verde 209 | - Central African Republic 210 | - Chad 211 | - Chile 212 | - China 213 | - Colombia 214 | - Comoros 215 | - Congo 216 | - Congo Democratic Republic 217 | - Costa Rica 218 | - Croatia 219 | - Cuba 220 | - Curacao 221 | - Cyprus 222 | - Czech Republic 223 | - Denmark 224 | - Djibouti 225 | - Dominica 226 | - Dominican Republic 227 | - East Timor 228 | - Ecuador 229 | - Egypt 230 | - El Salvador 231 | - Equatorial Guinea 232 | - Eritrea 233 | - Estonia 234 | - Ethiopia 235 | - Fiji 236 | - Finland 237 | - France 238 | - Gabon 239 | - Gambia 240 | - Georgia 241 | - Germany 242 | - Ghana 243 | - Greece 244 | - Grenada 245 | - Guatemala 246 | - Guinea 247 | - Guinea-Bissau 248 | - Guyana 249 | - Haiti 250 | - Honduras 251 | - Hungary 252 | - Iceland 253 | - India 254 | - Indonesia 255 | - Iran 256 | - Iraq 257 | - Ireland 258 | - Israel 259 | - Italy 260 | - Ivory Coast 261 | - Jamaica 262 | - Japan 263 | - Jordan 264 | - Kazakhstan 265 | - Kenya 266 | - Kiribati 267 | - Korea North 268 | - Korea South 269 | - Kosovo 270 | - Kuwait 271 | - Kyrgyzstan 272 | - Laos 273 | - Latvia 274 | - Lebanon 275 | - Lesotho 276 | - Liberia 277 | - Libya 278 | - Liechtenstein 279 | - Lithuania 280 | - Luxembourg 281 | - Macedonia 282 | - Madagascar 283 | - Malawi 284 | - Malaysia 285 | - Maldives 286 | - Mali 287 | - Malvinas Argentinas Islands 288 | - Malta 289 | - Marshall Islands 290 | - Mauritania 291 | - Mauritius 292 | - Mexico 293 | - Micronesia 294 | - Moldova 295 | - Monaco 296 | - Mongolia 297 | - Montenegro 298 | - Morocco 299 | - Mozambique 300 | - Myanmar 301 | - Namibia 302 | - Nauru 303 | - Nepal 304 | - Netherlands 305 | - New Zealand 306 | - Nicaragua 307 | - Niger 308 | - Nigeria 309 | - Norway 310 | - Oman 311 | - Pakistan 312 | - Palau 313 | - Palestine 314 | - Panama 315 | - Papua New Guinea 316 | - Paraguay 317 | - Peru 318 | - Philippines 319 | - Poland 320 | - Portugal 321 | - Qatar 322 | - Romania 323 | - Russia 324 | - Rwanda 325 | - St Kitts 326 | - St Lucia 327 | - Saint Vincent 328 | - Samoa 329 | - San Marino 330 | - Sao Tome Principe 331 | - Saudi Arabia 332 | - Senegal 333 | - Scotland 334 | - Serbia 335 | - Seychelles 336 | - Sierra Leone 337 | - Singapore 338 | - Slovakia 339 | - Slovenia 340 | - Solomon Islands 341 | - Somalia 342 | - South Africa 343 | - South Sudan 344 | - Spain 345 | - Sri Lanka 346 | - Sudan 347 | - Suriname 348 | - Swaziland 349 | - Sweden 350 | - Switzerland 351 | - Syria 352 | - Taiwan 353 | - Tajikistan 354 | - Tanzania 355 | - Thailand 356 | - Togo 357 | - Tonga 358 | - Trinidad Tobago 359 | - Tunisia 360 | - Turkey 361 | - Turkmenistan 362 | - Tuvalu 363 | - Uganda 364 | - Ukraine 365 | - United Arab Emirates 366 | - United Kingdom 367 | - United States 368 | - Uruguay 369 | - Uzbekistan 370 | - Vanuatu 371 | - Vatican City 372 | - Venezuela 373 | - Vietnam 374 | - Yemen 375 | - Zambia 376 | - Zimbabwe 377 | validations: 378 | required: true 379 | 380 | - type: textarea 381 | id: what-happened 382 | attributes: 383 | label: What happened? 384 | description: Use DETAILED DESCRIPTIVE information about the problem 385 | placeholder: Bug reports with full repro code and detailed information will be fixed faster. 386 | validations: 387 | required: true 388 | 389 | - type: textarea 390 | id: logs 391 | attributes: 392 | label: Standard Output Logs 393 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 394 | placeholder: Bug reports with full repro code and detailed information will be fixed faster. 395 | render: shell 396 | 397 | - type: markdown 398 | attributes: 399 | value: | 400 | **Before you open a new bug...** 401 | - 32-Bit is NOT supported. 402 | - Windows older than Windows 10 is NOT supported. 403 | - Mac OSX support is Experimental. 404 | - ARM support is Experimental. 405 | - Alpine Linux support is Experimental. 406 | - Termux support is Experimental. 407 | - Check if Git main branch already have a fix for your problem. 408 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Sponsor this Project 4 | url: https://gist.github.com/juancarlospaco/37da34ed13a609663f55f4466c4dbc3e 5 | about: Toss a coin to your witcher... 6 | -------------------------------------------------------------------------------- /.github/workflows/add-stars.yml: -------------------------------------------------------------------------------- 1 | name: Add Stars 2 | 3 | on: [watch] 4 | 5 | jobs: 6 | addstars: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Add Stars to Readme 11 | run: | 12 | echo -e ":star: [@${{github.actor}}](https://github.com/${{github.actor}} '`date --iso-8601`')\t" >> README.md 13 | 14 | - name: Commit changes 15 | uses: elstudio/actions-js-build/commit@v2 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | PUSH_BRANCH: 'nim' 19 | -------------------------------------------------------------------------------- /.github/workflows/antispamm.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request AntiSpamm 2 | on: [pull_request] 3 | jobs: 4 | automation: 5 | name: Repo Automation 6 | runs-on: ubuntu-latest 7 | if: ${{ !github.event.pull_request.draft && !contains(github.event.head_commit.message, '[skip ci]') }} 8 | steps: 9 | 10 | # AntiSpamm for Pull Requests: Stops single-commit PR automatically, like Hacktoberfests, Bots, Trolls, etc. 11 | - name: Must be >= 3 commits 12 | if: ${{ github.event.pull_request.commits < 3 }} 13 | uses: actions/github-script@v5 14 | with: 15 | script: core.setFailed('AntiSpamm\tMust be >= 3 commits, make more commits to unlock.') 16 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Stale Issues & PRs 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | # workflow_dispatch: 7 | 8 | jobs: 9 | mark_stale: 10 | name: Mark issues and PRs as Stale 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/stale@v3 14 | with: 15 | repo-token: ${{ secrets.GITHUB_TOKEN }} 16 | days-before-pr-stale: 90 17 | days-before-pr-close: 10 18 | days-before-issue-stale: 60 19 | days-before-issue-close: 7 20 | stale-issue-message: > 21 | This issue is Stale because it has been open for 60 days with no activity. 22 | Contribute a fix or comment on the issue, or it will be closed in 7 days. 23 | stale-pr-message: > 24 | This pull request is Stale because it has been open for 90 days with no activity. 25 | Contribute more commits on the pull request, or it will be closed in 10 days. 26 | close-issue-message: > 27 | This issue has been marked as Stale and closed due to inactivity. 28 | close-pr-message: > 29 | This pull request has been marked as Stale and Closed due to inactivity for 100 days. 30 | -------------------------------------------------------------------------------- /.github/workflows/welcome-new-users.yml: -------------------------------------------------------------------------------- 1 | name: Welcome New Users 2 | 3 | on: [pull_request, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/first-interaction@v1 10 | with: 11 | repo-token: ${{ secrets.GITHUB_TOKEN }} 12 | issue-message: | 13 | # Welcome ${{github.actor}} 14 | - **Remember to :star: Star the project on GitHub!.** 15 | - **Congrats for your first issue!, please provide a minimal code example that reproduces the :bug: Bug!.** 16 | Reports with full repro code and descriptive detailed information will be fixed faster. 17 | - Please, keep in mind there is ZERO FUNDING for the project!, we have no sponsors, no company behind, no dev team, 18 | :heart: Send crypto today to speed up development!: 19 |
20 | Bitcoin BTC 21 | 22 | **BEP20 Binance Smart Chain Network BSC** 23 | ``` 24 | 0xb78c4cf63274bb22f83481986157d234105ac17e 25 | ``` 26 | **BTC Bitcoin Network** 27 | ``` 28 | 1Pnf45MgGgY32X4KDNJbutnpx96E4FxqVi 29 | ``` 30 | **Lightning Network** 31 | ``` 32 | juancarlospaco@bitrefill.me 33 | ``` 34 |
35 | 36 |
37 | Ethereum ETH Dai DAI Uniswap UNI Axie Infinity AXS Smooth Love Potion SLP 38 | 39 | **BEP20 Binance Smart Chain Network BSC** 40 | ``` 41 | 0xb78c4cf63274bb22f83481986157d234105ac17e 42 | ``` 43 | **ERC20 Ethereum Network** 44 | ``` 45 | 0xb78c4cf63274bb22f83481986157d234105ac17e 46 | ``` 47 |
48 |
49 | Tether USDT 50 | 51 | **BEP20 Binance Smart Chain Network BSC** 52 | ``` 53 | 0xb78c4cf63274bb22f83481986157d234105ac17e 54 | ``` 55 | **ERC20 Ethereum Network** 56 | ``` 57 | 0xb78c4cf63274bb22f83481986157d234105ac17e 58 | ``` 59 | **TRC20 Tron Network** 60 | ``` 61 | TWGft53WgWvH2mnqR8ZUXq1GD8M4gZ4Yfu 62 | ``` 63 |
64 |
65 | Solana SOL 66 | 67 | **BEP20 Binance Smart Chain Network BSC** 68 | ``` 69 | 0xb78c4cf63274bb22f83481986157d234105ac17e 70 | ``` 71 | **SOL Solana Network** 72 | ``` 73 | FKaPSd8kTUpH7Q76d77toy1jjPGpZSxR4xbhQHyCMSGq 74 | ``` 75 |
76 |
77 | Cardano ADA 78 | 79 | **BEP20 Binance Smart Chain Network BSC** 80 | ``` 81 | 0xb78c4cf63274bb22f83481986157d234105ac17e 82 | ``` 83 | **ADA Cardano Network** 84 | ``` 85 | DdzFFzCqrht9Y1r4Yx7ouqG9yJNWeXFt69xavLdaeXdu4cQi2yXgNWagzh52o9k9YRh3ussHnBnDrg7v7W2hSXWXfBhbo2ooUKRFMieM 86 | ``` 87 |
88 |
89 | Sandbox SAND Decentraland MANA 90 | 91 | **ERC20 Ethereum Network** 92 | ``` 93 | 0xb78c4cf63274bb22f83481986157d234105ac17e 94 | ``` 95 |
96 |
97 | Algorand ALGO 98 | 99 | **ALGO Algorand Network** 100 | ``` 101 | WM54DHVZQIQDVTHMPOH6FEZ4U2AU3OBPGAFTHSCYWMFE7ETKCUUOYAW24Q 102 | ``` 103 |
104 |
105 | Binance 106 | 107 | [https://pay.binance.com/en/checkout/e92e536210fd4f62b426ea7ee65b49c3](https://pay.binance.com/en/checkout/e92e536210fd4f62b426ea7ee65b49c3 "Send via Binance Pay") 108 |
109 | 110 | pr-message: | 111 | # Welcome ${{github.actor}} 112 | - **Remember to :star: Star the project on GitHub!.** 113 | - **Congrats for your first Pull Request!, we will review your contributions very soon, and likely merge it!.** 114 | Pull Requests with detailed description of the changes and documentation on the code will be merged faster. 115 | - Please, keep in mind there is ZERO FUNDING for the project!, we have no sponsors, no company behind, no dev team, 116 | :heart: Send crypto today to speed up development!: 117 |
118 | Bitcoin BTC 119 | 120 | **BEP20 Binance Smart Chain Network BSC** 121 | ``` 122 | 0xb78c4cf63274bb22f83481986157d234105ac17e 123 | ``` 124 | **BTC Bitcoin Network** 125 | ``` 126 | 1Pnf45MgGgY32X4KDNJbutnpx96E4FxqVi 127 | ``` 128 | **Lightning Network** 129 | ``` 130 | juancarlospaco@bitrefill.me 131 | ``` 132 |
133 | 134 |
135 | Ethereum ETH Dai DAI Uniswap UNI Axie Infinity AXS Smooth Love Potion SLP 136 | 137 | **BEP20 Binance Smart Chain Network BSC** 138 | ``` 139 | 0xb78c4cf63274bb22f83481986157d234105ac17e 140 | ``` 141 | **ERC20 Ethereum Network** 142 | ``` 143 | 0xb78c4cf63274bb22f83481986157d234105ac17e 144 | ``` 145 |
146 |
147 | Tether USDT 148 | 149 | **BEP20 Binance Smart Chain Network BSC** 150 | ``` 151 | 0xb78c4cf63274bb22f83481986157d234105ac17e 152 | ``` 153 | **ERC20 Ethereum Network** 154 | ``` 155 | 0xb78c4cf63274bb22f83481986157d234105ac17e 156 | ``` 157 | **TRC20 Tron Network** 158 | ``` 159 | TWGft53WgWvH2mnqR8ZUXq1GD8M4gZ4Yfu 160 | ``` 161 |
162 |
163 | Solana SOL 164 | 165 | **BEP20 Binance Smart Chain Network BSC** 166 | ``` 167 | 0xb78c4cf63274bb22f83481986157d234105ac17e 168 | ``` 169 | **SOL Solana Network** 170 | ``` 171 | FKaPSd8kTUpH7Q76d77toy1jjPGpZSxR4xbhQHyCMSGq 172 | ``` 173 |
174 |
175 | Cardano ADA 176 | 177 | **BEP20 Binance Smart Chain Network BSC** 178 | ``` 179 | 0xb78c4cf63274bb22f83481986157d234105ac17e 180 | ``` 181 | **ADA Cardano Network** 182 | ``` 183 | DdzFFzCqrht9Y1r4Yx7ouqG9yJNWeXFt69xavLdaeXdu4cQi2yXgNWagzh52o9k9YRh3ussHnBnDrg7v7W2hSXWXfBhbo2ooUKRFMieM 184 | ``` 185 |
186 |
187 | Sandbox SAND Decentraland MANA 188 | 189 | **ERC20 Ethereum Network** 190 | ``` 191 | 0xb78c4cf63274bb22f83481986157d234105ac17e 192 | ``` 193 |
194 |
195 | Algorand ALGO 196 | 197 | **ALGO Algorand Network** 198 | ``` 199 | WM54DHVZQIQDVTHMPOH6FEZ4U2AU3OBPGAFTHSCYWMFE7ETKCUUOYAW24Q 200 | ``` 201 |
202 |
203 | Binance 204 | 205 | [https://pay.binance.com/en/checkout/e92e536210fd4f62b426ea7ee65b49c3](https://pay.binance.com/en/checkout/e92e536210fd4f62b426ea7ee65b49c3 "Send via Binance Pay") 206 |
207 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | nimcache/ 2 | src/nimterlingua 3 | src/*.cfg 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Juan Carlos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nimterlingua 2 | 3 | - Internationalization and localization at Compile Time for Nim. 4 | - 1 Macro to replace strings in-place at compile time with 0 cost at runtime. 5 | - Translate unmodified code from 1 INI file. Replace Emojis and Unicode in-place. 6 | - High performance with low resources, everything is done compile-time only!. 7 | 8 | 9 | # Use 10 | 11 | **translations.cfg:** 12 | ```ini 13 | # This is a comment. 14 | [cat] 15 | ES_AR = gato 16 | PT_BR = minino 17 | 18 | 19 | 20 | [dog] 21 | ES_AR = perro 22 | PT_BR = cão 23 | 24 | ; You can replace Emojis. This is a comment. 25 | [:crown:] 26 | ES_AR = 👑 27 | PT_BR = 👑 28 | 29 | 30 | ``` 31 | 32 | **Nim:** 33 | 34 | ```nim 35 | import nimterlingua 36 | 37 | nimterlingua() 38 | echo "cat" 39 | echo "dog" 40 | echo ":crown:" 41 | ``` 42 | 43 | **Compile:** 44 | ``` 45 | nim c -r -d:ES_AR -d:iniFile="translations.cfg" yourfile.nim 46 | ``` 47 | 48 | or 49 | 50 | ``` 51 | nim c -r -d:PT_BR -d:iniFile="translations.cfg" yourfile.nim 52 | ``` 53 | 54 | 55 | **NimScript:** 56 | 57 | ```nim 58 | import nimterlingua 59 | 60 | nimterlingua() 61 | echo "cat" 62 | echo "dog" 63 | echo ":crown:" 64 | ``` 65 | 66 | 67 | **Run:** 68 | ``` 69 | nim e -d:ES_AR -d:iniFile="translations.cfg" yourfile.nims 70 | ``` 71 | 72 | or 73 | 74 | ``` 75 | nim e -d:PT_BR -d:iniFile="translations.cfg" yourfile.nims 76 | ``` 77 | 78 | 79 | **NodeJS:** 80 | 81 | ```nim 82 | import nimterlingua 83 | 84 | nimterlingua() 85 | echo "cat" 86 | echo "dog" 87 | echo ":crown:" 88 | ``` 89 | 90 | **Compile:** 91 | ``` 92 | nim js -d:nodejs -d:ES_AR -d:iniFile="translations.cfg" yourfile.nim 93 | ``` 94 | 95 | or 96 | 97 | ``` 98 | nim js -d:nodejs -d:PT_BR -d:iniFile="translations.cfg" yourfile.nim 99 | ``` 100 | 101 | 102 | # Example 103 | 104 | ```nim 105 | $ cd example 106 | $ nim c -r -d:ES_AR -d:iniFile="translations.cfg" bohemian_rhapsody.nim 107 | 108 | bohemian_rhapsody.nim(5, 11) Hint: ES_AR0("Is this the real life?") --> '"Es la vida real?"' [Pattern] 109 | bohemian_rhapsody.nim(6, 11) Hint: ES_AR1("Is this just fantasy?") --> '"Es sólo fantasía?"' [Pattern] 110 | bohemian_rhapsody.nim(7, 11) Hint: ES_AR2("Caught in a landslide") --> '"Atrapado en un derrumbe"' [Pattern] 111 | bohemian_rhapsody.nim(13, 9) Hint: ES_AR3("No escape from reality") --> '"Sin escape de la realidad"' [Pattern] 112 | bohemian_rhapsody.nim(14, 9) Hint: ES_AR4("Open your eyes") --> '"Abre tus ojos"' [Pattern] 113 | bohemian_rhapsody.nim(15, 11) Hint: ES_AR5("Look up to the skies and see") --> '"Mira a los cielos y observa"' [Pattern] 114 | bohemian_rhapsody.nim(21, 7) Hint: ES_AR6("I\'m just a poor boy, I need no sympathy") --> '"Sólo soy un chico pobre, no necesito simpatía"' [Pattern] 115 | bohemian_rhapsody.nim(22, 7) Hint: ES_AR7("Because I\'m easy come, easy go") --> '"Porque fácil vengo, fácil me voy"' [Pattern] 116 | bohemian_rhapsody.nim(23, 7) Hint: ES_AR8("A little high, little low") --> '"Un poco alto, un poco bajo"' [Pattern] 117 | bohemian_rhapsody.nim(28, 6) Hint: ES_AR9("Anyway the wind blows, doesn\'t really matter to me, to me") --> '"De todos modos el viento sopla, realmente no me importa, a mi"' [Pattern] 118 | bohemian_rhapsody.nim(29, 11) Hint: ES_AR10("Mama, just killed a man") --> '"Mamá, maté a un hombre"' [Pattern] 119 | bohemian_rhapsody.nim(32, 3) Hint: ES_AR11("Put a gun against his head") --> '"Puse una pistola en su cabeza"' [Pattern] 120 | bohemian_rhapsody.nim(36, 3) Hint: ES_AR12("Pulled my trigger, now he\'s dead") --> '"Jalé el gatillo, ya está muerto"' [Pattern] 121 | bohemian_rhapsody.nim(42, 9) Hint: ES_AR15("Mama, ooo, Didn\'t mean to make you cry") --> '"Mamá, ooo, No quise hacerte llorar"' [Pattern] 122 | bohemian_rhapsody.nim(44, 6) Hint: ES_AR16("If I\'m not back again this time tomorrow") --> '"Si no regreso mañana a esta hora"' [Pattern] 123 | bohemian_rhapsody.nim(45, 6) Hint: ES_AR17("Carry on, carry on, as if nothing really matters") --> '"Continúa, continúa, como si nada realmente importara"' [Pattern] 124 | 125 | 126 | Es la vida real? 127 | Es sólo fantasía? 128 | Atrapado en un derrumbe 129 | Sin escape de la realidad 130 | Abre tus ojos 131 | Mira a los cielos y observa 132 | Sólo soy un chico pobre, no necesito simpatía 133 | Porque fácil vengo, fácil me voy 134 | Un poco alto, un poco bajo 135 | De todos modos el viento sopla, realmente no me importa, a mi 136 | Mamá, maté a un hombre 137 | Puse una pistola en su cabeza 138 | Jalé el gatillo, ya está muerto 139 | Si no regreso mañana a esta hora 140 | Continúa, continúa, como si nada realmente importara 141 | 142 | ``` 143 | 144 | 145 | ### under the hood 146 | 147 |
148 | How does it works internally?. 149 | 150 | ```nim 151 | # expandMacros: 152 | 153 | when defined(ES_AR): 154 | template ES_AR0{("cat"){texts}}(texts: string{lit, noalias}): string = 155 | ## Compile with -d:ES_AR to auto translate at compile time to ES_AR Lang ISO code. 156 | when texts == "cat": "gato" else: "cat" 157 | 158 | when defined(PT_BR): 159 | template PT_BR1{("cat"){texts}}(texts: string{lit, noalias}): string = 160 | ## Compile with -d:PT_BR to auto translate at compile time to PT_BR Lang ISO code. 161 | when texts == "cat": "minino" else: "cat" 162 | 163 | ``` 164 | 165 |
166 | 167 | 168 | # Nimterlingua Vs GetText 169 | 170 | | Nimterlingua | GetText | 171 | |--------------------------------------|---------------------------------------| 172 | | No `*.po` files | You need to write `*.po` files | 173 | | No `*.pot` files | You need to extract `*.pot` files | 174 | | No `*.mo` files | You need to compile `*.mo` files | 175 | | No `*.gmo` files | You need to compile `*.gmo` files | 176 | | Only `nim` | `xgettext`, `msginit`, `msgfmt`, etc | 177 | | Any editor, `*.INI` format | Requires `poedit` for fluent workflow | 178 | | Unmodified code can be translated | Requires refactor adding gettext functions | 179 | | `"cat"` | `gettext("cat")` or `_("cat")` | 180 | | No GetText dependency | GetText libs as dependency | 181 | | 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) | 182 | | `*.INI` is easy to delegate to people | `*.po` format complex for non-tech people | 183 | | Chill Lazy Dev | Time consuming beyond translation itself | 184 | 185 | **GetText** 186 | ```pot 187 | #. TRANSLATORS: Thank you for contributing to this project. 188 | #: src/name.c:36 189 | msgid "cat" 190 | msgstr "gato" 191 | 192 | ``` 193 | 194 | **Nimterlingua** 195 | ```ini 196 | [cat] 197 | ES_AR = gato 198 | ``` 199 | 200 | # Beyond Translation 201 | 202 | Its designed for translation, but it does not force anything on you, 203 | you can be creative and explore other possible uses. 204 | 205 | It replaces in-place any arbitrary `string` with any arbitrary `string` you want at compile time with 0 cost at runtime without touching the code. 206 | 207 | _Let us know if you built something cool with it!._ 208 | 209 | 210 | # FAQ 211 | 212 | - Its not possible to have different languages in 1 Nim program?. 213 | 214 | Use a period (dot), exclamation, space, emoji or something, the string will not match anymore. 215 | 216 | ```ini 217 | [cat] 218 | ES_AR = gato 219 | ``` 220 | 221 | ```nim 222 | if useSpanish: "cat" else: "cat." 223 | ``` 224 | 225 | `"cat"` get translated to Spanish, `"cat."` remains English, because of period. 226 | 227 | You choose languages with `if` or `case` or similar on your code. 228 | 229 | Or use NimScript or NodeJS to get a JSON or CSV or similar format and get the data from there. 230 | 231 | 232 | - I get `nimterlingua.nim(17, 29) Error: cannot open file: translations.cfg` ? 233 | 234 | compile with `-d:iniFile="path to your translations.cfg"` 235 | 236 | - Is there a Minimal Basic example?. 237 | 238 | https://github.com/juancarlospaco/nim-nimterlingua/blob/master/example/minimal.nims 239 | 240 | - How do you use this with Python or NodeJS or JavaScript?. 241 | 242 | https://github.com/juancarlospaco/nim-nimterlingua/blob/master/example/minimal.nims 243 | 244 | - This works with NodeJS and JavaScript?. 245 | 246 | Yes. 247 | 248 | - My Translated text contains `=` will make it fail?. 249 | 250 | Use `splitter=":"`, then use it as splitter separator. 251 | 252 | ```ini 253 | [cat] 254 | ES_AR : gato 255 | ``` 256 | 257 | - How to make an INI for a lot of languages?. 258 | 259 | ```ini 260 | [cat] 261 | ES_AR = gato 262 | PT_BR = minino 263 | RU = kot 264 | FR = chat 265 | # A lot of languages here... 266 | ``` 267 | 268 | - This is not the same as Search&Replace of any Editor?. 269 | 270 | No. 271 | Because it actually fully understands the code, 272 | typical Search&Replace of Editor can break comments, names, variables, etc. 273 | 274 | 275 | # Stars 276 | 277 | ![](https://starchart.cc/juancarlospaco/nim-nimterlingua.svg) 278 | -------------------------------------------------------------------------------- /example/bohemian_rhapsody.nim: -------------------------------------------------------------------------------- 1 | import nimterlingua 2 | 3 | nimterlingua() 4 | 5 | var foo = "Is this the real life?" 6 | var bar = "Is this just fantasy?" 7 | var baz = "Caught in a landslide" 8 | echo foo 9 | echo bar 10 | echo baz 11 | 12 | let 13 | one = "No escape from reality" 14 | two = "Open your eyes" 15 | three = "Look up to the skies and see" 16 | echo one 17 | echo two 18 | echo three 19 | 20 | var 21 | a = "I'm just a poor boy, I need no sympathy" 22 | b = "Because I'm easy come, easy go" 23 | c = "A little high, little low" 24 | echo a 25 | echo b 26 | echo c 27 | 28 | echo "Anyway the wind blows, doesn't really matter to me, to me" 29 | debugEcho "Mama, just killed a man" 30 | 31 | proc zzz(): string = 32 | "Put a gun against his head" 33 | echo zzz() 34 | 35 | func xxx(): string = 36 | "Pulled my trigger, now he's dead" 37 | echo xxx() 38 | 39 | assert "Mama, life had just begun".len > 0 40 | doAssert "But now I've gone and thrown it all away".len > 0 41 | 42 | discard "Mama, ooo, Didn't mean to make you cry" 43 | 44 | echo "If I'm not back again this time tomorrow" 45 | echo "Carry on, carry on, as if nothing really matters" 46 | -------------------------------------------------------------------------------- /example/bohemian_rhapsody.nim.cfg: -------------------------------------------------------------------------------- 1 | -d:ES_AR 2 | -------------------------------------------------------------------------------- /example/minimal.nims: -------------------------------------------------------------------------------- 1 | import nimterlingua 2 | nimterlingua() 3 | ### $ nim e -d:ES_AR minimal.nims 4 | ### $ nim e -d:ES_AR minimal.nims > python_translated.py 5 | ### $ nim e -d:ES_AR minimal.nims > javascript_translated.js 6 | echo [ 7 | "Is this the real life?", 8 | "Is this just fantasy?", 9 | "Caught in a landslide", 10 | "No escape from reality", 11 | "Open your eyes", 12 | "Look up to the skies and see", 13 | "I'm just a poor boy, I need no sympathy", 14 | "Because I'm easy come, easy go", 15 | "A little high, little low", 16 | "Anyway the wind blows, doesn't really matter to me, to me", 17 | "Mama, just killed a man", 18 | "Put a gun against his head", 19 | "Pulled my trigger, now he's dead", 20 | "Mama, life had just begun", 21 | "But now I've gone and thrown it all away", 22 | """Mama, ooo, Didn't mean to make you cry""", # This is a test Comment. 23 | """If I'm not back again this time tomorrow""", # Triple Quoted Strings. 24 | """Carry on, carry on, as if nothing really matters""", 25 | ] 26 | -------------------------------------------------------------------------------- /example/translations.cfg: -------------------------------------------------------------------------------- 1 | # Bohemian Rhapsody (Spanish translation). 2 | 3 | 4 | [Is this the real life?] 5 | ES_AR = Es la vida real? 6 | 7 | [Is this just fantasy?] 8 | ES_AR = Es sólo fantasía? 9 | 10 | [Caught in a landslide] 11 | ES_AR = Atrapado en un derrumbe 12 | [No escape from reality] 13 | ES_AR = Sin escape de la realidad 14 | [Open your eyes] 15 | ES_AR = Abre tus ojos 16 | [Look up to the skies and see] 17 | ES_AR = Mira a los cielos y observa 18 | [I'm just a poor boy, I need no sympathy] 19 | ES_AR = Sólo soy un chico pobre, no necesito simpatía 20 | [Because I'm easy come, easy go] 21 | ES_AR = Porque fácil vengo, fácil me voy 22 | [A little high, little low] 23 | ES_AR = Un poco alto, un poco bajo 24 | [Anyway the wind blows, doesn't really matter to me, to me] 25 | ES_AR = De todos modos el viento sopla, realmente no me importa, a mi 26 | 27 | 28 | 29 | 30 | [Mama, just killed a man] 31 | ES_AR = Mamá, maté a un hombre 32 | [Put a gun against his head] 33 | ES_AR = Puse una pistola en su cabeza 34 | [Pulled my trigger, now he's dead] 35 | ES_AR = Jalé el gatillo, ya está muerto 36 | [Mama, life had just begun] 37 | ES_AR = Mamá, la vida apenas empezaba 38 | [But now I've gone and thrown it all away] 39 | ES_AR = Pero ahora me he ido y lo tiré todo 40 | [Mama, ooo, Didn't mean to make you cry] 41 | ES_AR = Mamá, ooo, No quise hacerte llorar 42 | [If I'm not back again this time tomorrow] 43 | ES_AR = Si no regreso mañana a esta hora 44 | [Carry on, carry on, as if nothing really matters] 45 | ES_AR = Continúa, continúa, como si nada realmente importara 46 | -------------------------------------------------------------------------------- /nimterlingua.nimble: -------------------------------------------------------------------------------- 1 | version = "0.1.0" 2 | author = "Juan Carlos" 3 | description = "Internationalization at Compile Time for Nim. Macro to translate unmodified code from 1 INI file. NimScript compatible." 4 | license = "MIT" 5 | srcDir = "src" 6 | skipDirs = @["example"] 7 | 8 | requires "nim >= 1.0.0" 9 | -------------------------------------------------------------------------------- /src/nimterlingua.nim: -------------------------------------------------------------------------------- 1 | import std/macros 2 | 3 | from std/strutils import strip, splitLines, split, format, toUpperAscii 4 | 5 | 6 | const tI18i = """ 7 | when defined($1): 8 | template $1$4{("$3"){texts}}(texts: string{lit, noalias}): string = 9 | ## Compile with -d:$1 to auto translate at compile time to $1 Lang ISO code. 10 | when texts == "$3": "$2" else: "$3" 11 | 12 | """ 13 | 14 | const rI18i {.used.} = """ 15 | template $1$4{("$3"){texts}}(texts: string{lit, noalias}): untyped = 16 | func $1$4: string = "$3" 17 | 18 | """ 19 | 20 | 21 | macro nimterlingua*(splitter = "=") = 22 | ## Macro to replace strings in-place at compile time with 0 cost at runtime. 23 | const iniFile {.strdefine.} = "translations.cfg" 24 | assert iniFile.len > 5, "iniFile must not be empty string (INI or CFG)" 25 | var i: int 26 | var source, section: string 27 | for line in iniFile.staticRead.strip.splitLines: 28 | if unlikely(line.strip.len == 0 or line.strip[0] in {'#', ';'}): continue 29 | if line.strip[0] == '[' and line.strip[line.strip.len-1] == ']': 30 | section = line.strip[1..line.strip.len - 2].strip # [SomeWord] 31 | else: 32 | var l = line.split(splitter.strVal) # LANG_ISOCODE = SomeWord Translated 33 | if l.len != 2: error("Invalid INI format, value splitter not found.") 34 | source &= tI18i.format(l[0].strip.toUpperAscii, l[1].strip, section, i) 35 | inc i 36 | if source.len == 0: error("Invalid INI format or parse error or unkown error") 37 | # when not defined(release): echo source 38 | result = parseStmt(source) 39 | 40 | 41 | when isMainModule: 42 | nimterlingua(splitter = "=") 43 | echo "cat" 44 | echo "dog" 45 | echo ":crown:" 46 | -------------------------------------------------------------------------------- /src/translations.cfg: -------------------------------------------------------------------------------- 1 | # Bohemian Rhapsody (Spanish translation). 2 | 3 | 4 | [Is this the real life?] 5 | ES_AR = Es la vida real? 6 | 7 | [Is this just fantasy?] 8 | ES_AR = Es sólo fantasía? 9 | 10 | [Caught in a landslide] 11 | ES_AR = Atrapado en un derrumbe 12 | [No escape from reality] 13 | ES_AR = Sin escape de la realidad 14 | [Open your eyes] 15 | ES_AR = Abre tus ojos 16 | [Look up to the skies and see] 17 | ES_AR = Mira a los cielos y observa 18 | [I'm just a poor boy, I need no sympathy] 19 | ES_AR = Sólo soy un chico pobre, no necesito simpatía 20 | [Because I'm easy come, easy go] 21 | ES_AR = Porque fácil vengo, fácil me voy 22 | [A little high, little low] 23 | ES_AR = Un poco alto, un poco bajo 24 | [Anyway the wind blows, doesn't really matter to me, to me] 25 | ES_AR = De todos modos el viento sopla, realmente no me importa, a mi 26 | 27 | 28 | 29 | 30 | [Mama, just killed a man] 31 | ES_AR = Mamá, maté a un hombre 32 | [Put a gun against his head] 33 | ES_AR = Puse una pistola en su cabeza 34 | [Pulled my trigger, now he's dead] 35 | ES_AR = Jalé el gatillo, ya está muerto 36 | [Mama, life had just begun] 37 | ES_AR = Mamá, la vida apenas empezaba 38 | [But now I've gone and thrown it all away] 39 | ES_AR = Pero ahora me he ido y lo tiré todo 40 | [Mama, ooo, Didn't mean to make you cry] 41 | ES_AR = Mamá, ooo, No quise hacerte llorar 42 | [If I'm not back again this time tomorrow] 43 | ES_AR = Si no regreso mañana a esta hora 44 | [Carry on, carry on, as if nothing really matters] 45 | ES_AR = Continúa, continúa, como si nada realmente importara 46 | --------------------------------------------------------------------------------