Skip to content

Commit

Permalink
Number & Currency: Add format to parts support
Browse files Browse the repository at this point in the history
- Currency: Fix code style
- Currency: pluralGenerator better error handling

Fixes #679
Fixes #680
  • Loading branch information
rxaviers committed Mar 25, 2020
1 parent a053ecb commit 8b2a006
Show file tree
Hide file tree
Showing 44 changed files with 5,021 additions and 503 deletions.
48 changes: 45 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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.
Expand All @@ -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 )`.
Expand Down Expand Up @@ -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] )`
Expand Down
117 changes: 117 additions & 0 deletions doc/api/currency/currency-to-parts-formatter.md
Original file line number Diff line number Diff line change
@@ -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 );
})
});
```
140 changes: 140 additions & 0 deletions doc/api/number/number-to-parts-formatter.md
Original file line number Diff line number Diff line change
@@ -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 );
});
```
4 changes: 2 additions & 2 deletions examples/globalize-compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 3 additions & 1 deletion src/build/intro-currency-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
5 changes: 4 additions & 1 deletion src/build/intro-currency.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/build/intro-date-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 8b2a006

Please sign in to comment.