Skip to content

Commit 55e166a

Browse files
aphillipscatamorphismmacchiati
authored
Implement :unit as Proposed RECOMMENDED in the registry (#922)
* Implement `:unit` as _OPTIONAL_ in the registry This introduces `:unit` as an optional function, per discussion elsewhere. * Update registry.md * Remove stray mentions of "currency" * Apply suggestions from code review Co-authored-by: Tim Chevalier <[email protected]> * Better specify conversion conditions * Address per-unit comments * Update spec/registry.md Co-authored-by: Mark Davis <[email protected]> * Changes from 2024-11-04 teleconference - Cleanup the `usage` option (which appeared twice). - Remove `ordinal` selection and add a note to that effect. - Clean up text about conversion * Make `usage` optional * Add rounding to `:unit` * Make consistent with other functions - Replace `Composition` with `Resolved Value` - Match phrasing to other functions - Move `Resolved Value` before `Selection` like other functions * Linkify some terms; add `Unsupported Operation` for one error * Make section title consistent with other sections * Address comments - Change `:unit` to **Proposed** - Modify `usage` to use valid - Modify `usage` to be in its own subsection - Modify `usage` to SHOULD _Unsupported Operation_ when the conversion isn't supported * Address comments * Address comments, remove unit conversion * Move link to unit conversion to correct option --------- Co-authored-by: Tim Chevalier <[email protected]> Co-authored-by: Mark Davis <[email protected]>
1 parent 849db9c commit 55e166a

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

spec/registry.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,173 @@ together with the resolved options' values.
648648
649649
The _function_ `:currency` performs selection as described in [Number Selection](#number-selection) below.
650650
651+
### The `:unit` function
652+
653+
The _function_ `:unit` is **Proposed** for inclusion in the next release of this specification but has not yet been finalized.
654+
The _function_ `:unit` is proposed to be a **RECOMMENDED** selector and formatter for unitized values,
655+
that is, for numeric values associated with a unit of measurement.
656+
This is a specialized form of numeric selection and formatting.
657+
658+
#### Operands
659+
660+
The _operand_ of the `:unit` function can be one of any number of
661+
implementation-defined types,
662+
each of which contains a numerical `value` plus a `unit`
663+
or it can be a [Number Operand](#number-operands), as long as the _option_
664+
`unit` is provided.
665+
666+
The value of the _operand_'s `unit` SHOULD be either a string containing a
667+
valid [Unit Identifier](https://www.unicode.org/reports/tr35/tr35-general.html#unit-identifiers)
668+
or an implementation-defined unit type.
669+
670+
A [Number Operand](#number-operands) without a `unit` _option_ results in a _Bad Operand_ error.
671+
672+
> [!NOTE]
673+
> For example, in ICU4J, the type `com.ibm.icu.util.Measure` might be used
674+
> as an _operand_ for `:unit` because it contains the `value` and `unit`.
675+
676+
> [!NOTE]
677+
> For runtime environments that do not provide a ready-made data structure,
678+
> class, or type for unit values, the implementation ought to provide
679+
> a data structure, convenience function, or documentation on how to encode
680+
> the value and unit for formatting.
681+
> For example, such an implementation might define a "unit operand"
682+
> to include a key-value structure with specific keys to be the
683+
> local unit operand, which might look like the following:
684+
> ```
685+
> {
686+
> "value": 123.45,
687+
> "unit": "kilometer-per-hour"
688+
> }
689+
> ```
690+
691+
#### Options
692+
693+
Some _options_ do not have default values defined in this specification.
694+
The defaults for these _options_ are implementation-dependent.
695+
In general, the default values for such _options_ depend on the locale,
696+
the unit,
697+
the value of other _options_, or all of these.
698+
699+
> [!NOTE]
700+
> The option `select` does not accept the value `ordinal` because selecting
701+
> unit values using ordinal rules makes no sense.
702+
703+
The following options and their values are required to be available on the function `:unit`:
704+
- `select`
705+
- `plural` (default)
706+
- `exact`
707+
- `unit`
708+
- valid [Unit Identifier](https://www.unicode.org/reports/tr35/tr35-general.html#unit-identifiers)
709+
(no default)
710+
- `usage` \[RECOMMENDED\]
711+
- valid [Unicode Unit Preference](https://www.unicode.org/reports/tr35/tr35-info.html#unit-preferences)
712+
(no default, see [Unit Conversion](#unit-conversion) below)
713+
- `unitDisplay`
714+
- `short` (default)
715+
- `narrow`
716+
- `long`
717+
- `compactDisplay` (this option only has meaning when combined with the option `notation=compact`)
718+
- `short` (default)
719+
- `long`
720+
- `notation`
721+
- `standard` (default)
722+
- `compact`
723+
- `numberingSystem`
724+
- valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier)
725+
(default is locale-specific)
726+
- `signDisplay`
727+
- `auto` (default)
728+
- `always`
729+
- `exceptZero`
730+
- `negative`
731+
- `never`
732+
- `useGrouping`
733+
- `auto` (default)
734+
- `always`
735+
- `never`
736+
- `min2`
737+
- `minimumIntegerDigits`
738+
- ([digit size option](#digit-size-options), default: `1`)
739+
- `minimumFractionDigits`
740+
- ([digit size option](#digit-size-options))
741+
- `maximumFractionDigits`
742+
- ([digit size option](#digit-size-options))
743+
- `minimumSignificantDigits`
744+
- ([digit size option](#digit-size-options))
745+
- `maximumSignificantDigits`
746+
- ([digit size option](#digit-size-options))
747+
- `roundingPriority`
748+
- `auto` (default)
749+
- `morePrecision`
750+
- `lessPrecision`
751+
- `roundingIncrement`
752+
- 1 (default), 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, and 5000
753+
- `roundingMode`
754+
- `ceil`
755+
- `floor`
756+
- `expand`
757+
- `trunc`
758+
- `halfCeil`
759+
- `halfFloor`
760+
- `halfExpand` (default)
761+
- `halfTrunc`
762+
- `halfEven`
763+
764+
If the _operand_ of the _expression_ is an implementation-defined type,
765+
such as the _resolved value_ of an _expression_ with a `:unit` _annotation_,
766+
it can include _option_ values.
767+
These are included in the resolved _option_ values of the _expression_,
768+
with _options_ on the _expression_ taking priority over any _option_ values of the _operand_.
769+
770+
> For example, the _placeholder_ in this _message_:
771+
> ```
772+
> .input {$n :unit unit=furlong minimumFractionDigits=2}
773+
> {{{$n :unit minimumIntegerDigits=1}}}
774+
> ```
775+
> would have the resolved options:
776+
> `{ unit: 'furlong', minimumFractionDigits: '2', minimumIntegerDigits: '1' }`.
777+
778+
#### Resolved Value
779+
780+
The _resolved value_ of an _expression_ with a `:unit` _function_
781+
consist of an implementation-defined unit value
782+
of the _operand_ of the annotated _expression_,
783+
together with the resolved _options_ and their resolved values.
784+
785+
#### Selection
786+
787+
The _function_ `:unit` performs selection as described in [Number Selection](#number-selection) below.
788+
789+
#### Unit Conversion
790+
791+
Implementations MAY support conversion to the locale's preferred units via the `usage` _option_.
792+
Implementing this _option_ is optional.
793+
Not all `usage` values are compatible with a given unit.
794+
Implementations SHOULD emit an _Unsupported Operation_ error if the requested conversion is not supported.
795+
796+
> For example, trying to convert a `length` unit (such as "meters")
797+
> to a `volume` usage (which might be a unit akin to "liters" or "gallons", depending on the locale)
798+
> could produce an _Unsupported Operation_ error.
799+
800+
Implementations MUST NOT substitute the unit without performing the associated conversion.
801+
802+
> For example, consider the value:
803+
> ```
804+
> {
805+
> "value": 123.5,
806+
> "unit": "meter"
807+
> }
808+
> ```
809+
> The following _message_ might convert the formatted result to U.S. customary units
810+
> in the `en-US` locale:
811+
> ```
812+
> You have {$v :unit usage=road maximumFractionDigits=0} to go.
813+
> ```
814+
> This can produce "You have 405 feet to go."
815+
816+
817+
651818
### Number Operands
652819
653820
The _operand_ of a number function is either an implementation-defined type or

0 commit comments

Comments
 (0)