parameterized translations strings;what is the solution?

P

Paul Elliott

How are parameterized translation strings commonly handled?

Suppose I need to create a string like:

"file %1 failed to open", where %1 exists at runtime, but I need to
create it in a way that can be internationalized.

If I do something like this

str = _("file ") + filename + _(" failed to open");

The string to be translated is broken into pieces and the translators
can see what is going on. Besides different languages have different
word order. You can't necessarily hack tranlated phrases from a
different language together in the same way that you do in the native
language. Some things need to be translated as a whole.

Also there is UTF-8 and unicode.

Bjarne Stroustrup properly points out that sprintf and format
are not typesafe.

So what is the solution?

Gtkmm documentation recommends the compose library, but
that seems to be included in almost no Linux distributions,
so that can not be commonly used.

What is the solution that is used everyday in the real world?
 
J

James Kanze

How are parameterized translation strings commonly handled?
Suppose I need to create a string like:
"file %1 failed to open", where %1 exists at runtime, but I need to
create it in a way that can be internationalized.
If I do something like this
str = _("file ") + filename + _(" failed to open");
The string to be translated is broken into pieces and the translators
can see what is going on. Besides different languages have different
word order. You can't necessarily hack tranlated phrases from a
different language together in the same way that you do in the native
language. Some things need to be translated as a whole.
Also there is UTF-8 and unicode.
Bjarne Stroustrup properly points out that sprintf and format
are not typesafe.

There are typesafe implementations of format. At least mine and
the one in Boost support the X/Open positional parameters as
well.
So what is the solution?

It depends on what the requirements are. For simple error
messages, it's often possible to organize them so that the
variable parts are more or less separate from the rest, and
there is at most one of them. So that while English, French and
German have different word orders:

std::cout << "The following file could not be opened: " <<
filename ;
std::cout << "Le fichier suivant n'a pas pu être ouvert : " <<
filename ;
std::cout << "Folgende Datei könnte nicht geöffnet werden: " <<
filename ;

works in all three.

Obviously, the operative phrase above is "for SIMPLE error
messages"---this solution only goes so far.

Historically, a long time ago, X/Open extended printf et al.
with positional parameters. (See the printf specification at
http://www.unix.org/single_unix_specification/.) This solution
has been ported to C++, first by me, later by Samuel Krempp, for
Boost. I've dropped all maintenance on my version, however,
because it doesn't really work in practice. Not only does word
order vary, but just about every other aspect of basic grammar:
in French or German, for example, adjectives need to reflect the
gender and number of the noun they modify, where as they are
invariable in English (and that's just the tip of the iceberg).
So you end up making compromizes like the above anyway, to avoid
the problem cases. In the end, the only solution I've found is
to define a function for each message, and put them into a
separate dynamically loaded object, and rewrite the code for the
functions for each language.
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

How are parameterized translation strings commonly handled?

Suppose I need to create a string like:

"file %1 failed to open", where %1 exists at runtime, but I need to
create it in a way that can be internationalized.

If I do something like this

str = _("file ") + filename + _(" failed to open");

The string to be translated is broken into pieces and the translators
can see what is going on. Besides different languages have different
word order. You can't necessarily hack tranlated phrases from a
different language together in the same way that you do in the native
language. Some things need to be translated as a whole.

Also there is UTF-8 and unicode.

Bjarne Stroustrup properly points out that sprintf and format
are not typesafe.

So what is the solution?

Gtkmm documentation recommends the compose library, but
that seems to be included in almost no Linux distributions,
so that can not be commonly used.

What is the solution that is used everyday in the real world?

If your main problem with printf() is the fact that it's not typesafe
the you can create your own, simplified version.

std::string createMessage(std::string msg, std::vector<std::string>
params);

Where msg would be on the form "Error %1 in %2: Failed to open %3.",
and params would be a list of strings such that the first string would
replace %1 in msg, the second would replace %2 and so on. This of
course requires that all parameters are converted to strings first and
added to a vector.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top