11# MessageFormat 2.0 Default Function Registry  
22
3- This section describes the functions for which each implementation MUST provide
4- a _ function handler_  to be conformant with this specification.
5- 
6- Implementations MAY implement additional _ functions_  or additional _ options_ .
7- In particular, implementations are encouraged to provide feedback on proposed
8- _ options_  and their values.
9- 
10- >  [ !NOTE] 
11- >  The [ Stability Policy] ( /spec#stability-policy )  allows for updates to
12- >  Default Registry functions to add support for new options.
13- >  As implementations are permitted to ignore options that they do not support,
14- >  it is possible to write messages using options not defined below
15- >  which currently format with no error, but which could produce errors
16- >  when formatted with a later edition of the Default Registry.
17- >  Therefore, using options not explicitly defined here is NOT RECOMMENDED.
3+ This section defines the ** standard**  _ functions_  which are REQUIRED for conformance with this specification,
4+ along with ** optional**  _ functions_  that SHOULD be implemented to support
5+ additional functionality.
6+ 
7+ To ** _ <dfn >accept</dfn >_ **  a function means that an implementation MUST NOT
8+ emit an _ Unknown Function_  error for that _ function_ 's _ identifier_ .
9+ To _ accept_  an _ option_  means that a _ function handler_  MUST NOT
10+ emit a _ Bad Option_  error for that _ option_ 's _ identifier_  when used with the _ function_ 
11+ it is defined for
12+ and MUST NOT emit a _ Bad Option_  error for any of the _ option_  values
13+ defined for that _ option_ .
14+ Accepting a _ function_  or its _ options_  does not mean that a particular output is produced.
15+ Implementations MAY emit an _ Unsupported Operation_  error for _ options_ 
16+ or _ option_  values that they cannot support.
17+ 
18+ _ Functions_  can define _ options_ . 
19+ An _ option_  can be ** standard**  or ** optional** .
20+ 
21+ Implementations MUST _ accept_  each ** standard**  _ function_  and
22+ MUST _ accept_  all _ options_  defined as ** standard**  for those _ functions_ .
23+ 
24+ Implementations SHOULD _ accept_  each ** optional**  _ function_ . 
25+ For each such _ function_ , the implementation MUST accept all _ options_ 
26+ listed as ** standard**  for that _ function_ .
27+ 
28+ Implementations SHOULD _ accept_  _ options_  that are marked as ** optional** .
29+ 
30+ Implementations MAY _ accept_  _ functions_  not defined in this specification.
31+ In addition, implementations SHOULD provide mechanisms for users to
32+ register and use user-defined _ functions_  and their associated _ functional handlers_ .
33+ Functions not defined by any version of this specification SHOULD use 
34+ an implementation-defined or user-defined _ namespace_ .
35+ 
36+ Implementations MAY implement additional _ options_  not defined
37+ by any version of this specification
38+ for ** standard**  and ** optional**  functions.
39+ Such _ options_  MUST use an implementation-specific _ namespace_ .
40+ 
41+ Implementations MAY _ accept_  additional _ option_  values for _ options_  defined here.
42+ However, such values might become defined with a different meaning in the future,
43+ including with a different, incompatible name
44+ or using an incompatible value space.
45+ Supporting implementation-specific _ option_  values for ** standard**  or ** optional**  functions is NOT RECOMMENDED.
46+ 
47+ Future versions of this specification MAY define additional _ options_  and _ option_  values,
48+ subject to the rules in the [ Stability Policy] ( #stability-policy ) ,
49+ for _ functions_  found in this specification.
50+ As implementations are permitted to ignore _ options_  that they do not support,
51+ it is possible to write _ messages_  using _ options_  not defined below
52+ which currently format with no error, but which could produce errors
53+ when formatted with a later edition of this specification.
54+ Therefore, using _ options_  not explicitly defined here is NOT RECOMMENDED.
1855
1956## String Value Selection and Formatting  
2057
@@ -42,12 +79,15 @@ All other values produce a _Bad Operand_ error.
4279
4380#### Options  
4481
45- The function ` :string `  has no options .
82+ The function ` :string `  has no _ options _ .
4683
4784>  [ !NOTE] 
48- >  Proposals for string transformation options or implementation
49- >  experience with user requirements is desired during the Tech Preview.
50- 
85+ >  While ` :string `  has no built- in _ options_ ,
86+ >  _ options_  in the ` u: `  _ namespace_  can be used. 
87+ >  For example: 
88+ > ``` 
89+ > {$s :string u:dir=ltr u:locale=fr-CA} 
90+ >``` 
5191#### Resolved Value 
5292
5393The _resolved value_ of an _expression_ with a `:string` _function_ 
@@ -155,6 +195,25 @@ The following options and their values are required to be available on the funct
155195  - ([digit size option](#digit-size-options)) 
156196- `maximumSignificantDigits` 
157197  - ([digit size option](#digit-size-options)) 
198+ - `trailingZeroDisplay` 
199+   - `auto` (default) 
200+   - `stripIfInteger` 
201+ - `roundingPriority` 
202+   - `auto` (default) 
203+   - `morePrecision` 
204+   - `lessPrecision` 
205+ - `roundingIncrement` 
206+   - 1 (default), 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, and 5000 
207+ - `roundingMode` 
208+   - `ceil` 
209+   - `floor` 
210+   - `expand` 
211+   - `trunc` 
212+   - `halfCeil` 
213+   - `halfFloor` 
214+   - `halfExpand` (default) 
215+   - `halfTrunc` 
216+   - `halfEven`  
158217
159218If the _operand_ of the _expression_ is an implementation-defined type, 
160219such as the _resolved value_ of an _expression_ with a `:number` or `:integer` _annotation_, 
@@ -170,37 +229,6 @@ with _options_ on the _expression_ taking priority over any option values of the
170229> would be formatted with the resolved options 
171230> `{ notation: 'scientific', minimumFractionDigits: '1' }`. 
172231
173- > [!NOTE] 
174- > The following options and option values are being developed during the Technical Preview 
175- > period. 
176- 
177- The following values for the option `style` are _not_ part of the default registry. 
178- Implementations SHOULD avoid creating options that conflict with these, but 
179- are encouraged to track development of these options during Tech Preview: 
180- - `currency` 
181- - `unit` 
182- 
183- The following options are _not_ part of the default registry. 
184- Implementations SHOULD avoid creating options that conflict with these, but 
185- are encouraged to track development of these options during Tech Preview: 
186- - `currency` 
187-    - valid [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier) 
188-      (no default) 
189- - `currencyDisplay` 
190-    - `symbol` (default) 
191-    - `narrowSymbol` 
192-    - `code` 
193-    - `name` 
194- - `currencySign` 
195-   - `accounting` 
196-   - `standard` (default) 
197- - `unit` 
198-    - (anything not empty) 
199- - `unitDisplay` 
200-    - `long` 
201-    - `short` (default) 
202-    - `narrow` 
203- 
204232##### Default Value of `select` Option 
205233
206234The value `plural` is the default for the option `select`  
@@ -306,37 +334,6 @@ Option values with the following names are however discarded if included in the
306334- `maximumFractionDigits` 
307335- `minimumSignificantDigits` 
308336
309- > [!NOTE] 
310- > The following options and option values are being developed during the Technical Preview 
311- > period. 
312- 
313- The following values for the option `style` are _not_ part of the default registry. 
314- Implementations SHOULD avoid creating options that conflict with these, but 
315- are encouraged to track development of these options during Tech Preview: 
316- - `currency` 
317- - `unit` 
318- 
319- The following options are _not_ part of the default registry. 
320- Implementations SHOULD avoid creating options that conflict with these, but 
321- are encouraged to track development of these options during Tech Preview: 
322- - `currency` 
323-    - valid [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier) 
324-      (no default) 
325- - `currencyDisplay` 
326-    - `symbol` (default) 
327-    - `narrowSymbol` 
328-    - `code` 
329-    - `name` 
330- - `currencySign` 
331-   - `accounting` 
332-   - `standard` (default) 
333- - `unit` 
334-    - (anything not empty) 
335- - `unitDisplay` 
336-    - `long` 
337-    - `short` (default) 
338-    - `narrow` 
339- 
340337##### Default Value of `select` Option 
341338
342339The value `plural` is the default for the option `select`  
@@ -445,6 +442,190 @@ The `:math` _options_ are not included in the resolved option values.
445442
446443The _function_ `:math` performs selection as described in [Number Selection](#number-selection) below. 
447444
445+ ### The `:currency` function 
446+ 
447+ The function `:currency` is a selector and formatter for currency values,  
448+ which are a specialized form of numeric selection and formatting. 
449+ 
450+ #### Operands 
451+ 
452+ The _operand_ of the `:currency` function can be one of any number of 
453+ implementation-defined types, 
454+ each of which contains a numerical `value` and a `currency`; 
455+ or it can be a [Number Operand](#number-operands), as long as the option 
456+ `currency` is provided. 
457+ The option `currency` MUST NOT be used to override the currency of an implementation-defined type. 
458+ Using this option in such a case results in a _Bad Option_ error. 
459+ 
460+ The value of the _operand_'s `currency` MUST be either a string containing a 
461+ well-formed [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier) 
462+ or an implementation-defined currency type. 
463+ Although currency codes are expected to be uppercase, 
464+ implementations SHOULD treat them in a case-insensitive manner. 
465+ A well-formed Unicode Currency Identifier matches the production `currency_code` in this ABNF: 
466+ ```abnf 
467+ currency_code = 3ALPHA 
468+ ``` 
469+ 
470+ A [ Number Operand] ( #number-operands )  without a ` currency `  _ option_  results in a _ Bad Operand_  error.
471+ 
472+ >  [ !NOTE] 
473+ >  For example, in ICU4J, the type ` com.ibm.icu.util.CurrencyAmount `  can be used
474+ >  to set the amount and currency.
475+ 
476+ >  [ !NOTE] 
477+ >  The ` currency `  is only required to be well-formed rather than checked for validity.
478+ >  This allows new currency codes to be defined 
479+ >  (there are many recent examples of this occuring).
480+ >  It also avoids requiring implementations to check currency codes for validity,
481+ >  although implementations are permitted to emit _ Bad Option_  or _ Bad Operand_  for invalid codes.
482+ 
483+ >  [ !NOTE] 
484+ >  For runtime environments that do not provide a ready-made data structure,
485+ >  class, or type for currency values, the implementation ought to provide
486+ >  a data structure, convenience function, or documentation on how to encode
487+ >  the value and currency code for formatting.
488+ >  For example, such an implementation might define a "currency operand"
489+ >  to include a key-value structure with specific keys to be the
490+ >  local currency operand, which might look like the following:
491+ >  ``` 
492+ > { 
493+ >    "value": 123.45, 
494+ >    "currency": "EUR" 
495+ > } 
496+ > ``` 
497+ 
498+ #### Options 
499+ 
500+ Some options do not have default values defined in this specification. 
501+ The defaults for these options are implementation-dependent. 
502+ In general, the default values for such options depend on the locale,  
503+ the currency, 
504+ the value of other options, or all of these. 
505+ 
506+ Fraction digits for currency values behave differently than for other numeric formatters. 
507+ The number of fraction digits displayed is usually set by the currency used. 
508+ For example, USD uses 2 fraction digits, while JPY uses none. 
509+ Setting some other number of `fractionDigits` allows greater precision display 
510+ (such as when performing currency conversions or other specialized operations) 
511+ or disabling fraction digits if set to `0`. 
512+ 
513+ The _option_ `trailingZeroDisplay` has a value `stripIfInteger` that is useful  
514+ for displaying currencies with their fraction digits removed when the fraction 
515+ part of the _operand_ is zero. 
516+ This is sometimes used in _messages_ to make the displayed value omit the fraction part 
517+ automatically. 
518+ > For example, this _message_: 
519+ > ``` 
520+ > The special price is {$price :currency trailingZeroDisplay=stripIfInteger}. 
521+ > ``` 
522+ > When used with the value `5.00 USD` in the `en-US` locale displays as: 
523+ > ``` 
524+ > The special price is $5. 
525+ > ``` 
526+ > But like this when when value is `5.01 USD`: 
527+ > ``` 
528+ > The special price is $5.01. 
529+ > ``` 
530+ 
531+ Implementations MAY internally alias option values that they do not have data or a backing implementation for. 
532+ Notably, the `currencyDisplay` option has a rich set of values that mirrors developments in CLDR data. 
533+ Some implementations might not be able to produce all of these formats for every currency. 
534+ 
535+ > [!NOTE] 
536+ > Except where noted otherwise, the names of _options_ and their _values_ were derived from the 
537+ > [options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options) 
538+ > in JavaScript's `Intl.NumberFormat`. 
539+ 
540+ > [!NOTE] 
541+ > The option `select` does not accept the value `ordinal` because selecting 
542+ > currency values using ordinal rules makes no sense. 
543+ 
544+ The following options and their values are required to be available on the function `:currency`: 
545+ - `select` 
546+    -  `plural` (default) 
547+    -  `exact` 
548+ - `currency` 
549+    - well-formed [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier) 
550+      (no default) 
551+ - `compactDisplay` (this option only has meaning when combined with the option `notation=compact`) 
552+    - `short` (default) 
553+    - `long` 
554+ - `notation` 
555+    - `standard` (default) 
556+    - `compact` 
557+ - `numberingSystem` 
558+    - valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier) 
559+      (default is locale-specific) 
560+ - `currencySign` 
561+   - `accounting` 
562+   - `standard` (default) 
563+ - `currencyDisplay` 
564+   - `narrowSymbol` 
565+   - `symbol` (default) 
566+   - `name` 
567+   - `code` 
568+   - `formalSymbol` 
569+   - `never` (this is called `hidden` in ICU) 
570+ - `useGrouping` 
571+   - `auto` (default) 
572+   - `always` 
573+   - `never` 
574+   - `min2` 
575+ - `minimumIntegerDigits` 
576+   - ([digit size option](#digit-size-options), default: `1`) 
577+ - `fractionDigits` (unlike number/integer formats, the fraction digits for currency formatting are fixed) 
578+   - `auto` (default) (the number of digits used by the currency) 
579+   - ([digit size option](#digit-size-options)) 
580+ - `minimumSignificantDigits` 
581+   - ([digit size option](#digit-size-options)) 
582+ - `maximumSignificantDigits` 
583+   - ([digit size option](#digit-size-options)) 
584+ - `trailingZeroDisplay` 
585+   - `auto` (default) 
586+   - `stripIfInteger` 
587+ - `roundingPriority` 
588+   - `auto` (default) 
589+   - `morePrecision` 
590+   - `lessPrecision` 
591+ - `roundingIncrement` 
592+   - 1 (default), 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, and 5000 
593+ - `roundingMode` 
594+   - `ceil` 
595+   - `floor` 
596+   - `expand` 
597+   - `trunc` 
598+   - `halfCeil` 
599+   - `halfFloor` 
600+   - `halfExpand` (default) 
601+   - `halfTrunc` 
602+   - `halfEven` 
603+ 
604+ If the _operand_ of the _expression_ is an implementation-defined type, 
605+ such as the _resolved value_ of an _expression_ with a `:currency` _annotation_, 
606+ it can include option values. 
607+ These are included in the resolved option values of the _expression_, 
608+ with _options_ on the _expression_ taking priority over any option values of the _operand_. 
609+ 
610+ > For example, the _placeholder_ in this _message_: 
611+ > ``` 
612+ > .input {$n :currency currency=USD trailingZeroDisplay=stripIfInteger} 
613+ > {{{$n :currency currencySign=accounting}}} 
614+ > ``` 
615+ > would be formatted with the resolved options 
616+ > `{ currencySign: 'accounting', trailingZeroDisplay: 'stripIfInteger', currency: 'USD' }`. 
617+ 
618+ #### Resolved Value 
619+ 
620+ The _resolved value_ of an _expression_ with a `:currency` _function_ 
621+ contains an implementation-defined currency value 
622+ of the _operand_ of the annotated _expression_, 
623+ together with the resolved options' values. 
624+ 
625+ #### Selection 
626+ 
627+ The _function_ `:currency` performs selection as described in [Number Selection](#number-selection) below. 
628+ 
448629### Number Operands 
449630
450631The _operand_ of a number function is either an implementation-defined type or 
0 commit comments