[Zope3-checkins] CVS: Zope3/src/zope/app/translation_files - README.txt:1.1 extract.py:1.1 pygettext.py:1.1 zope.pot:1.1

Jim Fulton jim@zope.com
Thu, 3 Apr 2003 11:18:37 -0500


Update of /cvs-repository/Zope3/src/zope/app/translation_files
In directory cvs.zope.org:/tmp/cvs-serv26474/src/zope/app/translation_files

Added Files:
	README.txt extract.py pygettext.py zope.pot 
Log Message:
Changed the handling of program source translations

- The translation files for the application server (zope.app) are now
  al in one place, src/zope/app/translation_files.

- Added an extraction tool, extract.py that extracts all translatable
  strings from Python and zpt source files into a translation template
  file, zope.pot. This template file should then be merged into
  individual translation files.

To do:

- zcml extraction

- I don't think that encodings are handled correctly. The template
  file certainly doesn't have the encoding set correctly.



=== Added File Zope3/src/zope/app/translation_files/README.txt ===
Software translation files
==========================

This directory containes translation files and utilities for
translating the software strings for the zope application server
software.


=== Added File Zope3/src/zope/app/translation_files/extract.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Message id extraction script

This script extracts translatable strings and creates a single zope.pot file.

$Id: extract.py,v 1.1 2003/04/03 16:18:36 jim Exp $
"""

import os, sys, fnmatch
import pygettext


usage = """python extract.py [files]
"""

def app_dir():
    try:
        import zope.app
    except ImportError:
        # Couldn't import zope.app, need to add something to the Python
        # path

        # Get the path of the src
        translation_files = os.path.abspath(os.path.dirname(sys.argv[0]))
        app = os.path.dirname(translation_files)
        zope = os.path.dirname(app)
        src = os.path.dirname(zope)
        sys.path.insert(0, src)

        import zope.app

    dir = os.path.dirname(zope.app.__file__)

    return dir

def find_files(dir, pattern, exclude=()):


    files = []

    def visit(files, dirname, names):
        files += [os.path.join(dirname, name)
                  for name in fnmatch.filter(names, pattern)
                  if name not in exclude]
        
    os.path.walk(dir, visit, files)

    return files

def main(argv=sys.argv):
    dir = app_dir()
    sys.argv[1:] = ['-ozope.pot',]+find_files(dir, '*.py',
                                            exclude=["pygettext.py"])
    pygettext.main()

    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal import talgettext

    sys.argv[1:] = ['-uzope.pot', '-ozope.pot',]+find_files(dir, '*.pt')
    talgettext.main()


if __name__ == '__main__':
    main()


=== Added File Zope3/src/zope/app/translation_files/pygettext.py === (441/541 lines abridged)
#! /usr/bin/env python
# Originally written by Barry Warsaw <barry@zope.com>
#
# Minimally patched to make it even more xgettext compatible 
# by Peter Funk <pf@artcom-gmbh.de>

"""pygettext -- Python equivalent of xgettext(1)

Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
internationalization of C programs.  Most of these tools are independent of
the programming language and can be used from within Python programs.  Martin
von Loewis' work[1] helps considerably in this regard.

There's one problem though; xgettext is the program that scans source code
looking for message strings, but it groks only C (or C++).  Python introduces
a few wrinkles, such as dual quoting characters, triple quoted strings, and
raw strings.  xgettext understands none of this.

Enter pygettext, which uses Python's standard tokenize module to scan Python
source code, generating .pot files identical to what GNU xgettext[2] generates
for C and C++ code.  From there, the standard GNU tools can be used.

A word about marking Python strings as candidates for translation.  GNU
xgettext recognizes the following keywords: gettext, dgettext, dcgettext, and
gettext_noop.  But those can be a lot of text to include all over your code.
C and C++ have a trick: they use the C preprocessor.  Most internationalized C
source includes a #define for gettext() to _() so that what has to be written
in the source is much less.  Thus these are both translatable strings:

    gettext("Translatable String")
    _("Translatable String")

Python of course has no preprocessor so this doesn't work so well.  Thus,
pygettext searches only for _() by default, but see the -k/--keyword flag
below for how to augment this.

 [1] http://www.python.org/workshops/1997-10/proceedings/loewis.html
 [2] http://www.gnu.org/software/gettext/gettext.html

