Skip to content

Commit bc43db8

Browse files
eemeliaphillipscatamorphism
authored
Add contextual options to expression-attributes design doc (#780)
* Add design doc for u:options * Apply changes to expression attributes design doc * Update exploration/u-options.md Co-authored-by: Eemeli Aro <[email protected]> * Apply suggestions from code review Co-authored-by: Addison Phillips <[email protected]> * Rename exploration/u-options.md -> exploration/contextual-options.md * Refactor as a change of the expression-attributes proposal * Apply suggestions from code review Co-authored-by: Addison Phillips <[email protected]> * Apply suggestions from code review Co-authored-by: Tim Chevalier <[email protected]> * Apply suggestions from code review Co-authored-by: Addison Phillips <[email protected]> * Add text explaining markup identifier uses --------- Co-authored-by: Addison Phillips <[email protected]> Co-authored-by: Tim Chevalier <[email protected]>
1 parent 5e46aaa commit bc43db8

File tree

1 file changed

+148
-52
lines changed

1 file changed

+148
-52
lines changed

exploration/expression-attributes.md

Lines changed: 148 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Status: **Proposed**
1313
<dt>Pull Requests</dt>
1414
<dd><a href="https://github.com/unicode-org/message-format-wg/pull/458">#458</a></dd>
1515
<dd><a href="https://github.com/unicode-org/message-format-wg/pull/772">#772</a></dd>
16+
<dd><a href="https://github.com/unicode-org/message-format-wg/pull/780">#780</a></dd>
1617
<dd><a href="https://github.com/unicode-org/message-format-wg/pull/792">#792</a></dd>
1718
</dl>
1819
</details>
@@ -27,17 +28,33 @@ Function options may influence the resolution, selection, and formatting of anno
2728
These provide a great solution for options like `minFractionDigits`, `dateStyle`,
2829
or other similar factors that influence the formatted result.
2930

30-
However, this single bag of options is not appropriate in all cases,
31-
in particular for attributes that pertain to the expression as a selector or a placeholder.
32-
For example, many of the [XLIFF 2 inline element] attributes don't really make sense as function options.
31+
Such options naturally correspond to function arguments or builder-style function constructors.
32+
Each option is specific to the associated API.
33+
Message authors, such as translators or developers, want consistent ways to do common tasks,
34+
such as providing hints to translation tools or overriding the locale,
35+
but, unless MessageFormat provides otherwise, cannot rely on implementations
36+
to consistently implement these.
37+
38+
To reduce the learning curve for users and improve consistency,
39+
it would be useful to have common options
40+
(generally those related to the formatting context)
41+
shared between all functions.
42+
43+
Separately from formatting concerns,
44+
it is often useful to attach other information to message expressions and markup.
45+
For example, presenting how an example value could be formatted can be very useful for the message's translation.
46+
Providing the original source representation of a placeholder may be essential for being able to format a non-MF2 message,
47+
if it has been transformed to MF2 to provide translators with a unified experience.
48+
As a specific example, many of the [XLIFF 2 inline element] attributes have no meaning
49+
to the function that they appear as options or annotations of.
3350

3451
[XLIFF 2 inline element]: http://docs.oasis-open.org/xliff/xliff-core/v2.1/os/xliff-core-v2.1-os.html#inlineelements
3552

3653
## Use-Cases
3754

3855
### User Story: Formatting Context Override
3956
As a message author, I want to override values in the _formatting context_ for a specific _expression_.
40-
I would like to do this in a consistent, effective manner that does not require a change to the
57+
I would like to do this in a consistent, effective manner that does not require a change to the
4158
_function_ or _markup_ support code in order to be effective.
4259
As far as the code is concerned, it just reads the value from the _formatting context_ normally.
4360

@@ -82,11 +99,11 @@ Some examples include:
8299
These may include an example, which is best represented in MF2 as an `@example=...` attribute.
83100

84101
- In #772, @eemeli calls out:
85-
> While working on [moz.l10n](https://github.com/mozilla/moz-l10n/),
86-
> a new Python localization library that uses the MF2 message and
87-
> [resource data model](https://github.com/eemeli/message-resource-wg/pull/16) to represent messages
88-
> from a number of different current syntaxes,
89-
102+
> While working on [moz.l10n](https://github.com/mozilla/moz-l10n/),
103+
> a new Python localization library that uses the MF2 message and
104+
> [resource data model](https://github.com/eemeli/message-resource-wg/pull/16) to represent messages
105+
> from a number of different current syntaxes,
106+
90107
Apple's Xcode supports localization of plural messages via `.stringsdict` XML files,
91108
which encode the plural variable's name as a `NSStringLocalizedFormatKey` value,
92109
where it appears as e.g. `%#@countOfFoo@` or similar.
@@ -98,31 +115,31 @@ At least the following expression attributes should be considered:
98115

99116
- Attributes with a formatting runtime impact:
100117

101-
- `id` — An identifier for the expression.
118+
- `id` — An identifier for the expression or markup.
102119
This is included in the formatted part,
103-
and allows the parts of an expression to be explicitly addressed.
120+
and allows each part of a message to be explicitly addressed.
104121

105122
> Example identifying two literal numbers:
106123
>
107124
> ```
108-
> The first number was {1234 :number @id=first} and the second {56789 :number @id=second}.
125+
> The first number was {1234 :number u:id=first} and the second {56789 :number u:id=second}.
109126
> ```
110127
111128
- `locale` — An override for the locale used to format the expression.
112-
Should be expressed as a non-empty sequence of BCP 47 language codes.
113129
114-
> Example embedding a French literal in an English message:
130+
> Example embedding a French date in an English message:
115131
>
116132
> ```
117-
> In French, “{|bonjour| @locale=fr}” is a greeting
133+
> In French, this date would be displayed as {|2024-05-06| :date u:locale=fr}
118134
> ```
119135
120136
- `dir` — An override for the LTR/RTL/auto directionality of the expression.
121137
122-
> Example explicitly isolating the directionality of a placeholder:
138+
> Example explicitly isolating the directionality of a placeholder
139+
> for a custom user-defined function:
123140
>
124141
> ```
125-
> Welcome, {$username @dir=auto}
142+
> Welcome, {$user :x:username u:dir=auto}
126143
> ```
127144
128145
- Attributes relevant for translators, tools, and other message operations,
@@ -149,10 +166,10 @@ At least the following expression attributes should be considered:
149166
whether the expression should or should not be localised.
150167
The values here correspond to those used for this property in HTML and elsewhere.
151168
152-
> Example embedding a non-translatable French literal in an English message:
169+
> Example embedding a non-translatable CLI command in a message:
153170
>
154171
> ```
155-
> In French, "{|bonjour| @locale=fr @translate=no}" is a greeting
172+
> Use {+code @translate=no}git ls-files{-code} to list all files in a repository.
156173
> ```
157174
158175
- `canCopy`, `canDelete`, `canOverlap`, `canReorder`, etc. — Flags supported by
@@ -176,20 +193,16 @@ including expressions without an annotation.
176193
177194
Attributes are distinct from function options.
178195
179-
Common attributes are defined by the MF2 specification
180-
and must be supported by all implementations.
196+
Common options or attributes should work the same way in different functions.
197+
198+
Special options or attributes should not conflict with other option names.
181199
182200
Users may define their own attributes.
183201
184202
Implementations may define their own attributes.
185203
186-
Some attributes may have an effect on the formatting of an expression.
187-
These cannot be defined within comments either within or outside a message.
188-
189204
Each attribute relates to a specific expression.
190205
191-
An attribute's scope is limited to the expression to which it relates.
192-
193206
Multiple attributes should be assignable to a single expression.
194207
195208
Attributes should be assignable to all expressions, not just placeholders.
@@ -204,38 +217,132 @@ the reserved/private-use rules will need to be adjusted to support attributes.
204217
205218
## Proposed Design
206219
207-
Add support for option-like `@key=value` attribute pairs at the end of any expression.
220+
Provide separate solutions for attributes that impact formatting,
221+
and those which do not,
222+
so that their namespaces are not comingled.
223+
224+
### Contextual options
225+
226+
Define the expected values and handling for the following options
227+
wherever they are used:
228+
229+
- `u:id` — A string value that is included as an `id` or other suitable value
230+
in the formatted part(s) for the placeholder,
231+
or any other structured formatted results.
232+
Ignored when formatting to a string, but could show up in error messages.
233+
- `u:locale` — A comma-delimited list of BCP 47 language tags,
234+
or an implementation-defined list of such tags.
235+
The tags are parsed, and they replace the _locale_
236+
defined in the _formatting context_ for this expression or markup.
237+
- `u:dir` — One of the string values `ltr`, `rtl`, or `auto`.
238+
Replaces the character directionality
239+
defined in the _formatting context_ for this expression or markup.
240+
241+
Error handling should be well defined for invalid values.
242+
243+
Additional restrictions could be imposed,
244+
e.g. requiring that each `u:id` is unique within a formatted message.
245+
246+
### Attributes
247+
248+
Add support for standalone `@key` as well as
249+
option-like `@key=value` attribute pairs with a literal value
250+
at the end of any expression or markup.
251+
252+
To distinguish attributes from options,
253+
require `@` as a prefix for each attribute asignment.
254+
Examples: `@translate=yes` and `@xliff:canCopy`.
255+
256+
Do not allow expression or markup attributes to influence the formatting context,
257+
or pass them to function handlers.
258+
259+
Drop variable values from the `attribute` rule:
260+
261+
```diff
262+
-attribute = "@" identifier [[s] "=" [s] (literal / variable)]
263+
+attribute = "@" identifier [[s] "=" [s] literal]
264+
```
265+
266+
## Alternatives Considered
267+
268+
### Do nothing
269+
270+
Continue to [caution](https://github.com/unicode-org/message-format-wg/blob/d38ff326d2381b3ef361e996c3431d1b251518d6/spec/syntax.md#attributes)
271+
function authors and other implementers away from creating function-specific or implementation-specific option values
272+
for the use cases presented above.
273+
274+
As should be obvious, the current situation is not tenable in the long term, and should be resolved.
275+
276+
### Do not provide any guidance
208277

209-
If the syntax for function options is extended to support flag-like options
210-
(see <a href="https://github.com/unicode-org/message-format-wg/issues/386">#386</a>),
211-
also extend expression attribute syntax to match.
278+
Do not include in the spec rules or guidance for declaring formatted part identifiers,
279+
or overriding the message locale or directionality.
212280

213-
To distinguish expression attributes from options,
281+
Do not define a common way to communicate information
282+
about an expression or markup to translators or tools.
283+
284+
This would mean not defining anything for default registry functions either,
285+
effectively requiring implementation-specific options like `icu:locale`.
286+
287+
Other functions could use their own definitions and handling for similar options,
288+
such as `locale` or `x:lang`.
289+
290+
Formatted parts for markup would not be able to directly include an identifier.
291+
292+
If not explicitly defined, less information will be provided to translators.
293+
294+
Function options may be used as a workaround,
295+
but each implementation and user will end up with different practices.
296+
297+
### Define options for default registry only
298+
299+
Do not define a common way to communicate information
300+
about an expression or markup to translators or tools.
301+
Instead, define at least `locale` and `dir` as options for default registry functions,
302+
with handling internal to each function implementation.
303+
304+
Other functions could use their own definitions and handling for similar options,
305+
such as `locale` or `x:lang`.
306+
307+
Formatted parts for markup would not be able to directly include an identifier.
308+
Implementations and users will need to invent their own practices with
309+
markup option names like `l10n-id`, `mf:id`, or `markupId`
310+
to refer to specific markup parts.
311+
312+
Do not define a common way to communicate information
313+
about an expression or markup to translators or tools.
314+
315+
### Use attributes also for contextual options
316+
317+
Add support for standalone `@key` as well as
318+
option-like `@key=value` attribute pairs with a literal or variable value
319+
at the end of any expression or markup.
320+
321+
To distinguish attributes from options,
214322
require `@` as a prefix for each attribute asignment.
215323
Examples: `@translate=yes` and `@locale=$exprLocale`.
216324

217-
Define the meaning and supported values of some expression attributes in the specification,
325+
Define the meaning and supported values of some attributes in the specification,
218326
including at least `@dir` and `@locale`.
219327

220328
To support later extension of the specified set of attributes while allowing user extensibility,
221-
suggest custom attribute names to include a U+002D Hyphen-Minus `-`.
222-
Examples: `@can-copy=no`, `@note-link=|https://...|`.
329+
require custom attribute names to be namespaced.
330+
Examples: `@xliff:can-copy=no`, `@note:link=|https://...|`.
223331

224332
Allow expression attributes to influence the formatting context,
225333
but do not directly pass them to user-defined functions.
226334

227-
## Alternatives Considered
335+
### Use function options, but with some suggested "discard" namespace like `_`
228336

229-
### Do not support expression attributes
337+
Examples: `_:translate=yes` and `_:example=|World|`.
230338

231-
If not explicitly defined, less information will be provided to translators.
339+
Requires reserving an additional namespace.
232340

233-
Function options may be used as a workaround,
234-
but each implementation and user will end up with different practices.
341+
Requires cooperation from implementers to ignore all options using the namespace.
235342

236-
### Use function options, but with some suggested prefix like `_`
343+
Makes defining namespaced attributes difficult.
237344

238-
A bit less bad than the previous, but still mixes attributes and options into the same namespace.
345+
Could be combined with the definition of `u:dir`, `u:locale`, and `u:id` contextual options.
239346

240347
At least a no-op function is required for otherwise unannotated expressions.
241348

@@ -249,17 +356,6 @@ esp. if a similar expression is used in multiple variants.
249356

250357
Comments should not influence the runtime behaviour of a formatter.
251358

252-
### Define `@attributes` as above, but explicitly namespace custom attributes
253-
254-
As namespacing may also be required for function names and function option names,
255-
and because we want to allow at least for custom function options
256-
to be definable on default formatters,
257-
the namespace rules for parts of the specification would end up differing.
258-
259-
By suggesting instead of requiring,
260-
we rely on our stability policy to guide implementations to keep clear of the namespace
261-
that may be claimed by later versions of the specification.
262-
263359
### Enable function chaining within a single expression
264360

265361
By allowing for multiple annotation functions on a single expression,

0 commit comments

Comments
 (0)