{"id":15675152,"url":"https://github.com/aduth/tannin","last_synced_at":"2025-04-11T14:44:25.663Z","repository":{"id":33231298,"uuid":"156158913","full_name":"aduth/tannin","owner":"aduth","description":"gettext localization library compatible with Jed-formatted locale data","archived":false,"fork":false,"pushed_at":"2024-06-22T19:12:53.000Z","size":1723,"stargazers_count":13,"open_issues_count":4,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-13T22:35:06.904Z","etag":null,"topics":["gettext","i18n","internationalization","l10n","localization"],"latest_commit_sha":null,"homepage":null,"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/aduth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-05T04:04:54.000Z","updated_at":"2024-06-22T19:12:57.000Z","dependencies_parsed_at":"2024-06-18T16:55:02.739Z","dependency_job_id":"eb08607a-dc7e-4ac1-9326-2fa9309f9fce","html_url":"https://github.com/aduth/tannin","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Ftannin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Ftannin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Ftannin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Ftannin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aduth","download_url":"https://codeload.github.com/aduth/tannin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248420742,"owners_count":21100457,"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":["gettext","i18n","internationalization","l10n","localization"],"created_at":"2024-10-03T15:57:17.925Z","updated_at":"2025-04-11T14:44:25.637Z","avatar_url":"https://github.com/aduth.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tannin\n\nTannin is a [gettext](https://www.gnu.org/software/gettext/) localization library.\n\nInspired by [Jed](https://github.com/messageformat/Jed), it is built to be largely compatible with Jed-formatted locale data, and even offers a [Jed drop-in replacement compatibility shim](#jed-compatibility) to easily convert an existing project. Contrasted with Jed, it is more heavily optimized for performance and bundle size. While Jed works well with one-off translations, it suffers in single-page applications with repeated rendering of elements. Using Tannin, you can expect a bundle size **20% that of Jed** (**984 bytes gzipped**) and upwards of **330x better performance** ([see benchmarks](#benchmarks)). It does so without sacrificing the safety of plural forms evaluation, using a hand-crafted expression parser in place of the verbose compiled grammar included in Jed.\n\nFurthermore, the project is architected as a mono-repo, published on npm under the `@tannin` scope. These modules can be used standalone, with or without Tannin. For example, you may find value in [`@tannin/compile`](https://www.npmjs.com/package/@tannin/compile) for creating an expression evaluator, or [`@tannin/sprintf`](https://www.npmjs.com/package/@tannin/sprintf) as a minimal [printf](https://en.wikipedia.org/wiki/Printf_format_string) string formatter.\n\nThe following modules are available:\n\n- [`tannin`](https://www.npmjs.com/package/tannin)\n- [`@tannin/compat`](https://www.npmjs.com/package/@tannin/compat)\n- [`@tannin/compile`](https://www.npmjs.com/package/@tannin/compile)\n- [`@tannin/evaluate`](https://www.npmjs.com/package/@tannin/evaluate)\n- [`@tannin/plural-forms`](https://www.npmjs.com/package/@tannin/plural-forms)\n- [`@tannin/postfix`](https://www.npmjs.com/package/@tannin/postfix)\n- [`@tannin/sprintf`](https://www.npmjs.com/package/@tannin/sprintf)\n\n## Installation\n\nUsing [npm](https://www.npmjs.com/) as a package manager:\n\n```\nnpm install tannin\n```\n\nOtherwise, download a pre-built copy from unpkg:\n\n[https://unpkg.com/tannin/dist/tannin.min.js](https://unpkg.com/tannin/dist/tannin.min.js)\n\n## Usage\n\nConstruct a new instance of `Tannin`, passing locale data in the form of a [Jed-formatted JSON object](http://messageformat.github.io/Jed/).\n\nThe returned `Tannin` instance includes the fully-qualified `dcnpgettext` function to retrieve a translated string.\n\n```js\nimport Tannin from 'tannin';\n\nconst i18n = new Tannin({\n\tthe_domain: {\n\t\t'': {\n\t\t\tdomain: 'the_domain',\n\t\t\tlang: 'en',\n\t\t\tplural_forms: 'nplurals=2; plural=(n != 1);',\n\t\t},\n\t\texample: ['singular translation', 'plural translation'],\n\t},\n});\n\ni18n.dcnpgettext('the_domain', undefined, 'example');\n// ⇒ 'singular translation'\n```\n\nTannin accepts `plural_forms` both as a standard [gettext plural forms string](https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html) or as a function which, given a number, should return the (zero-based) plural form index. Providing `plural_forms` as a function can yield a performance gain of approximately 8x for plural evaluation.\n\nFor example, consider the following \"default\" English (untranslated) initialization:\n\n```js\nconst i18n = new Tannin({\n\tmessages: {\n\t\t'': {\n\t\t\tdomain: 'messages',\n\t\t\tplural_forms: (n) =\u003e (n === 1 ? 0 : 1),\n\t\t},\n\t},\n});\n\ni18n.dcnpgettext('messages', undefined, 'example', 'examples', 1);\n// ⇒ 'example'\n\ni18n.dcnpgettext('messages', undefined, 'example', 'examples', 2);\n// ⇒ 'examples'\n```\n\n## Jed Compatibility\n\nFor a more human-friendly API, or to more easily transition an existing project, consider using [`@tannin/compat`](https://www.npmjs.com/package/@tannin/compat) as a drop-in replacement for Jed.\n\n```js\nimport Jed from '@tannin/compat';\n\nconst i18n = new Jed({\n\tlocale_data: {\n\t\tthe_domain: {\n\t\t\t'': {\n\t\t\t\tdomain: 'the_domain',\n\t\t\t\tlang: 'en',\n\t\t\t\tplural_forms: 'nplurals=2; plural=(n != 1);',\n\t\t\t},\n\t\t\texample: ['singular translation', 'plural translation'],\n\t\t},\n\t},\n\tdomain: 'the_domain',\n});\n\ni18n.translate('example').fetch();\n// ⇒ 'singular translation'\n```\n\n## Benchmarks\n\nThe following benchmarks are performed in Node 10.16.0 on a MacBook Pro (2019), 2.4 GHz 8-Core Intel Core i9, 32 GB 2400 MHz DDR4 RAM.\n\n```\nSingular\n---\nTannin x 216,670,213 ops/sec ±0.73% (90 runs sampled)\nTannin (Optimized Default) x 219,477,869 ops/sec ±0.32% (96 runs sampled)\nJed x 58,730,499 ops/sec ±0.34% (96 runs sampled)\n\n\nSingular (Untranslated)\n---\nTannin x 75,835,743 ops/sec ±1.26% (96 runs sampled)\nTannin (Optimized Default) x 76,474,169 ops/sec ±0.61% (92 runs sampled)\nJed x 241,632 ops/sec ±0.73% (96 runs sampled)\n\n\nPlural\n---\nTannin x 7,108,006 ops/sec ±0.96% (95 runs sampled)\nTannin (Optimized Default) x 51,658,190 ops/sec ±1.25% (94 runs sampled)\nJed x 236,797 ops/sec ±0.98% (97 runs sampled)\n```\n\nTo run benchmarks on your own machine:\n\n```\ngit clone https://github.com/aduth/tannin.git\ncd tannin\nnpm install\nnode packages/tannin/benchmark\n```\n\n## License\n\nCopyright 2019-2024 Andrew Duthie\n\nReleased under the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduth%2Ftannin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faduth%2Ftannin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduth%2Ftannin/lists"}