[Development] format-like tr()

Giuseppe D'Angelo giuseppe.dangelo at kdab.com
Thu Oct 24 18:54:43 CEST 2024


Il 24/10/24 18:23, Thiago Macieira ha scritto:
> On Thursday 24 October 2024 05:19:45 Pacific Daylight Time Giuseppe D'Angelo
> via Development wrote:
>>> 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.
>>
>>
>> It can't be the former: tr() needs to see the string that got extracted
>> for translation, in order to look it up in the translation database;
>> it's not supposed to see what you get after you did arbitrary
>> replacements in it.
> 
> It could be vformat, but that's clumsy. We'll probably have a front-end like
> 
>   trFormat(std::format_string<Args...>, Args &&...)
> 
>> I'm not sure what you mean here. We could entertain a trFormat()
>> function that does the translation _and_ the formatting in one go,
>> basically as a generalization/replacement of tr("...", n).arg(x, y).
> 
> I think that's the idea.
> 
>> Since formatting for plain `int` is already taken, like you said, we
>> will have to wrap `n` into a custom type of ours, and this will give us
>> a lot of freedom in how to define the formatting options in a way that
>> the translator can understand which argument identifies the plural:
> 
> It can be a simple class enum.
> 
> namespace Qt {
>      enum class Cardinality : qint64 {};
> }
> 
>>> trFormat("{} bought {:N} apple(s)", user, QTrQuantity(n));
> 
> trFormat("{} bought {:N} apples(s)", user, Qt::Cardinality(n));
> 
> Name TBD of course.
> 
>> This form can do compile-time checks on the passed arguments.
> 
> Indeed and we can force the formatter for the cardinality type to require the
> "N" or "n" in the formatting string. So if the user forgets, they get a
> compilation error.
> 
> We may need something slightly more complex than one letter, because other
> types may also have "n" and it would confuse tooling.
> 
> This is what I'm more worried about: telling the string-extraction tools that
> don't really understand C++ that this is a string with plurals. I don't know
> if they need to: is it acceptable for the translator to simply supply 2-5
> different forms? Or does the tooling -- and this is both .ts/.qm and .po/.mo
> files -- need to know that multiple forms are possible? Will Linguist allow the
> translator to enter 2-5 different translations?

Maybe I'm missing something, but the tooling does all of this already: 
lupdate extracts all the strings in tr() calls, and linguist allows me 
to add several translated forms, depending on the target language (for 
Italian: singular/plural; for Polish: singular, paucal, plural...).

What do we need to change here exactly?



> 
>>> trFormat("{} bought {:N, the amount of apples purchased} apple(s)", user,
>>> QTrQuantity(n));
>> We could even support int-based formatting options for the quantity, but
>> I'm not really sure if that's necessary; has anyone ever requested the
>> quantity to be printed in another base, or with padding 0s or so? Of
>> course, we need to weigh the flexibility against the possibility that
>> someone modifies these padding options or comments without realizing
>> that that's changing the translation DB (!).
> 
> That goes back to the discussion on whether translators should be allowed to
> change the formatting options. For numbers, the one thing that may make sense
> to change is the L (locale) flag. I don't know how languages with different
> number formats usually do this, but do they prefer their native digits for
> some sentences and the Latin ones for some others (likely technical)?

I'm actually thinking that we may be missing a use case: tr() can be 
called with a string that does NOT contain %n. In this case, the 
quantity parameter is only used to look up which plural form to 
translate to; the developer can then use e.g. arg() replacements, and 
with those, manage localization, precision and what not:

> tr("You bought a total of %L1 apple(s)", n).arg(n) // localized and pluralized

We likely need to find a way to support this as well?


My 2 c,
-- 
Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - Trusted Software Excellence

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4244 bytes
Desc: Firma crittografica S/MIME
URL: <http://lists.qt-project.org/pipermail/development/attachments/20241024/eed5527f/attachment.bin>


More information about the Development mailing list