Translating Audacity/Writing Translatable Code

Marking Strings for Translation
In the source code, strings which are to be translated are written like so with a preceding underscore:

_("A string to be translated")

Such strings are detected by the 'xgettext' utility.

Strings which are not to be translated are written like so:

wxT("Don't translate this")

The wxT allows us to build Unicode versions of Audacity.

Dealing with Empty Strings
If a string needs to be empty it must not be marked for translation because this will create problems for gettext. This is wrong:

_("")

and this is correct:

wxT("")

Dealing with Long Strings
When strings get longer and span several lines we place a '\' at the end of each line, and continue immediately at the start of the next line. We have tried various other ways of dealing with long strings, but the other ways we've tried either don't work when compiling with Unicode, or defeat detection by xgettext.

So _("This is a very long string that is too long to fit on a single line, so we really have\ to do something about it"); is correct, as is just using a long line: _("This is a very long string that is too long to fit on a single line, so we really have to do something about it"); However, you mustn't put leading spaces or tabs on the continuation lines, because those extra spaces will be incorporated into the string sent for translation, as well as putting big blanks into the UI. So this is wrong: _("This is a very long string that is too long to fit on a single line, so we really have\           to do something about it"); and you mustn't do it in Audacity.

HTML Code
Some parts of the source code contain HTML code. Do not translate the HTML tags. Also in places, these embedded HTML strings have hyperlinks in Wiki syntax, like so:

Exporting to MP3

In the .po file, translators should translate the second part after the pipe (|), but not the first part. If at all possible the programmer should avoid putting HTML into translated strings, so that the HTML cannot become corrupted in the translation process.

Strings which change at runtime
To enable translation, rather than write strings like this: wxString(_("The file " )) + filename + _("could not be found.") use instead: wxString::Format(_("The file %s could not be found"), filename.c_str )

This gives the translator a complete sentence to work with, rather than the fragments "this file " and "could not be found.", which due to alphabetical sorting could be well separated in the .po file. It also means that if the file name needs to go somewhere else in string, all they have to do is move the %s in the string. You should also do this if you need to append a generated string to a translated string, e.g. rather than write _("Repeat ") + effectname; it should be done using a format string: wxString::Format(_("Repeat %s"), effectname); so that if a translator needs to translate it as "Do %s again" this is possible, which it wouldn't be with the first version of the code.

Menu Items
Some parts of the program source code denote menu items, like so: _("&Loop Play")

The ampersand (&) precedes that menu item's keyboard access key. This is shown as underlined in the Audacity menu, and allows Windows and Linux users to access that item without a mouse. Translators are encouraged to choose unique access keys for each translated item in the particular Audacity menu.

However, we don't use access keys in the Effect Menu because of the length of this built-in menu and because using access keys could prevent keyboard access to the optional effects underneath the divider which have no mechanism to add access keys. For similar reasons, don't use access keys in the Generate or Analyze menus either.

Format Strings
Finally, you will find many strings like "There were %d buffer underruns, last near %lf seconds."  The %d and %lf sequences mark places where numbers or names will be inserted into the string. The letters after the % sign determine the type of the variable that will be inserted, so it is vital not to change these % sequences. For example, after inserting values this string might become "There were 4 buffer underruns, last near 3.01 seconds." If you change the order of the % markers in a string, add 1$ after the percent sign that used to be first, 2$ after the percent sign that used to be second, and so on. For example:

_("The buffer underrun near %%2$lf seconds was the last of %%1$d.")

This ensures that the correct variable is inserted in the correct place in the string when the text is displayed.

See also the main Translating Audacity page for an overview of the process.