Free Pascal / Lazarus Po Files Utilities
Eleven command line utilities to modify PO translation files (.po
extension) used by Free Pascal and Lazarus.
These tools are similar to utilities available for GNU/Gettext and it's Delphi version dxgettext with the difference that they are adapted to the .po
dialect used in Free Pascal / Lazarus. More on that here: On Translating Free Pascal/Lazarus Programs.
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. So when a GNU gettext equivalent utility
is given in the list below, the equivalency is obviously partial only 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
1. poclean
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
2. pocopy
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:
pocpy myapp.po myapp.en.po
Then it will be possible to get back to the original language at run-time in myapp
.
GNU gettext equivalent utilities: msgen
, msginit
3. pofill
Fills any empty msgstr
field a .po
file with the content of the corresponding msgid
.
usage:
pofill sourcefile[.po] [outputfile[.po]]
Purpose: Usefull 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
4. poginore
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.
5. poinfo
Provides information about a .po
file.
usage:
poinfo source[.po]
The utility
- reports errors while reading the source file. The error checking is by no means exhaustive.
- displays summary statistics
- lists all entries that have a duplicate reference (which should never be allowed), a duplicate
msgid
, and a duplicatemsgstr
. Emptymsgstr
fields 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
6. pomerge
Merges two .po
files.
usage:
pomerge source[.po] more[.po] [output[.po]]
The output .po
file is constructed as follows.
- All entries in
source
are copied tooutput
. - All entries in
more
with a reference not insource
are added tooutput
. - If an entry in
more
has a reference that is also insource
then the possible conflict is resolved as follows:- if the
msgid
andmsgstr
of both entries are the same, the entry is not added tooutput
and it is removed frommore
(there is no conflict). - if there is a difference in
msgid
ormsgstr
, the entry is not added tooutput
and if is kept inmore
(there is a conflict).
- if the
- At the end all remaining entries in
more
are saved under the namemore.po.conflicts
.
GNU gettext equivalent utility: msgmerge
7. poscrub
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.
8. posort
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.
9. postrip
Removes all translated strings in a .po
file.
usage:
stripmsgstr 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.
10. poswap
Exchanges all msgid
and msgstr
in a .po
file
usage:
stripmsgstr source[.po] [output[.po]]
If the msgstr
field on an entry is empty, then the msgid
field will not be changed.
The header entry will not be altered.
11. poupdate
Updates empty msgstr
in a .po
file from translations found in another .po
file
usage:
poupdate source[.po] translations[.po] [output[.po]]