Difference between revisions of "Translating"

From WineHQ Wiki
Jump to: navigation, search
(Fix category)
Line 214: Line 214:
To keep things simple the way Wine deals with such issues is to have someone make the dialog a bit larger so its widgets fit all translations.
To keep things simple the way Wine deals with such issues is to have someone make the dialog a bit larger so its widgets fit all translations.
[[Category:Writing and Design]]

Revision as of 21:58, 28 February 2016

How is Wine translated?

For translating the WineHQ.org website see TranslateWineHQ.

Nowadays Wine is completely localized through standard gettext PO files. If you check out the Wine source you will find these in the po/ directory. You can see the status of each translation along with a list of potential consistency and spelling issues on the Wine PO site.

Now for some more developer oriented details that you can skip:

All of the Wine dialogs and strings that need to be translated are stored in standard .rc Windows resource files. These are then compiled to the binary .res format using Wine's wrc compiler and linked with Wine's libraries and programs. These resources can contain both language-neutral and language-specific data. So the scheme is as follows. Wine's .rc resource files only contain the English resources. Then, during the compilation step, wrc looks up translations from the PO files for the strings it finds, generates additional translated binary resources. This way Wine ends up with resources for each language and then uses the most appropriate one at run time based on the current locale.

How to improve the translation?

Wine is an Open Source project, thus anyone can download the source code, modify the translations and send them to the wine-patches mailing list for inclusion into the official Wine tree.

Note that translating Wine to a new language from scratch can take many weeks. As for many other coding projects, it is recommended to send patches often, here this would be as soon as you have a fair set of translations you are happy with. This will reduce the risk and scope of conflicts you may have to resolve.

It will also help if you fix or report all issues you find in the English strings. Think of it as improving the 'English translation', and helping your fellow translators by fixing the source before they base their work on it.

Using Wine's source

It is recommended to build Wine from source, so you can test the translations. The recommended way to get the latest Wine source is to use Git. (See GitWine for a guide to Git.)

To build Wine you may want to first check Recommended Packages. On some 64-bit Linux distributions building Wine may be harder (check the WineOn64bit page), while on 32-bit systems all you need to do (usually) is

./configure && make depend && make

After building Wine you can run it from the source directory without installing it - e.g. run `~/wine-git/wine` or `~/wine-git/wine program.exe` (if the Wine sources are in `~/wine-git`). You can also start built-in programs by running e.g. `~/wine-git/wine notepad`. If you don't already have Wine installed, you can install it by running `make install` as root from the main source directory. Then the Wine you have built can be started as just `wine`. However, if you have installed another version of Wine don't run `make install` (unless you remove the other Wine first) as this may lead to conflicts.

Once the above works you can edit your PO file, recompile Wine and check that the new strings were taken into account.

