> On 24 Oct 2024, at 12:29, Ivan Solovev <[email protected]> wrote:
>
> Hi Volker,
>
>> From my understanding, the idea behind the std::format framework would be
>> to have a “cardinality" type for which we can implement a special formatter,
>> allowing “whatever” to be in the format specification.
>
> True, but the custom formatter specialization is called when the argument id
> is already parsed.
> In your example:
>
> std::format("{0:Cardinality}", Cardinality{42});
>
> the std implementation parses the "{0:" part, extracting the argument id == 0,
> and then passes the rest of the string to the std::formatter<Cardinality>
> specialization.
>
> IIUC, Thiago suggested to use 'n' instead of the argument id.
What we need is a way to signal to translators: this placeholder in the string
represents the value that decides about which plural form to use. We can call
it whatever we want. Today we do that by putting a `%n` into the translatable
string; the tr() function replaces that with the number passed, but also
selects the appropriate plural form from the translation. So in Engineering
English
tr(“You have %n unread message(s)!”, “”, total);
the translator sees that %n is where the number goes and can position the %n
appropriately in the target languages, e.g. in German
Null: Du hast keine ungelesenen Nachrichten!
Singular: Du hast eine ungelesene Nachricht!
Plural: Du hast %n ungelesenen Nachrichten!
If we want to make that information available to the translator, then we need
to be able to do something in the source string. A very liberal formatter would
allow anything to appear between the `:` and the closing brace, e.g.:
std::format(“You have {:number of messages goes here} unread message(s)”);
is possible (updated my godbolt sandbox to do that).
Btw, where does the “tr” go? Is it going to be tr(std::format(…)) or
std::vformat(tr(…))?
In the former, we’d have to pass the value twice (once for std::format to
substitute, once for tr() to pick the right translation; the benefit is compile
time checks.
With the latter, we get no compile time services from std::format, but don’t
have to pass the value twice. Use tr()’s plural functionality and %n for it as
before. Otherwise, both sources and translations can muck around with
std::format-features as much as they like (it’s equivalent to tr(…).arg()).
Volker
--
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development