summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2000-03-08 15:18:35 (GMT)
committerBarry Warsaw <barry@python.org>2000-03-08 15:18:35 (GMT)
commita17e0f1b61add9a49f2f611c7baf42257a3979da (patch)
treed67608523f56301bc8c26ebe8c252fb54c1c4480 /Tools
parent34d11f0670cbfb1e72af5285b36f207f22fb99d2 (diff)
downloadcpython-a17e0f1b61add9a49f2f611c7baf42257a3979da.zip
cpython-a17e0f1b61add9a49f2f611c7baf42257a3979da.tar.gz
cpython-a17e0f1b61add9a49f2f611c7baf42257a3979da.tar.bz2
A bunch of changes, primarily to command line argument parsing
(inspired by Detlef Lannert). Specifically, -k/--keyword no longer takes an optional argument to clear the default keywords. Instead, use -K/--no-default-keywords to clear them. -n/--add-location also no longer takes an optional argument to set the comment style. Instead, use -S/--style to set the comment style to GNU or Solaris. -o/--output can take `-' as the filename, meaning write to standard output. The inputfile name can also be `-' meaning read from standard in. A few other changes include Kludge to mark the file docstring as translatable. Since the marking is to place _() around the docstring, and because we actually have to define the _() function before we use it, this means that we have to manually assign to __doc__ the output of _(). This doesn't seem too bad because you'll only use this idiom when translating a script's docstring (you really don't need to translate most module docstrings). Convert everything to string methods and do not import the string module. Bump the version number to 1.1
Diffstat (limited to 'Tools')
-rwxr-xr-xTools/i18n/pygettext.py164
1 files changed, 100 insertions, 64 deletions
diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py
index c39ce6e..422d773 100755
--- a/Tools/i18n/pygettext.py
+++ b/Tools/i18n/pygettext.py
@@ -4,7 +4,15 @@
# minimally patched to make it even more xgettext compatible
# by Peter Funk <pf@artcom-gmbh.de>
-"""pygettext -- Python equivalent of xgettext(1)
+# for selftesting
+try:
+ import fintl
+ _ = fintl.gettext
+except ImportError:
+ def _(s): return s
+
+
+__doc__ = _("""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
@@ -39,9 +47,11 @@ below for how to augment this.
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.
+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] filename ...
+Usage: pygettext [options] inputfile ...
Options:
@@ -61,33 +71,42 @@ Options:
--help
print this help message and exit
- -k [word]
- --keyword[=word]
- Additional keywords to look for. Without `word' means not to use the
- default keywords. The default keywords, which are always looked for
- if not explicitly disabled: _
+ -k word
+ --keyword=word
+ Keywords to look for in addition to the default set, which are:
+ %(DEFAULTKEYWORDS)s
+
+ You can have multiple -k flags on the command line.
- The default keyword list is different than GNU xgettext. You can have
- multiple -k flags on the command line.
+ -K
+ --no-default-keywords
+ Disable the default set of keywords (see above). Any keywords
+ explicitly added with the -k/--keyword option are still recognized.
--no-location
- Do not write filename/lineno location comments
+ Do not write filename/lineno location comments.
- -n [style]
- --add-location[=style]
+ -n
+ --add-location
Write filename/lineno location comments indicating where each
extracted string is found in the source. These lines appear before
- each msgid. Two styles are supported:
+ each msgid. The style of comments is controlled by the -S/--style
+ option. This is the default.
+
+ -S stylename
+ --style stylename
+ Specify which style to use for location comments. Two styles are
+ supported:
Solaris # File: filename, line: line-number
- Gnu #: filename:line
+ GNU #: filename:line
- If style is omitted, Gnu is used. The style name is case
- insensitive. By default, locations are included.
+ The style name is case insensitive. GNU style is the default.
-o filename
--output=filename
- Rename the default output file from messages.pot to filename.
+ Rename the default output file from messages.pot to filename. If
+ filename is `-' then the output is sent to standard out.
-p dir
--output-dir=dir
@@ -111,27 +130,25 @@ Options:
extracted from the input files. Each string to be excluded must
appear on a line by itself in the file.
-"""
+If `inputfile' is -, standard input is read.
+
+""")
import os
import sys
-import string
import time
import getopt
import tokenize
-__version__ = '1.0'
+__version__ = '1.1'
+default_keywords = ['_']
+DEFAULTKEYWORDS = ', '.join(default_keywords)
-
-# for selftesting
-try:
- import fintl
- _ = fintl.gettext
-except ImportError:
- def _(s): return s
+EMPTYSTRING = ''
+
# The normal pot-file header. msgmerge and EMACS' po-mode work better if
# it's there.
pot_header = _('''\
@@ -189,7 +206,7 @@ def escape(s):
s = list(s)
for i in range(len(s)):
s[i] = escapes[ord(s[i])]
- return string.join(s, '')
+ return EMPTYSTRING.join(s)
def safe_eval(s):
@@ -200,7 +217,7 @@ def safe_eval(s):
def normalize(s):
# This converts the various Python string types into a format that is
# appropriate for .po files, namely much closer to C style.
- lines = string.split(s, '\n')
+ lines = s.split('\n')
if len(lines) == 1:
s = '"' + escape(s) + '"'
else:
@@ -209,7 +226,8 @@ def normalize(s):
lines[-1] = lines[-1] + '\n'
for i in range(len(lines)):
lines[i] = escape(lines[i])
- s = '""\n"' + string.join(lines, '\\n"\n"') + '"'
+ lineterm = '\\n"\n"'
+ s = '""\n"' + lineterm.join(lines) + '"'
return s
@@ -245,7 +263,7 @@ class TokenEater:
# of messages seen. Reset state for the next batch. If there
# were no strings inside _(), then just ignore this entry.
if self.__data:
- msg = string.join(self.__data, '')
+ msg = EMPTYSTRING.join(self.__data)
if not msg in self.__options.toexclude:
entry = (self.__curfile, self.__lineno)
linenos = self.__messages.get(msg)
@@ -271,12 +289,14 @@ class TokenEater:
# as that generated by xgettext...
print pot_header % {'time': timestamp, 'version': __version__}
for k, v in self.__messages.items():
+ if not options.writelocations:
+ pass
# location comments are different b/w Solaris and GNU:
- if options.location == options.SOLARIS:
+ elif options.locationstyle == options.SOLARIS:
for filename, lineno in v:
d = {'filename': filename, 'lineno': lineno}
print _('# File: %(filename)s, line: %(lineno)d') % d
- elif options.location == options.GNU:
+ elif options.locationstyle == options.GNU:
# fit as many locations on one line, as long as the
# resulting line length doesn't exceeds 'options.width'
locline = '#:'
@@ -298,14 +318,15 @@ class TokenEater:
def main():
- default_keywords = ['_']
+ global default_keywords
try:
opts, args = getopt.getopt(
sys.argv[1:],
- 'ad:Ehk:n:o:p:Vvw:x:',
- ['extract-all', 'default-domain', 'escape', 'help', 'keyword',
+ 'ad:Ehk:Kno:p:S:Vvw:x:',
+ ['extract-all', 'default-domain', 'escape', 'help',
+ 'keyword=', 'no-default-keywords',
'add-location', 'no-location', 'output=', 'output-dir=',
- 'verbose', 'version', 'width=', 'exclude-file=',
+ 'style=', 'verbose', 'version', 'width=', 'exclude-file=',
])
except getopt.error, msg:
usage(1, msg)
@@ -321,7 +342,8 @@ def main():
keywords = []
outpath = ''
outfile = 'messages.pot'
- location = GNU
+ writelocations = 1
+ locationstyle = GNU
verbose = 0
width = 78
excludefilename = ''
@@ -342,19 +364,17 @@ def main():
elif opt in ('-E', '--escape'):
options.escape = 1
elif opt in ('-k', '--keyword'):
- if arg is None:
- default_keywords = []
options.keywords.append(arg)
+ elif opt in ('-K', '--no-default-keywords'):
+ default_keywords = []
elif opt in ('-n', '--add-location'):
- if arg is None:
- arg = 'gnu'
- try:
- options.location = locations[string.lower(arg)]
- except KeyError:
- d = {'arg':arg}
- usage(1, _('Invalid value for --add-location: %(arg)s') % d)
+ options.writelocations = 1
elif opt in ('--no-location',):
- options.location = 0
+ options.writelocations = 0
+ elif opt in ('-S', '--style'):
+ options.locationstyle = locations.get(arg.lower())
+ if options.locationstyle is None:
+ usage(1, _('Invalid value for --style: %s') % arg)
elif opt in ('-o', '--output'):
options.outfile = arg
elif opt in ('-p', '--output-dir'):
@@ -368,9 +388,7 @@ def main():
try:
options.width = int(arg)
except ValueError:
- d = {'arg':arg}
- usage(1, _('Invalid value for --width: %(arg)s, must be int')
- % d)
+ usage(1, _('--width argument must be an integer: %s') % arg)
elif opt in ('-x', '--exclude-file'):
options.excludefilename = arg
@@ -396,19 +414,37 @@ def main():
# slurp through all the files
eater = TokenEater(options)
for filename in args:
- if options.verbose:
- print _('Working on %(filename)s') % {'filename':filename}
- fp = open(filename)
- eater.set_filename(filename)
- tokenize.tokenize(fp.readline, eater)
- fp.close()
-
- if options.outpath:
- options.outfile = os.path.join(options.outpath, options.outfile)
- fp = open(options.outfile, 'w')
- eater.write(fp)
- fp.close()
+ 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)
+ tokenize.tokenize(fp.readline, eater)
+ 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__':