Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement :unit as Proposed RECOMMENDED in the registry #922

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions spec/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,157 @@ its _resolved value_ contains the implementation-defined integer value
of the _operand_ of the annotated _expression_,
together with the resolved options' values.


### `:unit` function

The function `:unit` is a selector and formatter for unitized values,
that is, numeric values associated with a unit of measurement.
This is a specialized form of numeric selection and formatting.

> [!IMPORTANT]
> Implementation of this function is **_OPTIONAL_**.
aphillips marked this conversation as resolved.
Show resolved Hide resolved
> Any implementation of this function is strongly encouraged to follow this specification.

#### Operands

The _operand_ of the `:unit` function can be one of any number of
implementation-defined types,
each of which contains a numerical `value` plus a `unit`
or it can be a [Number Operand](#number-operands), as long as the option
`unit` is provided.
The option `unit` MAY be used to override the units of an implementation-defined type,
provided the units are compatible and the implementation supports conversion.

The value of the _operand_'s `unit` SHOULD be either a string containing a
valid [Unit Identifier](https://www.unicode.org/reports/tr35/tr35-general.html#unit-identifiers)
or an implementation-defined unit type.

A [Number Operand](#number-operands) without a `unit` _option_ results in a _Bad Operand_ error.

> [!NOTE]
> For example, in ICU4J, the type `com.ibm.icu.util.Measure` might be used
> as an _operand_ for `:unit` because it contains the `value` and `unit`.

> [!NOTE]
> For runtime environments that do not provide a ready-made data structure,
> class, or type for unit values, the implementation ought to provide
> a data structure, convenience function, or documentation on how to encode
> the value and unit for formatting.
> For example, such an implementation might define a "unit operand"
> to include a key-value structure with specific keys to be the
> local unit operand, which might look like the following:
> ```
> {
> "value": 123.45,
> "unit": "kilometer-per-hour"
> }
> ```

#### Options

Some options do not have default values defined in this specification.
The defaults for these options are implementation-dependent.
In general, the default values for such options depend on the locale,
the unit,
the value of other options, or all of these.

The following options and their values are required to be available on the function `:unit`:
- `select`
- `plural` (default)
- `ordinal`
- `exact`
- `unit`
- valid [Unit Identifier](https://www.unicode.org/reports/tr35/tr35-general.html#unit-identifiers)
(no default)
macchiati marked this conversation as resolved.
Show resolved Hide resolved
- `usage`
- valid usage identifier (TBD)
(no default)
- `unitDisplay`
- `short` (default)
- `narrow`
- `long`
- `compactDisplay` (this option only has meaning when combined with the option `notation=compact`)
- `short` (default)
- `long`
- `notation`
- `standard` (default)
- `compact`
- `numberingSystem`
- valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier)
(default is locale-specific)
- `signDisplay`
- `auto` (default)
- `always`
- `exceptZero`
- `negative`
- `never`
- `useGrouping`
- `auto` (default)
- `always`
- `never`
- `min2`
- `minimumIntegerDigits`
- ([digit size option](#digit-size-options), default: `1`)
- `minimumFractionDigits`
- ([digit size option](#digit-size-options))
- `maximumFractionDigits`
- ([digit size option](#digit-size-options))
- `minimumSignificantDigits`
- ([digit size option](#digit-size-options))
- `maximumSignificantDigits`
- ([digit size option](#digit-size-options))

aphillips marked this conversation as resolved.
Show resolved Hide resolved
If the _operand_ of the _expression_ is an implementation-defined type,
such as the _resolved value_ of an _expression_ with a `:unit` _annotation_,
it can include option values.
These are included in the resolved option values of the _expression_,
with _options_ on the _expression_ taking priority over any option values of the _operand_.

> For example, the _placeholder_ in this _message_:
> ```
> .input {$n :unit unit=furlong minimumFractionDigits=2}
> {{{$n :unit minimumIntegerDigits=1}}}
> ```
> would have the resolved options:
> `{ unit: 'furlong', minimumFractionDigits: '2', minimumIntegerDigits: '1' }`.

Some implementations support conversion between compatible units.
Attempting to convert units (by specifying the `usage` option)
produces a _Bad Option_ error if conversion is unsupported
or if the specified units are incompatible.
For example, trying to convert meters to gallons produces a _Bad Option_.

Implementations MUST NOT substitute the unit without performing the associated conversion.

> For example, consider the value:
> ```
> {
> "value": 123.5,
> "unit": "meter"
> }
> ```
> The following _message_ might convert the formatted result to U.S. customary units:
> ```
> You have {$v :unit unit=foot maximumFractionDigits=0} to go.
> ```
> This can produce "You have 405 feet to go."

Not all usages are compatible with the unit.
Implementations will produce a _Bad Option_ error for units
or combinations of units and usages that are not supported.

#### Selection

The _function_ `:unit` performs selection as described in [Number Selection](#number-selection) below.

#### Composition

When an _operand_ or an _option_ value uses a _variable_ annotated,
directly or indirectly, by a `:unit` _annotation_,
its _resolved value_ contains an implementation-defined unit value
of the _operand_ of the annotated _expression_,
together with the resolved options' values.

### Number Operands

The _operand_ of a number function is either an implementation-defined type or
Expand Down