@@ -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
2728These provide a great solution for options like ` minFractionDigits ` , ` dateStyle ` ,
2829or 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
3956As 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.
4259As 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
177194Attributes 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
182200Users may define their own attributes.
183201
184202Implementations 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-
189204Each attribute relates to a specific expression.
190205
191- An attribute's scope is limited to the expression to which it relates.
192-
193206Multiple attributes should be assignable to a single expression.
194207
195208Attributes 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,
214322require ` @ ` as a prefix for each attribute asignment.
215323Examples: ` @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,
218326including at least ` @dir ` and ` @locale ` .
219327
220328To 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
224332Allow expression attributes to influence the formatting context,
225333but 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
240347At 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
250357Comments 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
265361By allowing for multiple annotation functions on a single expression,
0 commit comments