start

# Translate Toolkit Developers Guide

The goal of the translate toolkit is to simplify and unify the process of translation.

## History

The initial toolkit was designed to convert Mozilla .dtd and .properties files into Gettext PO format. The logic was not that PO was in any way superior but that by simplifying the translations process ie allowong a translator to use one format and one tool that we could get more people involved and more translators.

The tools have now evolved to include other formats such as OpenOffice.org and the goal is still to migrate various formats to a common format, PO and in the future XLIFF as more tools become available for that format.

These tools we group as convertors. Along the way we developed other tools that allowed us to manipulate PO files and check them for consistency. As we evolved the convertor tools we have also improved and abstracted the classes that read the various file types. In the future we hope to define these better so that we have a more or less stable API for convertors.

## Coding Conventions

### Python Code

We try to follow the official “Style Guide for Python Code”, as explained in PEP 8:

http://www.python.org/dev/peps/pep-0008/

### Docstrings

We use epydoc to generate our API documentation.

Please read PEP 257 (Docstring Conventions) for a general overview.

The important bits:

- A docstring should have a brief one-line summary, ending with a period.
- If there are more details there should be a blank line between the one-line summary and the rest of the text.
- Some epytext fields describing the input parameters and/or return types can be specified last.
- There should be a blank line before the closing quotes.

#### Example

        def addunit(self, unit):
            """Appends the given unit to the object's list of units.

            This method should always be used rather than trying to modify the
            list manually.

            @type unit: TranslationUnit
            @param unit: Any object that inherits from L{TranslationUnit}.

            """
            self.units.append(unit)

## Resources

### SVN access

We moved to the SourceForge Subversion repository in August 2006.

    svn co https://translate.svn.sourceforge.net/svnroot/translate/src/trunk translate

### CVS access

Up until August 2006, we used the SourceForge CVS repository. These were the necessary commands for access:

    cvs -d:pserver:anonymous@translate.cvs.sourceforge.net:/cvsroot/translate login
    cvs -z3 -d:pserver:anonymous@translate.cvs.sourceforge.net:/cvsroot/translate co -P src

### Bugzilla

- http://bugs.wordforge.org/

### Communication

- IRC channel - irc://irc.freenode.net/#pootle
- Developers mailing list - https://lists.sourceforge.net/lists/listinfo/translate-devel
- CVS commits - https://lists.sourceforge.net/lists/listinfo/translate-cvs

## Source code map

The tools are stored in SVN https://svn.sourceforge.net/svnroot/translate/src/ (previously in CVS). This rough map will allow you to navigate SVN:

- convert -- convert between different formats and PO format
- filters -- pofilter and its helper functions (badly named, it is really a checking tool)
- storage -- all base file formats: xliff, properties, oo, tmx, etc
- misc -- various helper functions
- tools -- all Po manipulation programs: pocount, pogrep, etc

## Current source state

Note that this documentation is almost always for HEAD.

Development | HEAD
Current stable branch | wordforge-0-10-branch
Previous stable branch | wordforge-0-9-branch
Previous stable branch | translate-toolkit-0-8-branch

## Setup

The toolkit is installed by running:

    ./setup.py install

As root

The various setup options are yours to explore

To run / test things without installing, see the instructions for Pootle. Those instructions sets your environment for both Pootle and the toolkit

## General overview of the programs

Each tool in the toolkit has both a core program and a command line wrapper. For example the oo2po convertor:

- oo2po -- the command line tool
- oo2po.py -- the core program

This is done so that the tools can be used from within the Pootle server thus reusing the toolkit easily.

### Command line options

Getting lost with the command line options? Well you might want to volunteer to move some of them into configuration files. But in terms of programming you might be confused as to where they are located. Many of the command line options are implemented in each tool. Things such as --progress and --errorlevel are used in each program. Thus these are abstracted in misc/optrecurse.py. While each tools unique command line options are inplemented in xxx.py.

## Convertors

The convertors each have a class that handles the conversion from one format to another. This class has one important method convertfile which handles the actual conversion.

A function convertXXX manages the conversion for the command line equivalent and essentially has at least 3 parameters: inputfile, outpurfile and templatefile. It itself will call the conversion class to handle conversion of individual files. Recursing through multiple files is handled by the optrecurse.py logic.

The convertors main function handles any unique command line options.

Where we are headed is to get to a level where the storage formats themselves are more aware of themselves and their abilities. Thus the convertor could end up as one program that accepts storage format plugins to convert from anything to almost anything else. Although our target localisation formats are PO and XLIFF only.

If you want to create a new convertor it is best to look at a simple instance such as csv2tbx or txt2po and their associated storage classes. The storage base class documentation will give you the information you need for the storage class implementation.

## Tools

The tools in some way copy the logic of the convertors. We have a class so that we can reuse a lot of the functionality in Pootle. We have a core function that take: input, output and templates. And we have a main function to handle the command line version.

pocount should be converted to this but does not follow this conventions. In fact pocount should move the counting to the storage formats to allow any format to return its own word count.

## Checks

There’s really only one, pofilter. But there are lots of helper functions for pofilter. pofilters main task is to check for errors in PO or XLIFF files. Here are the helper file and their descriptions.

- autocorrect.py -- when using --autocorrect it will attempt some basic corrections found in this file
- checks.py -- the heart. This contains: the actual checks and their error reports, and defined variables and acceleratators for eg --mozilla
- decorations.py -- various helper functions to identify accelerators, variables and markers
- helpers.py -- functions used by the tests
- prefilters.py -- functions to eg remove variables and accelerators before applying tests to the PO message

pofilter is now relatively mature. The best areas for contributions are:

- more tests
- language specific configuration files
- tests for the tests -- so we don’t break our good tests
- defining a config files scheme to do cool stuff off of the command line. Globally enable or disable tests based on language, etc
- some approach to retesting that would remove ‘# (pofilter)’ failure markings if the test now passes.
- ability to mark false positives

The API documentation is a good start if you want to add a new tests. To add a new language have a look at a language you understand amongst those already implemented.

## Storage

These are the heart of the convertors. Each destination storage format is implemented in its own file. Up until toolkit version 0.8, there was no formally defined API (the tools have been evolving and only recently stabilised), but they generally followed this structure. These classes are defined:

- XXelement -- handles the low level individual elements of the file format. eg PO message, CSV records, DTD elements
- XXfile -- handles the document or file level of the format. Eg a PO file, a CSV file a DTD file
  - fromlines -- read in a file and initialise the various elements
  - tolines -- convert the elements stored in XXelements and portions in XXfile to a raw file in that format

In the XML based formats eg. TMX, XLIFF and HTML there is usually just an extended parser to manage the file creation.

Within each storage format there are many helper funtions for escaping and managing the unique features of the actual format.

You can help by:

- abstracting more of the functions and documenting that so that we can get a better API
- adding other formats and convertors eg .DOC, .ODF and others
- helping us move to a position where any format should convert to the base format: PO and in the future XLIFF without having to create a specific convertor wrapper.
- Ensuring that our formats conform to the standards

### Base Classes

From toolkit 0.9 onwards, we are moving towards basing all storage formats on a set of base classes, in the move to a universal API. We’re also fixing things so that escaping is much more sane and handled within the class itself not by the convertors.

In base classes we have different terminology

- XXXunit = XXXelement
- XXXstore = XXXfile

We have also tried to unify terminology but this has been filtered into the old classes as far as possible.