Skip to content
Permalink
Browse files

Number & Currency: Add format to parts support

- Currency: Fix code style
- Currency: pluralGenerator better error handling

Fixes #679
Fixes #680
  • Loading branch information
rxaviers committed Feb 11, 2020
1 parent a053ecb commit 8b2a006d759e83f2f8fb898d36fe033db9edb3c3
Showing with 5,021 additions and 503 deletions.
  1. +45 −3 README.md
  2. +117 −0 doc/api/currency/currency-to-parts-formatter.md
  3. +140 −0 doc/api/number/number-to-parts-formatter.md
  4. +2 −2 examples/globalize-compiler/package.json
  5. +1 −1 package.json
  6. +3 −1 src/build/intro-currency-runtime.js
  7. +4 −1 src/build/intro-currency.js
  8. +2 −0 src/build/intro-date-runtime.js
  9. +2 −0 src/build/intro-date.js
  10. +2 −0 src/build/intro-number-runtime.js
  11. +2 −0 src/build/intro-number.js
  12. +44 −0 src/common/format-message-to-parts.js
  13. +12 −0 src/common/parts/join.js
  14. +17 −0 src/common/parts/push.js
  15. +9 −2 src/core-runtime.js
  16. +11 −4 src/core.js
  17. +19 −1 src/currency-runtime.js
  18. +91 −22 src/currency.js
  19. +0 −26 src/currency/code-properties.js
  20. +6 −27 src/currency/formatter-fn.js
  21. +17 −3 src/currency/name-format.js
  22. +17 −9 src/currency/name-properties.js
  23. +17 −0 src/currency/symbol-format.js
  24. +21 −15 src/currency/symbol-properties.js
  25. +36 −0 src/currency/to-parts-formatter-fn.js
  26. +4 −9 src/date/format.js
  27. +4 −4 src/date/formatter-fn.js
  28. +18 −2 src/number-runtime.js
  29. +46 −2 src/number.js
  30. +95 −36 src/number/format.js
  31. +4 −9 src/number/formatter-fn.js
  32. +16 −0 src/number/to-parts-formatter-fn.js
  33. +4 −0 test/functional.js
  34. +5 −5 test/functional/currency/currency-formatter.js
  35. +828 −0 test/functional/currency/currency-to-parts-formatter.js
  36. +101 −0 test/functional/currency/format-currency-to-parts.js
  37. +337 −0 test/functional/number/format-number-to-parts.js
  38. +93 −0 test/functional/number/number-to-parts-formatter.js
  39. +0 −1 test/unit.js
  40. +0 −67 test/unit/currency/code-properties.js
  41. +85 −10 test/unit/currency/name-format.js
  42. +0 −4 test/unit/currency/name-properties.js
  43. +38 −13 test/unit/currency/symbol-properties.js
  44. +2,706 −224 test/unit/number/format.js
@@ -99,11 +99,11 @@ We do NOT embed any i18n data within our library. However, we make it really eas

