xml2po 1.0.5 — © 2004, Danilo Segan

Requirements
............

 * Python
 * libxml2 and libxml2-python
 * xml2po.py
 * GNU gettext (msgfmt, msgmerge tools)

About xml2po
............

xml2po is a simple Python program which extracts translatable content
from free-form XML documents and outputs gettext compatible POT
files.

It can work it's magic only with simple tags, and for complicated
tags one has to provide a list of all tags which are "final" (that
will be put into one "message" in PO file).

I will try to provide sane defaults for DocBook documents, but one
would have to provide more suitable definitions for other kinds of
documents in files "ignored-tags" and "final-tags" in the directory
xml2po is run in, or with filenames passed as -i and -f options.

Ignored tags are those that will be silently skipped over, and not
recursed into.

Preparing a POTemplate from XML file
........................................

 ./xml2po.py -o template.pot file.xml

You may use parameters '-f final-tags' and '-i ignored-tags', where
file final-tags and ignored-tags contain one-tag-per-line, and first 
are considered "final" (i.e. do not recurse over its children), and
latter are ignored (including its children).  If you do not use -f or
-i parameters, default is to read files "final-tags" and
"ignored-tags" from current working directory.  There's also an 
option "-a" which tries to do its best to autodetect which tags are
to be considered "final".

Get back a translation from a translator
........................................

Save a translation to xx.po, where xx is language code of a
translation (i.e. "sr" for Serbian, "de" for German, ...).

Execute:
 ./xml2po.py -p xx.po -o file-xx.xml file.xml

Now you've got a nice and translated XML file in 'file-xx.xml'.

Updating a translation
......................

When base XML file changes, the real advantages of PO files come to
surface.  To merge the translation you need to first produce a new
POT file:
 ./xml2po.py -o newfile.pot newfile.xml

And then you need to use gettext "msgmerge" program to merge the
translation with the new POT file:
 msgmerge -o new-xx.po xx.po newfile.pot && mv new-xx.po xx.po

Alternatively, xml2po provides option "-u" which does exactly these
two steps for you:
 ./xml2po.py -u xx newfile.xml

(Note that you should not use "xx.po" in the -u option, this is to
emulate intltool-update behaviour; string ".po" will be appended
automatically to the file name.)

Lists of tags
.............

Files "ignore-tags" and "final-tags" contain lists of tags which are
treated specially.  If tag is in the ignore-tags list, *AND* not in
the final-tags list, it is completely ignored (skipped over, it is
output verbatim when XML DOM tree is "deserialized").  If it's in both
lists, it is processed, but corresponding message for translation
won't be output (useful for things like "itemizedlist" which don't
have any content for translation).  If a tag is only in final-tags, it
is considered to be the general translateable unit, and it is output
as one message into the PO file, except if it contains other
final-tags (eg. para containing another para), when that nesting final
tag is replaced with a string of the form "<placeholder-2/>".

If you don't want to worry about nesting of tags, option "-a" tries to
detect what nodes are most suitable as final-tags.  This won't work
well if one can nest tags indefinitelly (like with DocBook documents,
where one may have "<para>Blah... <orderedlist><listitem>...</para>"
which may become very long string, which defeats the advantages of 
PO files).

Caveats
.......

There are several situations in which xml2po produces temporary
files.  If permissions in current directory are wrong, they may cause
mysterious breakages, though I have tried to make it act as sanely as
possible.

Normally, xml2po doesn't substitute external entities, because such
files should be translated by themselves.  Unfortunately, Python
bindings for libxml2 are not complete, and there's no simple way to
detect if entity is external or not.  Still, there's a method
debugDumpNode which can output relevant data to a filehandle (it
doesn't work with StringIO), so I decided to create a temporary file
.xml2po-checkingentities in the current working directory.  If it is
not writeable, instead of showing an error, xml2po will replace every
entity.

Option "-p file.po" depends on program msgfmt being available and in
the path, and also depends on a file .xml2po.mo being writeable in
the current working directory.  If that fails, you'll see an error.

