Further on the road to new i18n API for KDE4

Chusslove Illich caslav.ilic at gmx.net
Mon Mar 13 23:24:56 GMT 2006

In this new installment of the i18n API quest, let me start from a 
different side. In the talks we've had before, some issues of the current 
interface jumped out, which are by themselves worthy of nailing down 
properly, without regard to my original reason for wanting to change the 

One issue is the behavior of QString when it comes to placeholder (%1, 
%2,...) substitution. Probably due to performance and wider field of 
application of QString, this behavior is not what we'd like to have for 
i18n purposes.

First, by Qt docs, the substitution is undefined in some cases, like:

QString("%1 %1").arg("foo").arg("bar")

gives "foo bar" or "foo foo"? It gives "foo bar", while one would or could 
expect otherwise. And this undefined behaviour is actually exploited 
around KDE code.

Then, the substitution is recursive, ie.

i18n("%1, %2...").arg("foo").arg("bar")

will do the expected, but:

i18n("%1, %2...").arg("foo%1").arg("bar")

will produce "Blah foobar, blah %2...". The programmers are aware of this, 
so for the occasion when a placeholder within argument is likely to happen 
(eg. when argument comes from external source, like URL), they would use 
QString's grouping arg() method:

i18n("%1, %2...").arg("foo%1", "bar")

Since this is something to think about, it is certainly easily forgotten. 
And if one of these arguments is a number, programmer additionaly has to 
use explicit conversion:

i18n("%1, %2...").arg("foo", QString::number(10))

Which brings us to second issue, the number formatting. Few days ago, on 
the kde-i18n-doc someone finally raised the question of localized numbers, 
and we are not talking only dots or commas here, but also different 

With respect to this, Qt offers new %1L placeholders, for localized 
numbers, but I don't know how far these go. And even if it is just what we 
need, it is still a pain to put the L's where they should go. The other 
possibility is to always use KDE's number formatters from KLocale, but 
that is yet even greater pain :) So, count both out for large scale 
introduction -- we need something automatic.

The solution, as of now, is to introduce new specialized class, the 
KLocalizedString. To fascilitate extraction by Gettext, it could only be 
instantaniated through friendly wrapper functions, which for the moment 
I'll call ki18n. It would be used like this:

ki18n("%1, %2...").argf("foo%1").argf(10).toString()

which would yield "foo%1, 10-in-your-own-digits...".

argf() methods would simply store arguments inside the class instance, and 
the substitution of placeholders would go at one pass in toString(); 
argf() methods for numbers would call within them KDE's number formatters. 
I use name argf() instead of arg(), as they are going to be operationg 
differently from QString's arg().

We might stop here, but I assume that the toString() to finalize *each* 
i18n call is an overhead which wouldn't be looked upon nicely. So, we 
could also add function template calls up to some number of arguments, 

template <typname T1, typname T2>
inline QString i18n (const char *msgid, const T1 &a1, const T1 &a2) {
    return ki18n(text).arg(a1).arg(a2).toString();

so that one can use simply and finally:

i18n("%1, %2...", "foo%1", 10);

The additional benefit of using these templates would be that agreement 
between placeholders and arguments could be easily checked by code 
scanning scripts. One would than use the ki18n().argf()...toString() 
notation only for messages with many arguments, or when it is very 
convinient to supply an argument at a later point in code.

The (slight?) problem with templates is that context and plural versions 
would have to have different names, like i18nc and i18np (or longer 

Thoughts, comments? I already have code conversion scripts for 
semi-automatic conversion to new API, and I've tested the system on KDE 
3.5 branch code (ie. kdelibs and kdebase converted and compiled).

Chusslove Illich (Часлав Илић)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20060314/278b5969/attachment.sig>

More information about the kde-core-devel mailing list