NOTE: pygettext attempts to be option and feature compatible with GNU xgettext
where ever possible.  However some options are still missing or are not fully
implemented.  Also, xgettext's use of command line switches with option
arguments is broken, and in these cases, pygettext just defines additional
switches.

Usage: pygettext [options] inputfile ...

Options:

    -a

[-=- -=- -=- 441 lines omitted -=- -=- -=-]

            print >> sys.stderr, _(
                "Can't read --exclude-file: %s") % options.excludefilename
            sys.exit(1)
    else:
        options.toexclude = []

    # slurp through all the files
    eater = TokenEater(options)
    for filename in args:
        if filename == '-':
            if options.verbose:
                print _('Reading standard input')
            fp = sys.stdin
            closep = 0
        else:
            if options.verbose:
                print _('Working on %s') % filename
            fp = open(filename)
            closep = 1
        try:
            eater.set_filename(filename)
            try:
                tokenize.tokenize(fp.readline, eater)
            except tokenize.TokenError, e:
                print >> sys.stderr, '%s: %s, line %d, column %d' % (
                    e[0], filename, e[1][0], e[1][1])
        finally:
            if closep:
                fp.close()

    # write the output
    if options.outfile == '-':
        fp = sys.stdout
        closep = 0
    else:
        if options.outpath:
            options.outfile = os.path.join(options.outpath, options.outfile)
        fp = open(options.outfile, 'w')
        closep = 1
    try:
        eater.write(fp)
    finally:
        if closep:
            fp.close()


if __name__ == '__main__':
    main()
    # some more test strings
    _(u'a unicode string')


=== Added File Zope3/src/zope/app/translation_files/zope.pot ===
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: Thu Apr  3 11:10:12 2003\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: ENCODING\n"
"Generated-By: pygettext.py 1.4\n"


#: /home/jim/atmp/z3/src/zope/app/interfaces/content/dtmlpage.py:31
#: /home/jim/atmp/z3/src/zope/app/interfaces/content/sql.py:52
#: /home/jim/atmp/z3/src/zope/app/interfaces/content/zpt.py:40
msgid "Source"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/dtmlpage.py:32
msgid "The source of the dtml page."
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/file.py:25
msgid "Content Type"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/file.py:26
msgid "The content type identifies the type of data."
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/file.py:32
msgid "Data"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/file.py:33
msgid "The actual content of the object."
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/sql.py:41
msgid "Connection Name"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/sql.py:42
msgid "The Connection Name for the connection to be used."
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/sql.py:46
msgid "Arguments"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/sql.py:47
msgid "A set of attributes that can be used during the DTML rendering process to provide dynamic data."
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/sql.py:53
#: /home/jim/atmp/z3/src/zope/app/interfaces/content/zpt.py:41
msgid "The source of the page template."
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/interfaces/content/zpt.py:45
msgid "Expand macros"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:36
#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:65
msgid "Delete"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:178
msgid "Delete Messages"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:109
msgid "Domain"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:33
#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:62
msgid "Edit"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translatemessage.pt:32
msgid "Edit Message"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:175
msgid "Edit Messages"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:94
msgid "Filter"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:87
msgid "Filter (% - wildcard):"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/exportimport.pt:40
msgid "Import File Name:"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:108
#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translatemessage.pt:18
msgid "Message Id"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:78
msgid "New Domain:"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:73
msgid "New Language:"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/exportimport.pt:29
#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:44
msgid "Select Domains:"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/exportimport.pt:18
#: /home/jim/atmp/z3/src/zope/app/browser/services/translation/translate.pt:15
msgid "Select Languages:"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/skins/rotterdam/folder_contents.pt:163
msgid "container_copy_button"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/skins/rotterdam/folder_contents.pt:160
msgid "container_cut_button"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/skins/rotterdam/folder_contents.pt:170
msgid "container_delete_button"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/skins/rotterdam/folder_contents.pt:166
msgid "container_paste_button"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/skins/rotterdam/folder_contents.pt:157
msgid "container_rename_button"
msgstr ""

#: /home/jim/atmp/z3/src/zope/app/browser/container/main.pt:68
msgid "menu_delete_button"
msgstr ""