Eleven command line utilities to modify PO translation files (.po extension) used by Free Pascal and Lazarus.
These tools are similar to utilities available from the generic GNU/Gettext used in the Translation Project and from Delphi specific versions (dxgettext and Gnu GetText Tools for Delphi). The difference is that the tools available here are adapted to the .po dialect used in Free Pascal / Lazarus. More on that here: On Translating Free Pascal/Lazarus Programs (ou Traduction de programmes Free Pascal/Lazarus).
Besides being tailored to handle Free Pascal / Lazarus generated PO files, the utilities differ from those provided by the GNU gettext project by their style. Each utility does a single task which cannot be modified by command line switches. Indeed, aside from file names, the utilities accept no command line switches or options. Consequently when a GNU gettext equivalent utility is given in the list below, the equivalency is only partial and it may be necessary to provide additional filters or scripts to perform the exact same action as the poxxxx utility.
It should be possible to compile the utilities for any of the Free Pascal supported targets. They have been used mostly in Linux, but some tests have been done in Windows.
Version 0.2 (June 2, 2021)
The utilities should now handle extracted and translator comments, all format flags and previous context fields which can be found in PO files generated with the GNU gettext system but which are not in PO files generated by Lazarus as far as the author knows. Translator comments added to a PO file with a translation utility such as poedit should no longer be lost if the PO file is processed with these programs. In any case, an effort has been made to avoid losing any work. In practice, this means that any file about to be overwritten is renamed and thus a backup remains available.
Warning:
The author offers no guarantee of any sort with regard to these tools.
Utilities
- 1. poclean
- 2. pocopy
- 3. pofill
- 4. poginore
- 5. poinfo
- 6. pomerge
- 7. poscrub
- 8. posort
- 9. postrip
- 10. poswap
- 11. poupdate
Removes any entry in a .po file that has the same reference, msgid and msgstr as an other entry.
usage:
poclean source[.po] [output[.po]]
Purpose: Obviously, this is meant to remove redundant entries. Normally duplicates would never be created by the Lazarus gettext implementation. Use poscrub for a more aggressive action.
GNU gettext equivalent utility: msguniq.
Copies all msgid to msgstr in a .po file.
usage:
pocopy source[.po] [output[.po]]
The header entry will not be modified.
Purpose: Use this to create a translation back to the original language:
pocopy myapp.po myapp.en.po
Then it will be possible to switch back to the original language at run-time in myapp if another translation had been previously loaded.
GNU gettext equivalent utilities: msgen, msginit.
Fills any empty msgstr field in a .po file with the content of the corresponding msgid.
usage:
pofill sourcefile[.po] [outputfile[.po]]
Purpose: Useful when creating a regional version of the original language, say en_GB from an implicit en template. Just copy the template to myapp.en_GB.po, translate the few msgid that would be different in the UK to the corresponding msgstr and then use the utility to fill in all the other msgstr.
GNU gettext equivalent utilities: msgfilter, msgexec.
Removes all entries found from a source .po file whose reference is found in a remove .po file.
usage:
poignore source[.po] remove[.po] [output[.po]]
Purpose: The template generated by the Lazarus gettext implementation can contain entries, such as captions that will be overwritten at run-time or technical terms that do not require translations. The same could be accomplished by adding the entry reference in the Excluded box in the i18n Project Options in the Lazarus IDE.
Provides information about a .po file.
usage:
poinfo source[.po]
The utility displays the following data.
- Errors while reading the source file. The error checking is by no means exhaustive.
- Summary statistics.
- All entries that have a duplicate reference (which should never be allowed), a duplicate
msgid, and a duplicatemsgstr. Emptymsgstrfields are not considered duplicates.
Example output:
$ ./poinfo bad
1 Error: Missing leading " quote in msgstr in line 17
2 Error: Entry 3 (stringres.mssconnected) does not have a msgstr in line 19
...
8 Error: Entry 12 (stringres.smessagesent) does not have a msgstr in line 61
9 Error: Reference empty in line 66
Source: bad`.po`
Errors: 0
Entries: 75 plus a header
Ambiguous entries: 1
Missing references: 0
Duplicate references: 2
Empty msgids: 0
Duplicate msgids: 5
Empty msgstrs: 0
Duplicate msgstrs: 5
Fuzzys: 0
prevmsgids: 0
Entry 6 () has a duplicate reference
...
Entry 47 (tbrokereditform.label2.caption) has a duplicate msgstr
Merges two .po files.
usage:
pomerge source[.po] more[.po] [output[.po]]
The output .po file is constructed as follows.
- All entries in
sourceare copied tooutput. - All entries in
morewith a reference not insourceare added tooutput. - If an entry in
morehas a reference that is also insourcethen the possible conflict is resolved as follows:- if the
msgidandmsgstrof both entries are the same, the entry is not added tooutputand it is removed frommore(there is no conflict). - if there is a difference in
msgidormsgstr, the entry is not added tooutputand if is kept inmore(there is a conflict).
- if the
- At the end, all remaining entries in
moreare saved under the namemore.po.conflicts.
GNU gettext equivalent utility: msgmerge.
Removes any entry in a .po file that has the same reference, msgid and msgstr as an other entry. Also removes all fuzzy flags and all prevmsgid fields.
usage:
poscrub source[.po] [output[.po]]
Use poclean for a less aggressive action.
Sorts a .po file by reference.
usage:
posort source[.po] [output[.po]]
It is not mandatory to sort entries alphabetically, but the Lazarus IDE does generate sorted .po files.
Removes all translated strings in a .po file.
usage:
postrip source[.po] [output[.po]]
The header entry in the output .po file will be
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
no matter if the source file had a header entry or not.
Purpose: Generate a template from a good translation.
Exchanges all msgid and msgstr in a .po file.
usage:
podswap source[.po] [output[.po]]
If the msgstr field in an entry is empty, then the msgid field will not be changed.
The header entry will not be altered.
Updates empty msgstr in a .po file from translations found in another .po file.
usage:
poupdate source[.po] translations[.po] [output[.po]]