8. How to contribute?

If you would like to contribute to the project, you can first send your feedback on what you like or dislike, and if there are features you miss in calcurse. For now on, possible contributions concern the translation of calcurse messages and documentation.

8.1. Translating documentation


We recently dropped all translations of the manual files from the distribution tarball. There are plan to reintroduce them in form of a Wiki on the calcurse website. Please follow the mailing lists for up-to-date information.

The doc/ directory of the source package already contains translated version of calcurse manual. However, if the manual is not yet available into your native language, it would be appreciated if you could help translating it.

To do so, just copy one of the existing manual file to manual_XX.html, where XX identifies your language. Then translate this newly created file and send it to the author (see Reporting bugs and feeback), so that it can be included in the next calcurse release.

8.2. calcurse i18n

As already mentioned, gettext utilities are used by calcurse to produce multi-lingual messages. We are currently using Transifex to manage those translations.

This section provides informations about how to translate those messages into your native language. However, this howto is deliberately incomplete, focusing on working with gettext for calcurse specifically. For more comprehensive informations or to grasp the Big Picture of Native Language Support, you should refer to the GNU gettext manual at: http://www.gnu.org/software/gettext/manual/


Since we switched to Transifex, editing po files is not necessary anymore as Transifex provides a user-friendly, intuitive web interface for translators. Knowledge of gettext and the po format is still useful for those of you who prefer the command line and local editing. If you want to use the web UI to edit the translation strings, you can skip over to Using the Transifex web UI tough.

Basically, three different people get involved in the translation chain: coders, language coordinator, and translators. After a quick overview of how things work, the translator tasks will be described hereafter.


To be able to display texts in the native language of the user, two steps are required: internationalization (i18n) and localization (l10n).

i18n is about making calcurse support multiple languages. It is performed by coders, who will mark translatable texts and provide a way to display them translated at runtime.

l10n is about making the i18n’ed calcurse adapt to the specific language of the user, ie translating the strings previously marked by the developers, and setting the environment correctly for calcurse to use the result of this translation.

So, translatable strings are first marked by the coders within the C source files, then gathered in a template file (calcurse.pot - the pot extension meaning portable object template). The content of this template file is then merged with the translation files for each language (fr.po for French, for instance - with po standing for portable object, ie meant to be read and edited by humans). A given translation team will take this file, translate its strings, and send it back to the developers. At compilation time, a binary version of this file (for efficiency reasons) will be produced (fr.mo - mo stands for machine object, i.e. meant to be read by programs), and then installed. Then calcurse will use this file at runtime, translating the strings according to the locale settings of the user.

Translator tasks

Suppose someone wants to initiate the translation of a new language. Here are the steps to follow:

  • First, find out what the locale name is. For instance, for french, it is fr_FR, or simply fr. This is the value the user will have to put in his LC_ALL environment variable for software to be translated (see Environment variable for i18n).
  • Then, go into the po/ directory, and create a new po-file from the template file using the following command: msginit -i calcurse.pot -o fr.po -l fr --no-translator If you do not have msginit installed on your system, simply copy the calcurse.pot file to fr.po and edit the header by hand.

Now, having this fr.po file, the translator is ready to begin.


The format of the po-files is quite simple. Indeed, po-files are made of four things:

  1. location lines: tells you where the strings can be seen (name of file and line number), in case you need to see a bit of context.
  2. msgid lines: the strings to translate.
  3. msgstr lines: the translated strings.
  4. lines prefixed with #: comments (some with a special meaning, as we will see below).

Basically, all you have to do is fill the msgstr lines with the translation of the above msgid line.

A few notes:

Fuzzy strings
You will meet strings marked with a "#, fuzzy" comment. calcurse won’t use the translations of such strings until you do something about them. A string being fuzzy means either that the string has already been translated but has since been changed in the sources of the program, or that this is a new string for which gettext made a wild guess for the translation, based on other strings in the file. It means you have to review the translation. Sometimes, the original string has changed just because a typo has been fixed. In this case, you won’t have to change anything. But sometimes, the translation will no longer be accurate and needs to be changed. Once you are done and happy with the translation, just remove the "#, fuzzy" line, and the translation will be used again in calcurse.
c-format strings and special sequences
Some strings have the following comment: "#, c-format". This tells that parts of the string to translate have a special meaning for the program, and that you should leave them alone. For instance, %-sequences, like "%s". These means that calcurse will replace them with another string. So it is important it remains. There are also \-sequences, like \n or \t. Leave them, too. The former represents an end of line, the latter a tabulation.
Translations can be wrapped

If lines are too long, you can just break them like this:

msgid ""
"some very long line"
"another line"
po-file header

At the very beginning of the po-file, the first string form a header, where various kind of information has to be filled in. Most important one is the charset. It should resemble

"Content-Type: text/plain; charset=utf-8\n"

You should also fill in the Last-Translator field, so that potential contributors can contact you if they want to join you in the translation team, or have remarks/typo fixes to give about the translations. You can either just give your name/nick, or add an email address, for exemple:

"Last-Translator: Frederic Culot <frederic@culot.org>\n"
Adding comments (lines begining with the # character) can be a good way to point out problems or translation difficulties to proofreaders or other members of your team.
Strings size
calcurse is a curses/console program, thus it can be heavily dependant on the terminal size (number of columns). You should think about this when translating. Often, a string must fit into a single line (standard length is 80 characters). Don’t translate blindly, try to look where your string will be displayed to adapt your translation.
A few useful tools

The po-file format is very simple, and the file can be edited with a standard text editor. But if you prefer, there are few specialized tools you may find convenient for translating:

And finally
I hope you’ll have fun contributing to a more internationalized world. :) If you have any more questions, don’t hesitate to contact us at misc .at. calcurse .dot. org.

Uploading to Transifex

There’s several different ways to upload a finished (or semi-finished) translation for a new language to Transifex. The easiest way is to browse to the Translation Teams page and request the addition of a new team.

As soon as we accepted your request, you will be able to upload your po file on the calcurse resource page by clicking the Add translation button at the bottom.

Using transifex-client

You can also use a command line client to submit translations instead of having to use the web interface every time you want to submit an updated version. If you have a recent version of setuptools installed, you can get the CLI client by issuing the following command:

$ easy_install -U transifex-client

Alternatively, you can get the source code of transifex-client at http://pypi.python.org/pypi/transifex-client.

After you downloaded and installed the client, run the following commands in the calcurse source directory to checkout the translation resources of calcurse:

$ tx pull -a

To submit changes back to the server, use:

$ tx push -r calcurse.calcursepot -t -l <locale>

For more details, read up on transifex-client usage at the The Transifex Command-line Client v0.4 section of the Transifex documentation.

Using the Transifex web UI

As an alternative to editing po files, there is a web-based interface that can be used to create and update translations. After having signed up and created a new translation team (see Uploading to Transifex on how to do that), click the Add translation button at the bottom on the calcurse resource page, select the language you’d like to translate and choose Translate Online.