Once you are satisfied with your translations, you can send them to wine-patches for inclusion into the official Wine Git. Read SubmittingPatches about how to do it and how to check if your patch got applied. Only send patch files (e.g. generated by `git format-patch`), one per mail, without compression (if the patch in your mail won't be recognized and applied by an automated script then the chances of it to be accepted are close to zero). Also note that because they contain non-Ascii characters, emails containing patches to PO files are at a higher risk than others of getting mangled. So you may want to make sure they go through ok by first sending a patch to yourself.

Using the Wine PO script

It is recommended for translators to get Wine's source and build it as described above. However if that does not work for you, a script is now available that will help you work on your translation. For instance, let's assume you want to work on the Hungarian translation:

  • First download the winepo script and save it as 'winepo'.
  • Make it executable by running 'chmod +x winepo' on the command line.
  • Then on the po/ page, identify which PO file corresponds to your language. For Hungarian this would be the 'hu.po' file.
  • So then you would run 'winepo hu.po'.
  • You can then edit the hu.po file to improve the translation. However make sure not to modify the 'hu.po.orig' file next to it.
  • From time to time run 'winepo hu.po' again to resynchronize with any changes that occurred on the Wine side.
  • This command will also generate a patch in 'hu.po.diff'.

When you feel you have something worth submitting, send the .diff file to the wine-patches mailing list.

Translating po files

PO files are regular UTF-8 text files which makes working with them straightforward. PO entries have generally the following form:

#: hhctrl.rc:62 winhlp32.rc:31
msgid "&Print..."
msgstr ""

The above means that the files 'hhctrl.rc' and 'winhlp32.rc' contain the English string '&Print...' on lines 62 and 31 respectively, and that it has not been translated yet since msgstr is empty. To translate that message just change the string after msgstr:

#: hhctrl.rc:62 winhlp32.rc:31
msgid "&Print..."
msgstr "&Imprimer..."

Note that some parts of the original string are important and must be preserved in the translation:

  • The ampersand '&' precedes the character to be used as the shortcut for this widget. So here, in an English locale pressing 'p' is the same as clicking on '&Print...'. The translation should usually specify its own shortcut, not necessarily for the same character. The tricky part is avoiding collisions between shortcuts. So here the French translator would have made sure none of the other dialog's widgets uses 'i' as its shortcut.
  • The ellipsis means additional information will be asked before the action is taken. So if you click on a 'Print...' button you know you will have an opportunity to cancel the action before anything is done. Not so if you click on a 'Print' button. So preserving the ellipsis in the translation is very important.
  • Also, double quotes must be escaped with a backslash so the string can be parsed by the PO tools.

Occasionally you will see entries like:

#: comdlg32.rc:195
#, fuzzy
msgid "Print"
msgstr "&Imprimer..."

This typically happens when a developer alters the original string so that your translation is now outdated, or when a developer adds a new string that looks like an already translated one. In the latter case this is how the PO tools suggest using that other translation as a basis for the new one. In any case a 'fuzzy' tag means the translation will no longer be used by Wine. It also means that before removing it you should carefully review and possibly update your translation as the changes are sometimes hard to notice. In this case one would obviously have to remove the ampersand and ellipsisis.

You can also see entries like:

#: foo.rc:123
#, fuzzy
#| msgid "old_string"
msgid "new_string"
msgstr "old_translation"

The #| msgid comment line indicates the previous msgid, which can help updating the translation. It should be removed along with the fuzzy line once the entry is updated.

Adding po message contexts

Message contexts are normally used to disambiguate messages for the same untranslated string. You can have several entries with the same untranslated string in a PO file, provided that they each have a different context.

Prerequisite: enable maintainer mode using

./configure --enable-maintainer-mode

1. Locate strings to be "altered"

Say for instance you have the following in your localized po file:

#: file1.rc:123 file2.rc:456
msgid "ambiguous terms"
msgstr "translation"

2. Find appropriate translations by checking the respective rc entries, e.g.

FOO "ambiguous terms" in file1.rc:123
BAR "ambiguous terms" in file2.rc:456

and determine their meaning/context (e.g. using some code browsing tools like cscope to find references; running the program is recommended, ...)

3. Add the messages contexts

  • The following syntax is used:
"translation" -> "#msgctxt#your context#translation"
  • You end up with sthg like
FOO "#msgctxt#context 1#ambiguous terms#" in file1.rc:123
  • Similarly
BAR "#msgctxt#context 2#ambiguous terms#" in file2.rc:456

4. Run make depend && make

5. Edit your po file to add the new translations, resulting in something like

#: file1.rc:123
msgctxt "context 1"
msgid "ambiguous terms"
msgstr "translation 1"


#: file2.rc:456
msgctxt "context 2"
msgid "ambiguous terms"
msgstr "translation 2"

6. Ideally, remove the "#, fuzzy" automatically inserted in the En_US.po reference file (and En.rc).

7. Run "make" again and test your changes.

In Wine the message context is sometimes also used to simply clarify the meaning of the string to be translated. Here are a couple of examples:

#: sane.rc:32
msgctxt "unit: bits"
msgid "b"
msgstr ""

#: wordpad.rc:283
msgctxt "accelerator Bold"
msgid "B"
msgstr ""

Dealing with strings that should not be translated

If a regular string resource should not be translated, first check to see if it would make sense to remove it from the resources. Similarly, if a label in a dialog should not be translated, it may mean that its content is in fact supplied at runtime. In such a case the label should be an empty string, and possibly have a comment next to it to identify its function (though normally its id, e.g. MSGBOX_IDTEXT, should be descriptive enough).

There are some cases where the above approaches don't work though. When set the string context to 'do not translate'. This will tell wrc to not include it in the PO files which will save much puzzling and work for the translators. Here are a couple of examples:

/* GetSizeMax is the name of a COM method so it makes no sense to translate it */
PUSHBUTTON  "#msgctxt#do not translate#&GetSizeMax", IDC_GETSIZEMAX_BUTTON, 6, 49, 50, 14

/* '&u', '&b' and '&d' are formatting directives and thus should not be translated.
 * It's also unlikely their order would need to be modified.
IDS_PRINT_FOOTER_TEMPLATE "#msgctxt#do not translate#&u&b&d"


Web-based translations systems

The Wine project would be very interested in making its PO files available on web-based community translations systems such as Pootle or Launchpad. Our hope is that this would make translating Wine even easier and engage new translators.

The reason why it has not happened yet is that all Wine contributions, including for translations, must be attributable to a specific author and that these tools don't make that possible yet. For more details see the wine-devel discussion here and here. Any contributions that would solve this issue would be very welcome.

Where can I find more help on translation?

Translating or localizing for those who are new to it can be daunting. The Localization Guide provides much help for those who are starting to translate for the first time.

How do I test my translation?

See also: Testing Languages.

If you translated a program you can (should) run it and check the translation. If instead you translated a DLL, and you don't know what programs use it, then it is good to at least check that the text in dialogs isn't too big for the control rectangles. This can be done by using a resource viewer/editor on the fake DLL. (Fake DLLs are created while Wine is being built. They have a .dll.fake extension, and they contain no code, only the resources.)

Resources inside such a file can be viewed by special programs. An example of such a program that I know of and that can be freely downloaded is ResHacker. It's an ANSI program, and cannot display UTF-8 correctly (although it worked for files converted from ISO-8859-1 if `#pragma code_page(65001)` is used). You can view all the dialogs to check if they display fine. Languages are on the third level of the tree on the left and are identified by numeric IDs. Such an ID can be computed as (language_id + 1024 * sublang_id) where the numerical language and sublanguage ids are defined in include/winnt.h

Another method to check your translation is to use a resource editor, e.g. XN Resource Editor to open the compiled resource files (.res) or even the dll (.dll.so). At least XN Resource Editor opens them both without any problems.

How to deal with truncated translations?

There is one hitch with the way Wine handles translations: it cannot resize the dialogs so the translated labels fit. This is because the Windows resource format relies entirely on hard-coded widgets positions and sizes so that the information needed to redo the dialog layout is missing. So sometimes a translation ends up being too large and is truncated on display.

To keep things simple the way Wine deals with such issues is to have someone make the dialog a bit larger so its widgets fit all translations.