diff --git a/.travis.yml b/.travis.yml index b18bae5..21a7e31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,8 @@ sudo: false +before_install: + - npm install full-icu +before_script: + - export NODE_ICU_DATA=node_modules/full-icu language: node_js node_js: - '6' diff --git a/index.js b/index.js index 9278dbe..2788730 100644 --- a/index.js +++ b/index.js @@ -1,11 +1,13 @@ 'use strict'; const UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; -module.exports = num => { +module.exports = (num, options) => { if (!Number.isFinite(num)) { throw new TypeError(`Expected a finite number, got ${typeof num}: ${num}`); } + options = Object.assign({}, options); + const neg = num < 0; if (neg) { @@ -13,12 +15,32 @@ module.exports = num => { } if (num < 1) { - return (neg ? '-' : '') + num + ' B'; + const numStr = toLocaleString(num, options.locale); + return (neg ? '-' : '') + numStr + ' B'; } const exponent = Math.min(Math.floor(Math.log10(num) / 3), UNITS.length - 1); - const numStr = Number((num / Math.pow(1000, exponent)).toPrecision(3)); + num = Number((num / Math.pow(1000, exponent)).toPrecision(3)); + const numStr = toLocaleString(num, options.locale); + const unit = UNITS[exponent]; return (neg ? '-' : '') + numStr + ' ' + unit; }; + +/** + * Formats the given number using number.toLocaleString(..). + * If locale is a string, the value is expected to be a locale-key (e.g. 'de'). + * If locale is true, the system default locale is used for translation. + * If no value for locale is specified, the number is returned unmodified. + */ +function toLocaleString(num, locale) { + let result = num; + if (typeof locale === 'string') { + result = num.toLocaleString(locale); + } else if (locale === true) { + result = num.toLocaleString(); + } + + return result; +} diff --git a/readme.md b/readme.md index fd7b525..490bd29 100644 --- a/readme.md +++ b/readme.md @@ -25,8 +25,28 @@ prettyBytes(1337); prettyBytes(100); //=> '100 B' + +// Localize output using german locale +prettyBytes(1337, { locale: 'de' }); +//=> '1,34 kB' ``` +## API +### prettyBytes(input, [options]) +#### input +Type: `number` + +The number to format. + +#### options +##### locale +Type: `boolean || string` +Default: `false` / no localization + +- `string`: Expects a [BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) (e.g. `en`, `de`, ...) +- `boolean`: If `true`: Localize the output using the system/browser locale. + +**Note:** Localization should generally work in browsers. Node.js needs to be [built](https://github.com/nodejs/node/wiki/Intl) with `full-icu` or `system-icu`. Alternatively, the [full-icu](https://github.com/unicode-org/full-icu-npm) module can be used to provide support at runtime. ## Related diff --git a/test.js b/test.js index c3d7f03..99f2dc9 100644 --- a/test.js +++ b/test.js @@ -31,3 +31,35 @@ test('supports negative number', t => { t.is(m(-999), '-999 B'); t.is(m(-1001), '-1 kB'); }); + +test('localized output', t => { + t.is(m(-0.4, {locale: 'de'}), '-0,4 B'); + t.is(m(0.4, {locale: 'de'}), '0,4 B'); + t.is(m(1001, {locale: 'de'}), '1 kB'); + t.is(m(10.1, {locale: 'de'}), '10,1 B'); + t.is(m(1e30, {locale: 'de'}), '1.000.000 YB'); + + t.is(m(-0.4, {locale: 'en'}), '-0.4 B'); + t.is(m(0.4, {locale: 'en'}), '0.4 B'); + t.is(m(1001, {locale: 'en'}), '1 kB'); + t.is(m(10.1, {locale: 'en'}), '10.1 B'); + t.is(m(1e30, {locale: 'en'}), '1,000,000 YB'); + + t.is(m(-0.4, {locale: true}), '-0.4 B'); + t.is(m(0.4, {locale: true}), '0.4 B'); + t.is(m(1001, {locale: true}), '1 kB'); + t.is(m(10.1, {locale: true}), '10.1 B'); + t.is(m(1e30, {locale: true}), '1,000,000 YB'); + + t.is(m(-0.4, {locale: false}), '-0.4 B'); + t.is(m(0.4, {locale: false}), '0.4 B'); + t.is(m(1001, {locale: false}), '1 kB'); + t.is(m(10.1, {locale: false}), '10.1 B'); + t.is(m(1e30, {locale: false}), '1000000 YB'); + + t.is(m(-0.4, {locale: undefined}), '-0.4 B'); + t.is(m(0.4, {locale: undefined}), '0.4 B'); + t.is(m(1001, {locale: undefined}), '1 kB'); + t.is(m(10.1, {locale: undefined}), '10.1 B'); + t.is(m(1e30, {locale: undefined}), '1000000 YB'); +});