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

Clarification to default bidi strategy #968

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

catamorphism
Copy link
Collaborator

I'm submitting this PR to test my understanding of the spec. As I understand it (having read #918 ), the directionality of fmt could be determined by introspection on fmt, but the implementation is not required to do that introspection. Rather, the resolved value of the expression has both an "input directionality" (determined by the u:dir attribute) and an "output directionality" (determined by the function handler for the annotation, or with a default value for placeholders without annotation.) The "output directionality" is what is meant by "the directionality of fmt" in the original text.

I was confused because point 5 of #918 implies that no introspection is necessary, if I'm understanding correctly; but "the directionality of fmt" seems to imply that the directionality has to be determined from the formatted output, rather than from the metadata of that formatted output that is created by a function (that is, the "resolved value").

If I'm still confused, hopefully there's another edit that would make it clearer.

@aphillips
Copy link
Member

I was confused because point 5 of #918 implies that no introspection is necessary, if I'm understanding correctly; but "the directionality of fmt" seems to imply that the directionality has to be determined from the formatted output, rather than from the metadata of that formatted output that is created by a function (that is, the "resolved value").

Introspection of the formatted string makes no sense, because introspection would take the form of scanning for the first strong character (plus a bunch of details from UAX9) and this exactly identical to what using FSI gets you for free. Only now you are responsible for bugs. We don't prohibit your doing this, but there is no value to be derived from doing so.

What the strategy allows is for the function handler to have some say over the direction used. This will usually be the result of the function handler calling a function like uloc_isRightToLeft [doc] on the resolved locale of the formatter.

There's a fallback for what the direction of the placeholder is:

u:dir > fmt dir > msgdir

The fmt directionality might be considering the directionality of the resolved value of the operand (if there is an operand and if said operand has a direction) or it might just compute it as mentioned above.

Comment on lines 939 to 940
1. Let `dir` be the directionality of the _resolved value_ of `exp`,
one of « `'LTR'`, `'RTL'`, `'unknown'` », with the same meanings as for `msgdir`.
Copy link
Member

@aphillips aphillips Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Let `dir` be the directionality of the _resolved value_ of `exp`,
one of « `'LTR'`, `'RTL'`, `'unknown'` », with the same meanings as for `msgdir`.
1. Let `dir` be the directionality of `fmt`,
one of « `'LTR'`, `'RTL'`, `'unknown'` », with the same meanings as for `msgdir`.
> [!NOTE]
> `dir` is usually computed from the locale of the formatter
> or from other information, such as the directionality of the _resolved value_ of `exp`,
> and not by introspecting the character sequence in `fmt`

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't take your suggestion exactly as-is, but let me know what you think about 58afcfa.

@aphillips aphillips added formatting LDML47 LDML 47 Release (Stable) labels Dec 6, 2024
Comment on lines 938 to 939
1. Let `fmt` be the formatted string representation of the _resolved value_ of `exp`.
1. Let `dir` be the directionality of `fmt`,
1. Let `dir` be `DIR(exp)`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The direction cannot be defined only from exp, as its resolved value also depends on the formatting context.

I'm not convinced that defining DIR() makes this algorithm clearer, as in the immediate context we're also reading "the formatted string representation of the resolved value of exp" as well as "the u:dir option of the resolved value of exp"

Something like this might be better:

   1. Let `resval` be the _resolved value_ of `exp`.
   1. Let `fmt` be the formatted string representation of `resval`.
   1. Let `dir` be the directionality of `resval`,
      one of « `'LTR'`, `'RTL'`, `'unknown'` », with the same meanings as for `msgdir`.
   1. Let the boolean value `isolate` be
      True if the `u:dir` _option_ of `resval` has a value other than `'inherit'`,
      or False otherwise.

And then reactoring the "The auxiliary function DIR..." paragraph into a non-normative note.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried to incorporate this, let me know what you think about the current version.

spec/formatting.md Outdated Show resolved Hide resolved
Comment on lines 967 to 985
> [!NOTE]
> A _resolved value_ is derived from an _expression_
> together with a _formatting context_.)
> An implementation can use
> a representation of _resolved values_ that tracks
> everything needed to determine the directionality
> of the formatted string representation
> of a _resolved value_.
> This can be accomplished by incorporating
> the `isolate` flag used in step 2(iii),
> as well as the separate directionality annotation
> (one of « `'LTR'`, `'RTL'`, `'unknown'` »),
> into the representation of _resolved values_.
> Each _function handler_ can have its own means
> for determining the directionality annotation
> on the _resolved value_ it returns.
> Alternately, an implementation could simply
> determine directionality
> based on the locale.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further consideration, does this perhaps belong more appropriately in the section defining resolved values?

Specifically, I think we ought to expand a bit the paragraph starting on line 133 with something like this:

 In a _pattern_, the _resolved value_ of an _expression_ or _markup_ is used in its _formatting_.
+To account for the _Default Bidi Strategy_,
+the _resolved value_ of each _expression_ _placeholder_
+SHOULD include information about the directionality of its formatted string representation,
+as well as information about whether its formatted representation
+requires isolation from the surrounding text.

With that in place, this note could be simplified quite a bit, or even left out entirely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty good, but I wouldn't limit it to the default bidi strategy, nor would I necessarily limit it to placeholders (other expressions might have a directionality so that the direction is commutative across assignments). Perhaps:

The resolved value of each expression
SHOULD include the string direction
of its formatted string representation,
as well as information about whether the message author
wants to suppress or require isolation from the surrounding message text,
such as is found in the Default Bidi Strategy.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that resolved value is an implementation-internal thing, and is therefore not expected to have public visibility during formatting. This means that attaching any normative requirements on it ought to be explicitly connected to some spec-defined consumer of that information, i.e. the Default Bidi Strategy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made these changes. Also modified the example MessageValue definition to show what the directionality methods could look like.

spec/formatting.md Outdated Show resolved Hide resolved
@@ -131,6 +131,13 @@ 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.

In a _pattern_, the _resolved value_ of an _expression_ or _markup_ is used in its _formatting_.
To support the _Default Bidi Strategy_,
the _resolved value_ of each _expression_ _placeholder_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @aphillips's suggestion.

Suggested change
the _resolved value_ of each _expression_ _placeholder_
the _resolved value_ of each _expression_

@@ -146,6 +153,8 @@ and different implementations MAY choose to perform different levels of resoluti
> getValue(): unknown
> resolvedOptions(): { [key: string]: MessageValue }
> selectKeys(keys: string[]): string[]
> directionality() : Dir // where Dir is an enum type, one of « `'LTR'`, `'RTL'`, `'unknown'` »
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to define a new type in order to communicate the intent here; this is TypeScript after all.

Suggested change
> directionality() : Dir // where Dir is an enum type, one of « `'LTR'`, `'RTL'`, `'unknown'` »
> directionality(): 'LTR' | 'RTL' | 'unknown'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editorial formatting LDML47 LDML 47 Release (Stable)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants