summaryrefslogtreecommitdiff
path: root/src/zope/tal/talgettext.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/zope/tal/talgettext.py')
-rw-r--r--src/zope/tal/talgettext.py232
1 files changed, 9 insertions, 223 deletions
diff --git a/src/zope/tal/talgettext.py b/src/zope/tal/talgettext.py
index bc90439..08f621b 100644
--- a/src/zope/tal/talgettext.py
+++ b/src/zope/tal/talgettext.py
@@ -12,44 +12,22 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Program to extract internationalization markup from Page Templates.
+"""Extract internationalization markup from Page Templates.
Once you have marked up a Page Template file with i18n: namespace tags, use
-this program to extract GNU gettext .po file entries.
-
-Usage: talgettext.py [options] files
-Options:
- -h / --help
- Print this message and exit.
- -o / --output <file>
- Output the translation .po file to <file>.
- -u / --update <file>
- Update the existing translation <file> with any new translation strings
- found.
+this code to extract GNU gettext .po file entries.
"""
-# XXX this module seems to be unused, it has NameErrors and is not Python 3
-# compatible.
-
-from __future__ import print_function
-
-import sys
-import time
-import getopt
-import traceback
import warnings
+from zope.i18nmessageid import Message
from zope.interface import implementer
-from zope.tal.htmltalparser import HTMLTALParser
-from zope.tal.talinterpreter import TALInterpreter, normalize
+
from zope.tal.dummyengine import DummyEngine
from zope.tal.interfaces import ITALExpressionEngine
-from zope.tal.taldefs import TALExpressionError
-from zope.i18nmessageid import Message
+from zope.tal.talinterpreter import TALInterpreter
+from zope.tal.talinterpreter import normalize
-PY3 = sys.version_info > (3,)
-if PY3:
- unicode = str
pot_header = '''\
# SOME DESCRIPTIVE TITLE.
@@ -72,18 +50,10 @@ msgstr ""
NLSTR = '"\n"'
-def usage(code, msg=''):
- # Python 2.1 required
- print(__doc__, file=sys.stderr)
- if msg:
- print(msg, file=sys.stderr)
- sys.exit(code)
-
-
class POTALInterpreter(TALInterpreter):
def translate(self, msgid, default=None, i18ndict=None, obj=None):
if default is None:
- default = getattr(msgid, 'default', unicode(msgid))
+ default = getattr(msgid, 'default', str(msgid))
# If no i18n dict exists yet, create one.
if i18ndict is None:
i18ndict = {}
@@ -145,200 +115,16 @@ class POEngine(DummyEngine):
references = '\n'.join([location[0] + ':' + str(location[1])
for location in domain[msgid]])
# Note: a lot of encode calls here are needed so
- # Python 3 does not break.
+ # it does not break.
warnings.warn(
"Warning: msgid '%s' in %s already exists "
"with a different default (bad: %s, should be: %s)\n"
"The references for the existent value are:\n%s\n" %
(msgid.encode('utf-8'),
- self.file.encode('utf-8') + ':'.encode('utf-8')
+ self.file.encode('utf-8') + b':'
+ str(position).encode('utf-8'),
msgid.default.encode('utf-8'),
existing_msgid.default.encode('utf-8'),
references.encode('utf-8')))
domain[msgid].append((self.file, position))
return 'x'
-
-
-class UpdatePOEngine(POEngine):
- """A slightly-less braindead POEngine which supports loading an existing
- .po file first."""
-
- def __init__(self, macros=None, filename=None):
- POEngine.__init__(self, macros)
-
- self._filename = filename
- self._loadFile()
- self.base = self.catalog
- self.catalog = {}
-
- def __add(self, id, s, fuzzy):
- "Add a non-fuzzy translation to the dictionary."
- if not fuzzy and str:
- # check for multi-line values and munge them appropriately
- if '\n' in s:
- lines = s.rstrip().split('\n')
- s = NLSTR.join(lines)
- self.catalog[id] = s
-
- def _loadFile(self):
- # shamelessly cribbed from Python's Tools/i18n/msgfmt.py
- # 25-Mar-2003 Nathan R. Yergler (nathan@zope.org)
- # 14-Apr-2003 Hacked by Barry Warsaw (barry@zope.com)
-
- ID = 1
- STR = 2
-
- try:
- lines = open(self._filename).readlines()
- except IOError as msg:
- print(msg, file=sys.stderr)
- sys.exit(1)
-
- section = None
- fuzzy = False
-
- # Parse the catalog
- lno = 0
- for l in lines:
- lno += True
- # If we get a comment line after a msgstr, this is a new entry
- if l[0] == '#' and section == STR:
- self.__add(msgid, msgstr, fuzzy)
- section = None
- fuzzy = False
- # Record a fuzzy mark
- if l[:2] == '#,' and l.find('fuzzy'):
- fuzzy = True
- # Skip comments
- if l[0] == '#':
- continue
- # Now we are in a msgid section, output previous section
- if l.startswith('msgid'):
- if section == STR:
- self.__add(msgid, msgstr, fuzzy)
- section = ID
- l = l[5:]
- msgid = msgstr = ''
- # Now we are in a msgstr section
- elif l.startswith('msgstr'):
- section = STR
- l = l[6:]
- # Skip empty lines
- if not l.strip():
- continue
- # TODO: Does this always follow Python escape semantics?
- l = eval(l)
- if section == ID:
- msgid += l
- elif section == STR:
- msgstr += '%s\n' % l
- else:
- print('Syntax error on %s:%d' % (infile, lno),
- 'before:', file=sys.stderr)
- print(l, file=sys.stderr)
- sys.exit(1)
- # Add last entry
- if section == STR:
- self.__add(msgid, msgstr, fuzzy)
-
- def evaluate(self, expression):
- try:
- return POEngine.evaluate(self, expression)
- except TALExpressionError:
- pass
-
- def evaluatePathOrVar(self, expr):
- return 'who cares'
-
- def translate(self, msgid, domain=None, mapping=None, default=None,
- position=None):
- if msgid not in self.base:
- POEngine.translate(self, msgid, domain, mapping, default, position)
- return 'x'
-
-
-def main():
- try:
- opts, args = getopt.getopt(
- sys.argv[1:],
- 'ho:u:',
- ['help', 'output=', 'update='])
- except getopt.error as msg:
- usage(1, msg)
-
- outfile = None
- engine = None
- update_mode = False
- for opt, arg in opts:
- if opt in ('-h', '--help'):
- usage(0)
- elif opt in ('-o', '--output'):
- outfile = arg
- elif opt in ('-u', '--update'):
- update_mode = True
- if outfile is None:
- outfile = arg
- engine = UpdatePOEngine(filename=arg)
-
- if not args:
- print('nothing to do')
- return
-
- # We don't care about the rendered output of the .pt file
- class Devnull(object):
- def write(self, s):
- pass
-
- # check if we've already instantiated an engine;
- # if not, use the stupidest one available
- if not engine:
- engine = POEngine()
-
- # process each file specified
- for filename in args:
- try:
- engine.file = filename
- p = HTMLTALParser()
- p.parseFile(filename)
- program, macros = p.getCode()
- POTALInterpreter(program, macros, engine, stream=Devnull(),
- metal=False)()
- except BaseException: # Hee hee, I love bare excepts!
- print('There was an error processing', filename)
- traceback.print_exc()
-
- # Now output the keys in the engine. Write them to a file if --output or
- # --update was specified; otherwise use standard out.
- if (outfile is None):
- outfile = sys.stdout
- else:
- outfile = file(outfile, update_mode and "a" or "w")
-
- catalog = {}
- for domain in engine.catalog:
- catalog.update(engine.catalog[domain])
-
- messages = catalog.copy()
- try:
- messages.update(engine.base)
- except AttributeError:
- pass
- if '' not in messages:
- print(pot_header % {'time': time.ctime(), 'version': __version__},
- file=outfile)
-
- # TODO: You should not sort by msgid, but by filename and position. (SR)
- msgids = sorted(catalog)
- for msgid in msgids:
- positions = engine.catalog[msgid]
- for filename, position in positions:
- outfile.write('#: %s:%s\n' % (filename, position[0]))
-
- outfile.write('msgid "%s"\n' % msgid)
- outfile.write('msgstr ""\n')
- outfile.write('\n')
-
-
-if __name__ == '__main__':
- main()