| File | Minified + gzipped size | Runtime minified + gzipped size | Summary |
| -------------------------- | ----------------------: | ------------------------------: | ------------------------------------------------------------ |
| globalize.js | 1.5KB | 1.0KB | [Core library](#core-module) |
| globalize/currency.js | 2.7KB | 0.6KB | [Currency module](#currency-module) provides currency formatting |
| globalize.js | 1.7KB | 1.1KB | [Core library](#core-module) |
| globalize/currency.js | 3.0KB | 0.7KB | [Currency module](#currency-module) provides currency formatting |
| globalize/date.js | 7.7KB | 4.3KB | [Date module](#date-module) provides date formatting and parsing |
| globalize/message.js | 5.3KB | 0.7KB | [Message module](#message-module) provides ICU message format support |
| globalize/number.js | 4.1KB | 2.3KB | [Number module](#number-module) provides number formatting and parsing |
| globalize/number.js | 4.4KB | 2.6KB | [Number module](#number-module) provides number formatting and parsing |
| globalize/plural.js | 2.3KB | 0.4KB | [Plural module](#plural-module) provides pluralization support |
| globalize/relative-time.js | 0.8KB | 0.5KB | [Relative time module](#relative-time-module) provides relative time formatting support |
| globalize/unit.js | 0.9KB | 0.6KB | [Unit module](#unit-module) provides unit formatting support |
@@ -475,6 +475,21 @@ Return a function that formats a number according to the given options or locale

[Read more...](doc/api/number/number-formatter.md)

#### `.numberToPartsFormatter( [options] )`

Return a function that formats a number into parts tokens according to the given options or locale's defaults.

```javascript
.numberToPartsFormatter()( new Date() )
// > [
// { "type": "integer", "value": "3" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "142" }
// ]
```

[Read more...](doc/api/number/number-to-parts-formatter.md)

#### `.numberParser( [options] )`

Return a function that parses a string representing a number according to the given options or locale's defaults.
@@ -496,6 +511,10 @@ Return a function that parses a string representing a number according to the gi

Alias for `.numberFormatter( [options] )( value )`.

#### `.formatNumberToParts( value [, options] )`

Alias for `.numberToPartsFormatter( [options] )( value )`.

#### `.parseNumber( value [, options] )`

Alias for `.numberParser( [options] )( value )`.
@@ -525,10 +544,33 @@ Return a function that formats a currency according to the given options or loca

[Read more...](doc/api/currency/currency-formatter.md)

#### `.currencyToPartsFormatter( currency [, options] )`

Return a function that formats a currency into parts tokens according to the given options or locale's defaults.

```javascript
.currencyToPartsFormatter()( new Date() )
// > [
// { "type": "currency", "value": "USD" },
// { "type": "literal", "value": " " },
// { "type": "integer", "value": "69" },
// { "type": "group", "value": "," },
// { "type": "integer", "value": "900" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "00" }
// ]
```

[Read more...](doc/api/currency/currency-to-parts-formatter.md)

#### `.formatCurrency( value, currency [, options] )`

Alias for `.currencyFormatter( currency [, options] )( value )`.

#### `.formatCurrencyToParts( value, currency [, options] )`

Alias for `.currencyToPartsFormatter( currency [, options] )( value )`.

### Plural module

#### `.pluralGenerator( [options] )`
@@ -0,0 +1,117 @@
## .currencyToPartsFormatter( currency [, options] ) ➜ function( value )

Return a function that formats a `currency` into parts tokens according to the given `options` or locale's defaults.

The returned function is invoked with one argument: the Number `value` to be formatted.

### Parameters

#### currency

3-letter currency code as defined by ISO 4217, eg. `"USD"`.

#### options

Please, see [.currencyFormatter() options](./currency-formatter.md#parameters).

#### value

Number to be formatted, eg. `9.99`.

### Returns

An Array of objects containing the formatted currency in parts. The returned structure looks like this:

```js
[
{ type: "day", value: "17" },
{ type: "weekday", value: "Monday" }
]
```

Possible types are the following:

- `currency`

The currency string, such as the symbols `"$"` and `"€"` or the name `"Dollar"`, `"Euro"` depending on which style is used.

Please, see [.numberToPartsFormatter()](../number/number-to-parts-formatter.md#returns) for details about the inherited number parts such as `decimal`, `fraction`, `group`, `infinity`, `integer`, `literal`, `minusSign`, `nan`, `plusSign`, `percentSign`, and `compact`.

### Example

Prior to using any currency methods, you must load `cldr/main/{locale}/currencies.json`, `cldr/supplemental/currencyData.json`, and the CLDR content required by the number module. If using plural messages, you also must load the CLDR content required by the plural module. Read [CLDR content][] if you need more information.

[CLDR content]: ../../../README.md#2-cldr-content

#### Static Formatter

#### Using the default options

You can use the static method `Globalize.currencyToPartsFormatter()`, which uses the default locale.

```javascript
var formatter;
Globalize.locale( "en" );
formatter = Globalize.currencyToPartsFormatter( "USD" );
formatter( 9.99 );
// > [
// { "type": "currency", "value": "$" },
// { "type": "integer", "value": "9" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "99" }
// ]
```

#### Instance Formatter

You can use the instance method `.currencyFormatter()`, which uses the instance locale.

```javascript
var deFormatter = Globalize( "de" ).currencyToPartsFormatter( "EUR" ),
zhFormatter = Globalize( "zh" ).currencyToPartsFormatter( "EUR" );
deFormatter( 9.99 );
// > [
// { "type": "integer", "value": "9" },
// { "type": "decimal", "value": "," },
// { "type": "fraction", "value": "99" },
// { "type": "literal", "value": " " },
// { "type": "currency", "value": "€" }
// ]
zhFormatter( 9.99 );
// > [
// { "type": "currency", "value": "€" },
// { "type": "integer", "value": "9" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "99" }
// ]
```

The information is available separately and it can be formatted and concatenated again in a customized way. For example by using [`Array.prototype.map()`][], [arrow functions][], a [switch statement][], [template literals][], and [`Array.prototype.reduce()`][].

[`Array.prototype.map()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
[arrow functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
[switch statement]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
[template literals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
[`Array.prototype.reduce()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

#### More Examples

Please, see [.currencyFormatter() example](./currency-formatter.md#example) for additional examples such as using alternative `symbolForm`, configuring `style` (symbol, accounting, and name styles), and the inherited number options (e.g., compact numbers).

#### Performance Suggestion

For improved performance on iterations, first create the formatter. Then, reuse it on each loop.

```javascript
var formatter = Globalize( "en" ).currencyToPartsFormatter( "USD" );
renderInvoice({
prices: prices.map(function( price ) {
return formatter( price );
})
});
```
@@ -0,0 +1,140 @@
## .numberToPartsFormatter( [options] ) ➜ function( value )

Return a function that formats a number into parts tokens according to the given options.

The returned function is invoked with one argument: the Number `value` to be formatted.

### Parameters

#### options

Please, see [.numberFormatter() options](./number-formatter.md#parameters).

### Returns

An Array of objects containing the formatted number in parts. The returned structure looks like this:

- `decimal`

The decimal separator string, e.g., `"."`.

- `fraction`

The fraction number.

- `group`

The group separator string, e.g., `","`.

- `infinity`

The Infinity string, e.g., `"∞"`.

- `integer`

The integer number.

- `literal`

Any literal strings or whitespace in the formatted number.

- `minusSign`

The minus sign string, e.g., `"-"`.

- `nan`

The NaN string, e.g., `"NaN"`.

- `plusSign`

The plus sign string, e.g., `"+"`.

- `percentSign`

The percent sign string, e.g., `"%"`.

- `compact`

The compact string, e.g., `"thousand"`.

### Examples

Prior to using any number methods, you must load `cldr/main/{locale}/numbers.json` and `cldr/supplemental/numberingSystems.json`. Read [CLDR content][] if you need more information.

[CLDR content]: ../../../README.md#2-cldr-content

#### Static Formatter

You can use the static method `Globalize.numberToPartsFormatter()`, which uses the default locale.

```javascript
var formatter;
Globalize.locale( "en" );
formatter = Globalize.numberToPartsFormatter();
formatter( 3.141592 );
// > [
// { "type": "integer", "value": "3" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "142" }
// ]
```

#### Instance Formatter

You can use the instance method `.numberFormatter()`, which uses the instance
locale.

```javascript
var arFormatter = Globalize( "ar" ).numberToPartsFormatter(),
esFormatter = Globalize( "es" ).numberToPartsFormatter(),
zhFormatter = Globalize( "zh-u-nu-native" ).numberToPartsFormatter();
arFormatter( 3.141592 );
// > [
// { "type": "integer", "value": "٣" },
// { "type": "decimal", "value": "٫" },
// { "type": "fraction", "value": "١٤٢" }
// ]
esFormatter( 3.141592 );
// > [
// { "type": "integer", "value": "3" },
// { "type": "decimal", "value": "," },
// { "type": "fraction", "value": "142" }
// ]
zhFormatter( 3.141592 );
// > [
// { "type": "integer", "value": "三" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "一四二" }
// ]
```

The information is available separately and it can be formatted and concatenated again in a customized way. For example by using [`Array.prototype.map()`][], [arrow functions][], a [switch statement][], [template literals][], and [`Array.prototype.reduce()`][].

[`Array.prototype.map()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
[arrow functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
[switch statement]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
[template literals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
[`Array.prototype.reduce()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

#### More Examples

Please, see [.numberFormatter() example](./number-formatter.md#example) for additional examples such as configuring decimal places, significant digits, percentages, and compact numbers.

#### Performance Suggestions

For improved performance on iterations, the formatter should be created before the loop. Then, it can be reused in each iteration.

```javascript
var numbers = [ 1, 1, 2, 3, ... ];
var formatter = Globalize( "en" ).numberFormatter();
formattedNumbers = numbers.map(function( number ) {
return formatter( number );
});
```
@@ -6,8 +6,8 @@
},
"devDependencies": {
"cldr-data": ">=25",
"globalize": "^1.3.0",
"globalize-compiler": "^1.0.0",
"globalize": "^1.5.0",
"globalize-compiler": "^1.1.1",
"iana-tz-data": "^2017.1.0",
"jquery": "latest"
},
@@ -75,7 +75,7 @@
"devDependencies": {
"cldr-data-downloader": "^0.3.1",
"glob": "^7.1.2",
"globalize-compiler": "^1.1.0",
"globalize-compiler": "^1.1.1",
"grunt": "1.0.1",
"grunt-check-dependencies": "1.0.0",
"grunt-commitplease": "0.0.6",
@@ -41,7 +41,9 @@

"use strict";

var formatMessage = Globalize._formatMessage,
var formatMessageToParts = Globalize._formatMessageToParts,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
runtimeKey = Globalize._runtimeKey,
validateParameterPresence = Globalize._validateParameterPresence,
validateParameterTypeNumber = Globalize._validateParameterTypeNumber;
@@ -34,9 +34,12 @@
}(this, function( Cldr, Globalize ) {

var alwaysArray = Globalize._alwaysArray,
formatMessage = Globalize._formatMessage,
createError = Globalize._createError,
formatMessageToParts = Globalize._formatMessageToParts,
numberNumberingSystem = Globalize._numberNumberingSystem,
numberPattern = Globalize._numberPattern,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
runtimeBind = Globalize._runtimeBind,
stringPad = Globalize._stringPad,
validateCldr = Globalize._validateCldr,
@@ -43,6 +43,8 @@

var createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature,
looseMatching = Globalize._looseMatching,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
regexpEscape = Globalize._regexpEscape,
removeLiteralQuotes = Globalize._removeLiteralQuotes,
runtimeKey = Globalize._runtimeKey,

0 comments on commit 8b2a006

Please sign in to comment.
You can’t perform that action at this time.