FontForge uses a standard mechanism called gettext to provide translations of user interface strings into different language. Gettext is described profusely at the gettext site, the following are some brief notes on what you need to know to translate FontForge's UI.
In a gettext based package, the translatable strings live in a "pot" file. In FontForge's case it is called "FontForge.pot".
Each source distribution I make contains the then current FontForge.pot file in the top level directory of the distribution. You may find a copy of the current distribution on sourceforge, it will be called something like fontforge_full-20060817.tar.bz2.
After you have downloaded one of these packages, either copy the tarball to where you are, or move to the directory containing the tarball (I can't provide explicit instructions here, because I don't know where your browser put the file) and type (do not type "$"):
$ bunzip2 fontforge*.tar.bz2 $ tar xf fontforge*.tar
Then edit the file fontforge-*/FontForge.pot
.
This is a better solution because it gives you a current version of the pot file. Create a cvs directory as described in the section on building from source. Having done that type
$ cd fontforge/fontforge $ make -f Makefile.in FontForge.pot
You should now have a FontForge.pot file (if you don't see the above section on how to get one).
The pot file is in the same format as the "po" file which you need to generate. Simply rename FontForge.pot to the language/locale that you are working on. In most cases you will probably want to rename it just to the language
$ mv FontForge.pot fr.po
But sometimes that will not be enough. For example, Traditional and simplified chinese are sufficiently different that a locale must also be specified:
$ mv FontForge.pot zh_TW.po
Once you have created your po file it is time to start modifying it. I shall use French as an example in the following (because I almost speak French), obviously you will need to make changes appropriate for your language.
The po file begins with some lines like:
# (American) English User Interface strings for FontForge. # Copyright (C) 2000-2006 by George Williams # This file is distributed under the same license as the FontForge package. # George Williams, <pfaedit@users.sourceforge.net>, 2006. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2006-08-19 07:32-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
You should change this to:
# (French) French User Interface strings for FontForge. # Copyright (C) 2004-2006 by Pierre Hanser & Yannis Haralambous # This file is distributed under the same license as the FontForge package. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: 20060821\n" "POT-Creation-Date: 2006-08-19 07:32-0700\n" "PO-Revision-Date: 2006-08-20 14:46+0100\n" "Last-Translator: Pierre Hanser\n" "Language-Team: French <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n"
Most of these are pretty self-explanatory. Fill in your name and email address where appropriate, and the date on which you last worked on the file. The plurals line is a little more complex, and I'll describe it later.
Next there are thousands of string entries. They look something like this:
#: ttfinstrs.c:2184 typofeatures.c:1450 ../gdraw/gaskdlg.c:1076 #: ../gdraw/gaskdlg.c:1332 ../gdraw/gaskdlg.c:1391 ../gdraw/gfiledlg.c:152 #: ../gdraw/gmatrixedit.c:711 ../gdraw/gsavefiledlg.c:280 msgid "_Cancel" msgstr ""
You should change these to:
#: ttfinstrs.c:2184 typofeatures.c:1450 ../gdraw/gaskdlg.c:1076 #: ../gdraw/gaskdlg.c:1332 ../gdraw/gaskdlg.c:1391 ../gdraw/gfiledlg.c:152 #: ../gdraw/gmatrixedit.c:711 ../gdraw/gsavefiledlg.c:280 msgid "_Cancel" msgstr "_Annuler"
So the translation goes into the msgstr line. (The comment lines above indicate in what source files and on what lines the "_Cancel" string as used -- this information may be helpful if you want more information about context). If you don't want to translate a string just leave the msgstr as a null-string, and the English text will be used ("OK" seems to be left untranslated in many languages)
#: ttfinstrs.c:2184 typofeatures.c:1450 ../gdraw/gaskdlg.c:1076 #: ../gdraw/gaskdlg.c:1332 ../gdraw/gaskdlg.c:1391 ../gdraw/gfiledlg.c:152 #: ../gdraw/gmatrixedit.c:711 ../gdraw/gsavefiledlg.c:280 msgid "_OK" msgstr ""
Some strings contain mnemonics. The mnemonic is preceded by an underscore.
That seems fairly straight forward. But there are always complications. Sometimes an English word might be translated by different French words depending on context. For example in French the English word "New" might be translated as either "Nouveau" or "Nouvelle" depending on the gender of the thing being created. In Japanese the word for the latin language is different from the latin script. So to disambiguate some strings a little bit of context information may appear before the actual string to be translated:
msgid "File|_New" msgstr "_Nouveau"
or
msgid "Anchor|_New" msgstr "_Nouvelle"
The context will be any text before an "|". It should not be translated. Indeed both it and the "|" should be completely omitted.
Finally we have the problem of plurals. Suppose we have a string
msgid "%d Group"
We need to inflect the word "Group" depending on the number of groups we've got -- and each language has different rules.
Remember, at the beginning of the file there was a line:
"Plural-Forms: nplurals=2; plural=n>1;\n"
This says that this language has two plural forms, the singular form is used when there are 0 or 1 entries (n<=1), and the plural form is used for n>1 entries. That rule is correct for French. English looks like:
"Plural-Forms: nplurals=2; plural=n!=1;\n"
A language like classical Greek, which has a dual form, might look like
"Plural-Forms: nplurals=3; plural=n<=1?0:n==2?1:2;\n"
The expression is a c language expression. When there is a string that might be plural it has a slightly different form in the po file
#: groups.c:1558 msgid "%d Group" msgid_plural "%d Groups" msgstr[0] "%d Groupe" msgstr[1] "%d Groupes"
Obviously, in a language with three forms there would be additional
msgstr[n]
entries.
After a few months, you will probably find that I've added some additional strings to FontForge, and you may what to update your original po file.
Once again you grab a current "pot" file and you type:
$ msgmerge fr.po FontForge.pot
This will update your po file to contain any new strings for you to translate. It will also make guesses for these new strings. Some of these guesses are correct, some are very strange, so you will want to examine the guessed strings (they will be marked with the word "fuzzy")
Once you have completed your po file you will want to test it. First you need to compile it:
$ msgfmt -o fr.mo fr.po
and create an "mo" file. This file you will want to rename and move to the appropriate directory. If fontforge is installed in /usr/local/bin then you would say
$ mv fr.mo /usr/local/share/locale/fr/LC_MESSAGES/FontForge.mo
Then make sure your locale is set properly and start fontforge. You should see your messages
$ LANG=fr_FR.UTF-8; export LANG $ fontforge -new