Solving ambiguities

Sometimes it may happen that the same English message should be translated to two different messages in another language. A very wellknown ambiguity is the word "free", which can be like free beer or free speech. For instance, if you have two radiobutton groups describing a piece of software, and the first is about the software price and the second is about the software type, both may include the choice "free". The software price "free" would be translated to "gratis" in Danish, and the software type "free" would be translated to "fri" in Danish.

It is the programmer's responsibility to ensure, that one msgid only can result in one translation. Sometimes this fails - and then the translator has to report back that something has to be changed. There are several ways to solve this

Change words

The first solution is to change the words. Instead of the price option "free" you could give the option "$0", or you could write "free software" in one of the choices. Do a brainstorm and pick the best.

Adding spaces

You could add a space to one of the strings. This would give the translations "free"->"fri" and "free "->"gratis". Spaces are not visible in a radiogroup. If you use this technique inside the source code, you may want to remove the space before the space. In this case, you should provide a comment to the translator that the space needs to be preserved:

// Preserve the initial space in the translation.
dataset.FieldByName('Name').DisplayLabel:=copy(_(' Name'),2,maxint);

A good translator should always preserve leading and trailing spaces, but sometimes it is useful to give the translator a hint anyway.

Using domains

In some occasions, the solution to ambiguities can be to use several text domains. In the case with two radio button groups, you would exclude one of them from TranslateComponent() with TP_Ignore(), and then translate it separately afterwards using TranslateComponent(MyRadioButtonGroup,'separatedomain');.

Using trailing comments

Some people using trailing comments to include a comment within the msgid:

function stripafterdot(s:widestring):widestring;
var
  p:integer;
begin
  p:=pos('.',s);
  if p<>0 then
    s:=copy(s,1,p-1);
  Result:=s;
end;

myfield.DisplayLabel:=stripafterdot(_('Name.Displaylabel for the field named "name"'));

This solution requires the translator to know about this notation.