diff --git a/spec/errors.md b/spec/errors.md
index a625b1c4e1..5782622b2e 100644
--- a/spec/errors.md
+++ b/spec/errors.md
@@ -269,7 +269,7 @@ a reference to a function which cannot be resolved.
### Bad Selector
A **_Bad Selector_** error occurs when a message includes a _selector_
-with a resolved value which does not support selection.
+with a _resolved value_ which does not support selection.
> For example, attempting to format this message
> would result in a _Bad Selector_ error:
@@ -283,10 +283,10 @@ with a resolved value which does not support selection.
## Message Function Errors
A **_Message Function Error_** is any error that occurs
-when calling a message function implementation
+when calling a _function handler_
or which depends on validation associated with a specific function.
-Implementations SHOULD provide a way for _functions_ to emit
+Implementations SHOULD provide a way for _function handlers_ to emit
(or cause to be emitted) any of the types of error defined in this section.
Implementations MAY also provide implementation-defined _Message Function Error_ types.
@@ -300,7 +300,7 @@ Implementations MAY also provide implementation-defined _Message Function Error_
> 3. Uses a `:get` message function which requires its argument to be an object and
> an option `field` to be provided with a string value.
>
-> The exact type of _Message Function Error_ is determined by the message function implementation.
+> The exact type of _Message Function Error_ is determined by the _function handler_.
>
> ```
> Hello, {horse :get field=name}!
diff --git a/spec/formatting.md b/spec/formatting.md
index f048975659..27495fb01e 100644
--- a/spec/formatting.md
+++ b/spec/formatting.md
@@ -16,7 +16,8 @@ The formatting of a _message_ is defined by the following operations:
For a message with no _selectors_, this is simple as there is only one _pattern_.
With _selectors_, this will depend on their resolution.
-- **_Formatting_** takes the resolved values of the selected _pattern_,
+- **_Formatting_** takes the _resolved values_ of
+ the _text_ and _placeholder_ parts of the selected _pattern_,
and produces the formatted result for the _message_.
Depending on the implementation, this result could be a single concatenated string,
an array of objects, an attributed string, or some other locally appropriate data type.
@@ -25,7 +26,7 @@ The formatting of a _message_ is defined by the following operations:
with reference to the current _formatting context_.
This can include multiple steps,
such as looking up the value of a variable and calling formatting functions.
- The form of the resolved value is implementation defined and the
+ The form of the _resolved value_ is implementation defined and the
value might not be evaluated or formatted yet.
However, it needs to be "formattable", i.e. it contains everything required
by the eventual formatting.
@@ -40,7 +41,7 @@ as long as the final _formatting_ result is made available to users
and the observable behavior of the _formatting_ matches that described here.
_Attributes_ MUST NOT have any effect on the formatted output of a _message_,
-nor be made available to function implementations.
+nor be made available to _function handlers_.
> [!IMPORTANT]
>
@@ -77,50 +78,92 @@ At a minimum, it includes:
This is often determined by a user-provided argument of a formatting function call.
- The _function registry_,
- providing the implementations of the functions referred to by message _functions_.
+ providing the _function handlers_ of the functions referred to by message _functions_.
- Optionally, a fallback string to use for the message if it is not _valid_.
Implementations MAY include additional fields in their _formatting context_.
-## Expression and Markup Resolution
+## Resolved Values
-_Expressions_ are used in _declarations_ and _patterns_.
-_Markup_ is only used in _patterns_.
+A **_resolved value_** is the result of resolving a _text_, _literal_, _variable_, _expression_, or _markup_.
+The _resolved value_ is determined using the _formatting context_.
+The form of the _resolved value_ is implementation-defined.
-In a _declaration_, the resolved value of the _expression_ is bound to a _variable_,
-which is available for use by later _expressions_.
-Since a _variable_ can be referenced in different ways later,
-implementations SHOULD NOT immediately fully format the value for output.
+In a _declaration_, the _resolved value_ of an _expression_ is bound to a _variable_,
+which makes it available for use in later _expressions_ and _markup_ _options_.
+
+> For example, in
+> ```
+> .input {$a :number minimumFractionDigits=3}
+> .local $b = {$a :integer notation=compact}
+> .match $a
+> 0 {{The value is zero.}}
+> * {{In compact form, the value {$a} is rendered as {$b}.}}
+> ```
+> the _resolved value_ bound to `$a` is used as the _operand_
+> of the `:integer` _function_ when resolving the value of the _variable_ `$b`,
+> as a _selector_ in the `.match` statement,
+> as well as for formatting the _placeholder_ `{$a}`.
In an _input-declaration_, the _variable_ operand of the _variable-expression_
identifies not only the name of the external input value,
-but also the _variable_ to which the resolved value of the _variable-expression_ is bound.
+but also the _variable_ to which the _resolved value_ of the _variable-expression_ is bound.
-In a _pattern_, the resolved value of an _expression_ or _markup_ is used in its _formatting_.
+In a _pattern_, the _resolved value_ of an _expression_ or _markup_ is used in its _formatting_.
-The form that resolved values take is implementation-dependent,
+The form that _resolved values_ take is implementation-dependent,
and different implementations MAY choose to perform different levels of resolution.
-> For example, the resolved value of the _expression_ `{|0.40| :number style=percent}`
-> could be an object such as
+> While this specification does not require it,
+> a _resolved value_ could be implemented by requiring each _function handler_ to
+> return a value matching the following interface:
>
+> ```ts
+> interface MessageValue {
+> formatToString(): string
+> formatToX(): X // where X is an implementation-defined type
+> getValue(): unknown
+> resolvedOptions(): { [key: string]: MessageValue }
+> selectKeys(keys: string[]): string[]
+> }
> ```
-> { value: Number('0.40'),
-> formatter: NumberFormat(locale, { style: 'percent' }) }
-> ```
>
-> Alternatively, it could be an instance of an ICU4J `FormattedNumber`,
-> or some other locally appropriate value.
+> With this approach:
+> - An _expression_ could be used as a _placeholder_ if
+> calling the `formatToString()` or `formatToX()` method of its _resolved value_
+> did not emit an error.
+> - A _variable_ could be used as a _selector_ if
+> calling the `selectKeys(keys)` method of its _resolved value_
+> did not emit an error.
+> - Using a _variable_, the _resolved value_ of an _expression_
+> could be used as an _operand_ or _option_ value if
+> calling the `getValue()` method of its _resolved value_ did not emit an error.
+> In this use case, the `resolvedOptions()` method could also
+> provide a set of option values that could be taken into account by the called function.
+>
+> Extensions of the base `MessageValue` interface could be provided for different data types,
+> such as numbers or strings,
+> for which the `unknown` return type of `getValue()` and
+> the generic `MessageValue` type used in `resolvedOptions()`
+> could be narrowed appropriately.
+> An implementation could also allow `MessageValue` values to be passed in as input variables,
+> or automatically wrap each variable as a `MessageValue` to provide a uniform interface
+> for custom functions.
+
+## Expression and Markup Resolution
+
+_Expressions_ are used in _declarations_ and _patterns_.
+_Markup_ is only used in _patterns_.
Depending on the presence or absence of a _variable_ or _literal_ operand and a _function_,
-the resolved value of the _expression_ is determined as follows:
+the _resolved value_ of the _expression_ is determined as follows:
If the _expression_ contains a _function_,
-its resolved value is defined by _function resolution_.
+its _resolved value_ is defined by _function resolution_.
Else, if the _expression_ consists of a _variable_,
-its resolved value is defined by _variable resolution_.
+its _resolved value_ is defined by _variable resolution_.
An implementation MAY perform additional processing
when resolving the value of an _expression_
that consists only of a _variable_.
@@ -139,9 +182,9 @@ that consists only of a _variable_.
> the pattern included the function `:datetime` with some set of default options.
Else, the _expression_ consists of a _literal_.
-Its resolved value is defined by _literal resolution_.
+Its _resolved value_ is defined by _literal resolution_.
-> **Note**
+> [!NOTE]
> This means that a _literal_ value with no _function_
> is always treated as a string.
> To represent values that are not strings as a _literal_,
@@ -156,25 +199,40 @@ Its resolved value is defined by _literal resolution_.
### Literal Resolution
-The resolved value of a _text_ or a _literal_ is
+The _resolved value_ of a _text_ or a _literal_ contains
the character sequence of the _text_ or _literal_
after any character escape has been converted to the escaped character.
When a _literal_ is used as an _operand_
or on the right-hand side of an _option_,
-the formatting function MUST treat its resolved value the same
+the formatting function MUST treat its _resolved value_ the same
whether its value was originally a _quoted literal_ or an _unquoted literal_.
> For example,
> the _option_ `foo=42` and the _option_ `foo=|42|` are treated as identical.
-The resolution of a _text_ or _literal_ MUST resolve to a string.
+
+> For example, in a JavaScript formatter
+> the _resolved value_ of a _text_ or a _literal_ could have the following implementation:
+>
+> ```ts
+> class MessageLiteral implements MessageValue {
+> constructor(value: string) {
+> this.formatToString = () => value;
+> this.getValue = () => value;
+> }
+> resolvedOptions: () => ({});
+> selectKeys(_keys: string[]) {
+> throw Error("Selection on unannotated literals is not supported");
+> }
+> }
+> ```
### Variable Resolution
To resolve the value of a _variable_,
its _name_ is used to identify either a local variable or an input variable.
-If a _declaration_ exists for the _variable_, its resolved value is used.
+If a _declaration_ exists for the _variable_, its _resolved value_ is used.
Otherwise, the _variable_ is an implicit reference to an input value,
and its value is looked up from the _formatting context_ _input mapping_.
@@ -191,8 +249,8 @@ the following steps are taken:
1. If the _expression_ includes an _operand_, resolve its value.
If this fails, use a _fallback value_ for the _expression_.
2. Resolve the _identifier_ of the _function_ and, based on the starting sigil,
- find the appropriate function implementation to call.
- If the implementation cannot find the function,
+ find the appropriate _function handler_ to call.
+ If the implementation cannot find the _function handler_,
or if the _identifier_ includes a _namespace_ that the implementation does not support,
emit an _Unknown Function_ error
and use a _fallback value_ for the _expression_.
@@ -202,108 +260,63 @@ the following steps are taken:
3. Perform _option resolution_.
-4. Call the function implementation with the following arguments:
+4. Call the _function handler_ with the following arguments:
- The current _locale_.
- The resolved mapping of _options_.
- - If the _expression_ includes an _operand_, its resolved value.
+ - If the _expression_ includes an _operand_, its _resolved value_.
The form that resolved _operand_ and _option_ values take is implementation-defined.
- A _declaration_ binds the resolved value of an _expression_
- to a _variable_.
- Thus, the result of one _function_ is potentially the _operand_
- of another _function_,
- or the value of one of the _options_ for another function.
- For example, in
- ```
- .input {$n :number minimumIntegerDigits=3}
- .local $n1 = {$n :number maximumFractionDigits=3}
- ```
- the value bound to `$n` is the
- resolved value used as the _operand_
- of the `:number` _function_
- when resolving the value of the _variable_ `$n1`.
-
- Implementations that provide a means for defining custom functions
- SHOULD provide a means for function implementations
- to return values that contain enough information
- (e.g. a representation of
- the resolved _operand_ and _option_ values
- that the function was called with)
- to be used as arguments to subsequent calls
- to the function implementations.
- For example, an implementation might define an interface that allows custom function implementation.
- Such an interface SHOULD define an implementation-specific
- argument type `T` and return type `U`
- for implementations of functions
- such that `U` can be coerced to `T`.
- Implementations of a _function_ SHOULD emit a
- _Bad Operand_ error for _operands_ whose resolved value
- or type is not supported.
-
-> [!NOTE]
-> The behavior of the previous example is
-> currently implementation-dependent. Supposing that
-> the external input variable `n` is bound to the string `"1"`,
-> and that the implementation formats to a string,
-> the formatted result of the following message:
->
-> ```
-> .input {$n :number minimumIntegerDigits=3}
-> .local $n1 = {$n :number maximumFractionDigits=3}
-> {{What is the value of: {$n1}}}
-> ```
->
-> is currently implementation-dependent.
-> Depending on whether the options are preserved
-> between the resolution of the first `:number` _function_
-> and the resolution of the second `:number` _function_,
-> a conformant implementation
-> could produce either "001.000" or "1.000"
->
-> Each function **specification** MAY have
-> its own rules to preserve some options in the returned structure
-> and discard others.
-> In instances where a function specification does not determine whether an option is preserved or discarded,
-> each function **implementation** of that specification MAY have
-> its own rules to preserve some options in the returned structure
-> and discard others.
->
-
-> [!NOTE]
-> During the Technical Preview,
-> feedback on how the registry describes
-> the flow of _resolved values_ and _options_
-> from one _function_ to another,
-> and on what requirements this specification should impose,
-> is highly desired.
-
- An implementation MAY pass additional arguments to the function,
+ An implementation MAY pass additional arguments to the _function handler_,
as long as reasonable precautions are taken to keep the function interface
simple and minimal, and avoid introducing potential security vulnerabilities.
- An implementation MAY define its own functions.
- An implementation MAY allow custom functions to be defined by users.
-
- Function access to the _formatting context_ MUST be minimal and read-only,
- and execution time SHOULD be limited.
-
- Implementation-defined _functions_ SHOULD use an implementation-defined _namespace_.
-
5. If the call succeeds,
resolve the value of the _expression_ as the result of that function call.
If the call fails or does not return a valid value,
emit the appropriate _Message Function Error_ for the failure.
- Implementations MAY provide a mechanism for the _function_ to provide
+ Implementations MAY provide a mechanism for the _function handler_ to provide
additional detail about internal failures.
Specifically, if the cause of the failure was that the datatype, value, or format of the
_operand_ did not match that expected by the _function_,
- the _function_ might cause a _Bad Operand_ error to be emitted.
+ the _function_ SHOULD cause a _Bad Operand_ error to be emitted.
- In all failure cases, use the _fallback value_ for the _expression_ as the resolved value.
+ In all failure cases, use the _fallback value_ for the _expression_ as its _resolved value_.
+
+#### Function Handler
+
+A **_function handler_** is an implementation-defined process
+such as a function or method
+which accepts a set of arguments and returns a _resolved value_.
+A _function handler_ is required to resolve a _function_.
+
+An implementation MAY define its own functions and their handlers.
+An implementation MAY allow custom functions to be defined by users.
+
+Implementations that provide a means for defining custom functions
+MUST provide a means for _function handlers_
+to return _resolved values_ that contain enough information
+to be used as _operands_ or _option_ values in subsequent _expressions_.
+
+The _resolved value_ returned by a _function handler_
+MAY be different from the value of the _operand_ of the _function_.
+It MAY be an implementation specified type.
+It is not required to be the same type as the _operand_.
+
+A _function handler_ MAY include resolved options in its _resolved value_.
+The resolved options MAY be different from the _options_ of the function.
+
+A _function handler_ SHOULD emit a
+_Bad Operand_ error for _operands_ whose _resolved value_
+or type is not supported.
+
+_Function handler_ access to the _formatting context_ MUST be minimal and read-only,
+and execution time SHOULD be limited.
+
+Implementation-defined _functions_ SHOULD use an implementation-defined _namespace_.
#### Option Resolution
@@ -313,7 +326,7 @@ For each _option_:
- Resolve the _identifier_ of the _option_.
- If the _option_'s right-hand side successfully resolves to a value,
- bind the _identifier_ of the _option_ to the resolved value in the mapping.
+ bind the _identifier_ of the _option_ to the _resolved value_ in the mapping.
- Otherwise, bind the _identifier_ of the _option_ to an unresolved value in the mapping.
Implementations MAY later remove this value before calling the _function_.
(Note that an _Unresolved Variable_ error will have been emitted.)
@@ -326,7 +339,7 @@ This mapping can be empty.
Unlike _functions_, the resolution of _markup_ is not customizable.
-The resolved value of _markup_ includes the following fields:
+The _resolved value_ of _markup_ includes the following fields:
- The type of the markup: open, standalone, or close
- The _identifier_ of the _markup_
@@ -336,7 +349,7 @@ The resolution of _markup_ MUST always succeed.
### Fallback Resolution
-A **_fallback value_** is the resolved value for an _expression_ that fails to resolve.
+A **_fallback value_** is the _resolved value_ for an _expression_ that fails to resolve.
An _expression_ fails to resolve when:
@@ -400,6 +413,23 @@ _Option_ _identifiers_ and values are not included in the _fallback value_.
_Pattern selection_ is not supported for _fallback values_.
+> For example, in a JavaScript formatter
+> the _fallback value_ could have the following implementation,
+> where `source` is one of the above-defined strings:
+>
+> ```ts
+> class MessageFallback implements MessageValue {
+> constructor(source: string) {
+> this.formatToString = () => `{${source}}`;
+> this.getValue = () => undefined;
+> }
+> resolvedOptions: () => ({});
+> selectKeys(_keys: string[]) {
+> throw Error("Selection on fallback values is not supported");
+> }
+> }
+> ```
+
## Pattern Selection
If the _message_ being formatted is not _well-formed_ and _valid_,
@@ -478,17 +508,17 @@ as long as its observable behavior matches the results of the method defined her
First, resolve the values of each _selector_:
-1. Let `res` be a new empty list of resolved values that support selection.
+1. Let `res` be a new empty list of _resolved values_ that support selection.
1. For each _selector_ `sel`, in source order,
- 1. Let `rv` be the resolved value of `sel`.
+ 1. Let `rv` be the _resolved value_ of `sel`.
1. If selection is supported for `rv`:
1. Append `rv` as the last element of the list `res`.
1. Else:
- 1. Let `nomatch` be a resolved value for which selection always fails.
+ 1. Let `nomatch` be a _resolved value_ for which selection always fails.
1. Append `nomatch` as the last element of the list `res`.
1. Emit a _Bad Selector_ error.
-The form of the resolved values is determined by each implementation,
+The form of the _resolved values_ is determined by each implementation,
along with the manner of determining their support for selection.
### Resolve Preferences
@@ -502,9 +532,9 @@ Next, using `res`, resolve the preferential order for all message keys:
1. Let `key` be the `var` key at position `i`.
1. If `key` is not the catch-all key `'*'`:
1. Assert that `key` is a _literal_.
- 1. Let `ks` be the resolved value of `key` in Unicode Normalization Form C.
+ 1. Let `ks` be the _resolved value_ of `key` in Unicode Normalization Form C.
1. Append `ks` as the last element of the list `keys`.
- 1. Let `rv` be the resolved value at index `i` of `res`.
+ 1. Let `rv` be the _resolved value_ at index `i` of `res`.
1. Let `matches` be the result of calling the method MatchSelectorKeys(`rv`, `keys`)
1. Append `matches` as the last element of the list `pref`.
@@ -535,7 +565,7 @@ filter the list of _variants_ to the ones that match with some preference:
1. If `key` is the catch-all key `'*'`:
1. Continue the inner loop on `pref`.
1. Assert that `key` is a _literal_.
- 1. Let `ks` be the resolved value of `key`.
+ 1. Let `ks` be the _resolved value_ of `key`.
1. Let `matches` be the list of strings at index `i` of `pref`.
1. If `matches` includes `ks`:
1. Continue the inner loop on `pref`.
@@ -561,7 +591,7 @@ Finally, sort the list of variants `vars` and select the _pattern_:
1. Let `key` be the `tuple` _variant_ key at position `i`.
1. If `key` is not the catch-all key `'*'`:
1. Assert that `key` is a _literal_.
- 1. Let `ks` be the resolved value of `key`.
+ 1. Let `ks` be the _resolved value_ of `key`.
1. Let `matchpref` be the integer position of `ks` in `matches`.
1. Set the `tuple` integer value as `matchpref`.
1. Set `sortable` to be the result of calling the method `SortVariants(sortable)`.
@@ -711,7 +741,7 @@ one {{Category match for {$count}}}
After _pattern selection_,
each _text_ and _placeholder_ part of the selected _pattern_ is resolved and formatted.
-Resolved values cannot always be formatted by a given implementation.
+_Resolved values_ cannot always be formatted by a given implementation.
When such an error occurs during _formatting_,
an appropriate _Message Function Error_ is emitted and
a _fallback value_ is used for the _placeholder_ with the error.
@@ -721,8 +751,8 @@ appropriate data type or structure. Some examples of these include:
- A single string concatenated from the parts of the resolved _pattern_.
- A string with associated attributes for portions of its text.
-- A flat sequence of objects corresponding to each resolved value.
-- A hierarchical structure of objects that group spans of resolved values,
+- A flat sequence of objects corresponding to each _resolved value_.
+- A hierarchical structure of objects that group spans of _resolved values_,
such as sequences delimited by _markup-open_ and _markup-close_ _placeholders_.
Implementations SHOULD provide _formatting_ result types that match user needs,
@@ -837,7 +867,7 @@ The _Default Bidi Strategy_ is defined as follows:
These correspond to the message having left-to-right directionality,
right-to-left directionality, and to the message's directionality not being known.
1. For each _expression_ `exp` in _pattern_:
- 1. Let `fmt` be the formatted string representation of the resolved value of `exp`.
+ 1. Let `fmt` be the formatted string representation of the _resolved value_ of `exp`.
1. Let `dir` be the directionality of `fmt`,
one of « `'LTR'`, `'RTL'`, `'unknown'` », with the same meanings as for `msgdir`.
1. If `dir` is `'LTR'`:
diff --git a/spec/registry.md b/spec/registry.md
index d89b957055..a962ed09b7 100644
--- a/spec/registry.md
+++ b/spec/registry.md
@@ -1,7 +1,7 @@
# MessageFormat 2.0 Default Function Registry
-This section describes the functions which each implementation MUST provide
-to be conformant with this specification.
+This section describes the functions for which each implementation MUST provide
+a _function handler_ to be conformant with this specification.
Implementations MAY implement additional _functions_ or additional _options_.
In particular, implementations are encouraged to provide feedback on proposed
@@ -51,7 +51,7 @@ The function `:string` has no options.
#### Selection
When implementing [`MatchSelectorKeys(resolvedSelector, keys)`](/spec/formatting.md#resolve-preferences)
-where `resolvedSelector` is the resolved value of a _selector_
+where `resolvedSelector` is the _resolved value_ of a _selector_
and `keys` is a list of strings,
the `:string` selector function performs as described below.
@@ -88,7 +88,7 @@ the `:string` selector function performs as described below.
#### Formatting
-The `:string` function returns the string value of the resolved value of the _operand_.
+The `:string` function returns the string value of the _resolved value_ of the _operand_.
## Numeric Value Selection and Formatting
@@ -374,12 +374,12 @@ All other values produce a _Bad Operand_ error.
### Digit Size Options
Some _options_ of number _functions_ are defined to take a "digit size option".
-Implementations of number _functions_ use these _options_ to control aspects of numeric display
+The _function handlers_ for number _functions_ use these _options_ to control aspects of numeric display
such as the number of fraction, integer, or significant digits.
A "digit size option" is an _option_ value that the _function_ interprets
as a small integer value greater than or equal to zero.
-Implementations MAY define an upper limit on the resolved value
+Implementations MAY define an upper limit on the _resolved value_
of a digit size option option consistent with that implementation's practical limits.
In most cases, the value of a digit size option will be a string that
@@ -404,7 +404,7 @@ Number selection has three modes:
followed by an ordinal rule category if there is no explicit match
When implementing [`MatchSelectorKeys(resolvedSelector, keys)`](/spec/formatting.md#resolve-preferences)
-where `resolvedSelector` is the resolved value of a _selector_
+where `resolvedSelector` is the _resolved value_ of a _selector_
and `keys` is a list of strings,
numeric selectors perform as described below.
@@ -448,7 +448,7 @@ but a weaker match than any exact match _key_ value.
The rules for a given locale might not produce all of the keywords.
A given _operand_ value might produce different keywords depending on the locale.
-Apply the rules to the resolved value of the _operand_ and the relevant function _options_,
+Apply the rules to the _resolved value_ of the _operand_ and the relevant function _options_,
and return the resulting keyword.
If no rules match, return `other`.
@@ -554,7 +554,7 @@ or can use a collection of _field options_ (but not both) to control the formatt
output.
If both are specified, a _Bad Option_ error MUST be emitted
-and a _fallback value_ used as the resolved value of the _expression_.
+and a _fallback value_ used as the _resolved value_ of the _expression_.
> [!NOTE]
> The names of _options_ and their _values_ were derived from the
@@ -579,8 +579,6 @@ The function `:datetime` has these _style options_.
_Field options_ describe which fields to include in the formatted output
and what format to use for that field.
-The implementation may use this _function_ to configure which fields
-appear in the formatted output.
> [!NOTE]
> _Field options_ do not have default values because they are only to be used
diff --git a/spec/syntax.md b/spec/syntax.md
index 24ea52318f..a31c3f9215 100644
--- a/spec/syntax.md
+++ b/spec/syntax.md
@@ -97,7 +97,7 @@ Attempting to parse a _message_ that is not _valid_ will result in a _Data Model
A **_message_** is the complete template for a specific message formatting request.
-A **_variable_** is a _name_ associated to a resolved value.
+A **_variable_** is a _name_ associated to a _resolved value_.
An **_external variable_** is a _variable_
whose _name_ and initial value are supplied by the caller
@@ -195,7 +195,7 @@ An **_input-declaration_** binds a _variable_ to an external input va
The _variable-expression_ of an _input-declaration_
MAY include a _function_ that is applied to the external value.
-A **_local-declaration_** binds a _variable_ to the resolved value of an _expression_.
+A **_local-declaration_** binds a _variable_ to the _resolved value_ of an _expression_.
```abnf
declaration = input-declaration / local-declaration
@@ -379,7 +379,7 @@ match-statement = match 1*(s selector)
### Selector
-A **_selector_** is a _variable_ whose resolved value ranks or excludes the
+A **_selector_** is a _variable_ whose _resolved value_ ranks or excludes the
_variants_ based on the value of the corresponding _key_ in each _variant_.
The combination of _selectors_ in a _matcher_ thus determines
which _pattern_ will be used during formatting.
diff --git a/test/README.md b/test/README.md
index dabde2aa20..6fa50dfc50 100644
--- a/test/README.md
+++ b/test/README.md
@@ -84,8 +84,8 @@ its `Input`, `DecimalPlaces`, `FailsFormat`, and `FailsSelect` values are determ
1. Let `DecimalPlaces` be 0.
1. Let `FailsFormat` be `false`.
1. Let `FailsSelect` be `false`.
-1. Let `arg` be the resolved value of the _expression_ _operand_.
-1. If `arg` is the resolved value of an _expression_
+1. Let `arg` be the _resolved value_ of the _expression_ _operand_.
+1. If `arg` is the _resolved value_ of an _expression_
with a `:test:function`, `:test:select`, or `:test:format` _annotation_
for which resolution has succeeded, then
1. Let `Input` be the `Input` value of `arg`.
@@ -97,7 +97,7 @@ its `Input`, `DecimalPlaces`, `FailsFormat`, and `FailsSelect` values are determ
1. Let `Input` be the numerical value of `arg`.
1. Else,
1. Emit "bad-input" _Resolution Error_.
- 1. Use a _fallback value_ as the resolved value of the _expression_.
+ 1. Use a _fallback value_ as the _resolved value_ of the _expression_.
Further steps of this algorithm are not followed.
1. If the `decimalPlaces` _option_ is set, then
1. If its value resolves to a numerical integer value 0 or 1
@@ -105,7 +105,7 @@ its `Input`, `DecimalPlaces`, `FailsFormat`, and `FailsSelect` values are determ
1. Set `DecimalPlaces` to be the numerical value of the _option_.
1. Else if its value is not an unresolved value set by _option resolution_,
1. Emit "bad-option" _Resolution Error_.
- 1. Use a _fallback value_ as the resolved value of the _expression_.
+ 1. Use a _fallback value_ as the _resolved value_ of the _expression_.
1. If the `fails` _option_ is set, then
1. If its value resolves to the string `'always'`, then
1. Set `FailsFormat` to be `true`.
@@ -133,7 +133,7 @@ depends on its `Input`, `DecimalPlaces` and `FailsSelect` values.
When an _expression_ with a `:test:function` _annotation_ is assigned to a _variable_ by a _declaration_
and that _variable_ is used as an _option_ value,
-its resolved value is the `Input` value.
+its _resolved value_ is the `Input` value.
When `:test:function` is used as a _formatter_,
a _placeholder_ resolving to a value with a `:test:function` _expression_