Translator Guide

Virgil Dupras edited this page May 10, 2015 · 3 revisions

dupeGuru doesn't support your language, or supports it poorly? You can help by adding or improving a translation. There are two major areas of translation: the application itself and the help file.

Getting the source

If you translate the help document or if you don't use Transifex (see below), you'll need to get the latest version of the source. You can get it by cloning the repository. If you don't have Git installed you can download the source from this very website, by clicking on "Download ZIP". Note that if you download it manually, you'll also have to download two sub-repositories, hscommon, cocoalib and qtlib.

Being able to build from source is better. Gathering requirements to build dupeGuru from source is not the easiest thing in the world, especially for non-developers, but it's much better (although not required) if you're able to build it yourself. This way, you'll be able to see your translation "live" for yourself and make adjustments if needed.

Application Translation

dupeGuru's localizations are in "gettext" format, in ".po" files. These files are in subfolders called "locale". There are 4 "locale" folders within the dupeGuru project: One directly at the root of the dupeGuru project and the three others within its subprojects "hscommon", "cocoalib" and "qtlib". To completely translate dupeGuru a translation has to be added in all these "locale" folders.

The Transifex option

The instructions below might be a bit daunting for the person who isn't familiar with programming, source files and other whatnots. This is why I've recently started to use Transifex. Alternatively to reading all that documentation below, you can create an account in Transifex and start translating dupeGuru on this page. Transifex has an easy-to-use interface that doesn't need much explanations. The only thing you'll need to remember is the par about placeholders like "{}" or "%s" (you need to keep them intact).

Which files to work on?

If you're updating a translation, you'll first have to locate the subfolder in "locale" that corresponds to your language ("fr" for french, "cs" for czech, "it" for italian etc.). In this folder, there's a "LC_MESSAGES" folder and in that folder, there are ".po" files. These are the files you'll work on.

If you're creating a new translation, work with the ".pot" files at the root of the "locale" folder. Be aware that even if you're creating a new translation, it's possible that a translation for your language is already present in hscommon, cocoalib and qtlib because these subprojects are shared among all HS apps. In this case, you'll create a new translation for dupeGuru, but you'll just update the 3 sub-translations.

.po files syntax

The .po files syntax is rather simple. For each string to translate, there's first a comment describing where in the code is that string, and then there's a "msgid" line with the english string text to it and then there's a "msgstr" line with the translated string next to it. Here's an example:

#: core/
msgid "My name is John"
msgstr "Mon nom est John"

When an entry isn't translated yet, the "msgstr" line will be empty like this:

#: core/
msgid "My name is John"
msgstr ""

Therefore, if you want to update an existing translation, look for empty "msgstr" lines and fill them.

Multi-lines, escapes, placeholders

Long strings can span over multiple lines. In these cases, the string is simply closed with a quote and continues on the next line. Normally, when a strings spans multiple line, the first line is empty to indicate multiple lines. Example:

#: core/
msgid ""
"This sentence is spanning "
"one more than one line"
msgstr ""
"Cette phrase est contenue "
"sur plus d'une ligne"

Line breaks is something very important in a program, so here's something important to keep in mind: Spanning on multiple lines doesn't introduce a line break in the string. It's just there to make it more readable. To add a line break, the "\n" character has to be introduced:

#: core/
msgid ""
"This sentence contains\n"
"a line break"
msgstr ""
"Cette phrase contient\n"
"un changement de ligne"

The quote character is also special. If a string contains a quote character, it has to be escaped with a backslash:

#: core/
msgid "My name is \"John\""
msgstr "Mon nom est \"John\""

Placeholders and newlines should be kept intact. Placehoders are special character sequences like "{}" or "%s" that are replaced during the execution of the program. It's very important that they stay intact and in the correct position in the string. Newlines should stay too. They're represented by "\n".

Also be aware that in several places, it's important to keep strings short because there's not enough space in the button or label or whatever to accommodate long strings. When you send me your translation, I'll let you know if some strings are too long so you can give me an abbreviated version, but it's better if you're already aware of this limitation.

Rule of thumb: Just copy/paste msgid

All these rules in the previous section are rather complex, but the fact of the matter is that you don't really need to know them. The "msgid" part of the translation already contains all the special stuff in it, so what you can do is simply to copy/paste the "msgid" part, replace "msgid" with "msgstr" and translate the english string while trying to keep the stuff that looks weird intact.


If your text editor lets you choose an encoding to save your file to, make sure that you use UTF-8. It will make my life much easier.

See the results live

To see the results of your translation, you have to be able to build dupeGuru from source. Then, the steps to follow depend on the situation.


If you've done the translation on Transifex, you'll have to pull those translations into dupeGuru using the transifex client. You can install it with those steps:

  1. Make sure that dupeGuru's virtualenv is active: . env/bin/activate.
  2. pip install transifex-client

Then, you can pull translations update with tx pull -a

Existing language

If the language you're working on is already present in dupeGuru, things are simple. You simply have to build dupeGuru with python followed by python and you'll be able to see your changes live.

New language

If the language you're working on is new, things are a bit more complicated. You'll have to add that language in the code. You'll have to add references to your new language in these files:

  • hscommon/
  • qtlib/
  • qt/base/

To help you, you can look at this commit where the Korean language was added.

Help File translation

Help file translation is much simpler to do than application translation, but it's much longer and more boring. I'd understand if you don't want to do it, or do it partially (I personally hate to do it). dupeGuru help is built using Sphinx, so it's better if you're familiar with its syntax.

To create a new help file translation, duplicate the "help/en" folder (the folder with ".rst" files in it), and simply start translating away. Very often, it's pretty hard (and boring) to be faithful to the original form and meaning of the sentences. Don't hesitate to reformulate as you see fit.

If you're not familiar with Sphinx's syntax, try to keep the markup intact. For example, words between stars ("*") are bold, so in your translation, the same words should be between stars. There is markup for titles and bullet points too, but these are fairly obvious.

An important markup to keep intact are hyperlinks. stuff like ``foo ``_ or :doc:``foo ``. Don't translate what is between <> brackets because it's a reference to a page. Also, don't try to translate :doc:, it's part of the markup.

Some lines are indented (they start with a number of space characters). Keep the indentation intact, it's important.

Updating help files

With time, translated help files fall out of sync with the main english help file. One way you can help, as a translator, is by refreshing those files.

Whenever the english help file is changed, a "todo" entry is added to all translations. Therefore, it's easy to spot what a translation needs to be refreshed, you just have to look for the ".. todo::" directives, then locate the text they refers to in the english help file, and then translate that text.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.