From be3f7b50fb1e5e23c9fd940562ea8e9dc1abf0db Mon Sep 17 00:00:00 2001 From: Christian Kaisermann Date: Tue, 14 Aug 2018 15:21:06 -0300 Subject: [PATCH] Add simple pluralization --- README.md | 72 +++++++++++++++++++++++++++++++++++++++++----- package-lock.json | 30 +++++++++++++------ package.json | 2 +- src/index.d.ts | 0 src/index.js | 17 +++++++++-- test/index.test.js | 7 ++++- 6 files changed, 108 insertions(+), 20 deletions(-) delete mode 100644 src/index.d.ts diff --git a/README.md b/README.md index e3e6840..fcc2446 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # svelte-i18n -> Internationalization for svelte - -**Work-in-progress** +> Internationalization for Svelte ## Usage @@ -13,10 +11,16 @@ import i18n from 'svelte-i18n' import { Store } from 'svelte/store' /** i18n(svelteStore, { dictionary }) */ -const store = i18n(new Store(), { +let store = new Store() + +store = i18n(store, { dictionary: { 'pt-BR': { message: 'Mensagem', + greeting: 'Olá {name}, como vai?', + greetingIndex: 'Olá {0}, como vai?', + meter: 'metros | metro | metros', + book: 'livro | livros', messages: { alert: 'Alerta', error: 'Erro', @@ -24,6 +28,10 @@ const store = i18n(new Store(), { }, 'en-US': { message: 'Message', + greeting: 'Hello {name}, how are you?', + greetingIndex: 'Hello {0}, how are you?', + meter: 'meters | meter | meters', + book: 'book | books', messages: { alert: 'Alert', error: 'Error', @@ -57,14 +65,64 @@ store.i18n.setLocale('en-US') ### On `templates` +#### Basic usage + ```html
- {$_('message')}: {$_.upper('messages.success'))} + {$_('message')}: {$_('messages.success'))} +
``` -Renders: +#### Interpolation ```html -Message: SUCCESS +
+ + {$_('greeting', { name: 'John' }))} + + + + {$_('greetingIndex', ['John']))} + +
``` + +#### Pluralization + +```html +
+ 0 {$_.plural('meter', 0))} + + + 1 {$_.plural('meter', 1))} + + + 100 {$_.plural('meter', 100))} + + + 0 {$_.plural('book', 0))} + + + 10 {$_.plural('book', 10))} + +
+``` + +#### Utilities + +```html +
+ {$_.upper('message'))} + + + {$_.lower('message'))} + + + {$_.capital('message'))} + + + {$_.title('greeting', { name: 'John' }))} + +
+``` \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4c56166..17e9eaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte-i18n", - "version": "0.0.1", + "version": "0.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3401,12 +3401,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3421,17 +3423,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3548,7 +3553,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3560,6 +3566,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3574,6 +3581,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3581,12 +3589,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3605,6 +3615,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3685,7 +3696,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3697,6 +3709,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3818,6 +3831,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/package.json b/package.json index 836179a..73bb4e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte-i18n", - "version": "0.0.3", + "version": "0.0.4", "license": "MIT", "main": "dist/i18n.js", "module": "dist/i18n.m.js", diff --git a/src/index.d.ts b/src/index.d.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/index.js b/src/index.js index f9af24d..f0ebeb8 100644 --- a/src/index.js +++ b/src/index.js @@ -49,9 +49,20 @@ export function i18n(store, { dictionary: initialDictionary }) { plural(path, counter, interpolations, locale) { return getLocalizedMessage(path, interpolations, locale, [ message => { - const choice = - typeof counter === 'number' ? Math.min(Math.abs(counter), 2) : 0 - return message.split('|')[choice] + const parts = message.split('|') + + /** Check for 'singular|plural' or 'zero|one|multiple' pluralization */ + const isSimplePluralization = parts.length === 2 + let choice = isSimplePluralization ? 1 : 0 + + if (typeof counter === 'number') { + choice = Math.min( + Math.abs(counter) - (isSimplePluralization ? 1 : 0), + parts.length - 1, + ) + } + + return parts[choice] }, ]) }, diff --git a/test/index.test.js b/test/index.test.js index f747a0a..f234056 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -2,7 +2,7 @@ import { i18n } from '../src/index' import { Store } from 'svelte/store.umd' -import { capital, title, upper, lower, isObject, warn } from '../src/utils' +import { capital, title, upper, lower, isObject } from '../src/utils' const store = new Store() const locales = { @@ -11,6 +11,7 @@ const locales = { phrase: 'adoro banana', phrases: ['Frase 1', 'Frase 2'], pluralization: 'Zero | Um | Muito!', + simplePluralization: 'Singular | Plural', interpolation: { key: 'Olá, {0}! Como está {1}?', named: 'Olá, {name}! Como está {time}?', @@ -132,6 +133,10 @@ describe('Localization', () => { store.i18n.setLocale('pt-br') const { _ } = store.get() + expect(_.plural('simplePluralization')).toBe('Plural') + expect(_.plural('simplePluralization', 1)).toBe('Singular') + expect(_.plural('simplePluralization', 3)).toBe('Plural') + expect(_.plural('simplePluralization', -23)).toBe('Plural') expect(_.plural('pluralization')).toBe('Zero') expect(_.plural('pluralization', 0)).toBe('Zero') expect(_.plural('pluralization', 1)).toBe('Um')