Index: Tools/i18n/pygettext.py =================================================================== --- Tools/i18n/pygettext.py (revision 82959) +++ Tools/i18n/pygettext.py (working copy) @@ -12,6 +12,11 @@ # directory (including globbing chars, important for Win32). # Made docstring fit in 80 chars wide displays using pydoc. # +# 2005-01-08 Martin Blais +# Added option to allow extration of multi-line strings as if +# they were single strings (this makes translation more fun +# if the strings are used for HTML anyway). +# # for selftesting try: @@ -102,6 +107,21 @@ --no-location Do not write filename/lineno location comments. + -l word + --keyword-single=word + Keywords to look for for single-line lookup. + + You can have multiple -l flags on the command line. + + Strings matched using single-line keywords are meant to be looked up by + joining all multiple lines in single lines. This will require a + corresponding query function at runtime, but is a bit cleaner when the + query strings are all for HTML output and we want to avoid the + restrictions of the GNU gettext for multiple lines (because it doesn't + matter since the output will be justified regardless of source text, + like for HTML) and when we don't want the translators to see the + newlines when translating (because they should not bother with them). + -n --add-location Write filename/lineno location comments indicating where each @@ -256,6 +276,22 @@ s = '""\n"' + lineterm.join(lines) + '"' return s +def normalize_single(s): + return '"%s"' % genkey_single(s) + +def genkey_single(s): + lines = s.split('\n') + if len(lines) == 1: + s = '%s' % escape(s).strip() + else: + newlines = [] + for i in range(len(lines)): + l = escape(lines[i]).strip() + if l: + newlines.append(l) + s = '%s' % ' '.join(newlines) + return s + def containsAny(str, set): """Check whether 'str' contains ANY of the chars in 'set'""" @@ -359,6 +395,7 @@ self.__lineno = -1 self.__freshmodule = 1 self.__curfile = None + self.__single = 0 def __call__(self, ttype, tstring, stup, etup, line): # dispatch @@ -383,8 +420,13 @@ if ttype == tokenize.NAME and tstring in ('class', 'def'): self.__state = self.__suiteseen return - if ttype == tokenize.NAME and tstring in opts.keywords: - self.__state = self.__keywordseen + if ttype == tokenize.NAME: + if tstring in opts.keywords: + self.__state = self.__keywordseen + self.__single = 0 + elif tstring in opts.keywords_single: + self.__state = self.__keywordseen + self.__single = 1 def __suiteseen(self, ttype, tstring, lineno): # ignore anything until we see the colon @@ -416,7 +458,7 @@ # of messages seen. Reset state for the next batch. If there # were no strings inside _(), then just ignore this entry. if self.__data: - self.__addentry(EMPTYSTRING.join(self.__data)) + self.__addentry(EMPTYSTRING.join(self.__data), single=self.__single) self.__state = self.__waiting elif ttype == tokenize.STRING: self.__data.append(safe_eval(tstring)) @@ -432,12 +474,15 @@ }, file=sys.stderr) self.__state = self.__waiting - def __addentry(self, msg, lineno=None, isdocstring=0): + def __addentry(self, msg, lineno=None, isdocstring=0, single=0): if lineno is None: lineno = self.__lineno if not msg in self.__options.toexclude: entry = (self.__curfile, lineno) - self.__messages.setdefault(msg, {})[entry] = isdocstring + if single: + msg = genkey_single(msg) + msgkey = (msg, single) + self.__messages.setdefault(msgkey, {})[entry] = isdocstring def set_filename(self, filename): self.__curfile = filename @@ -492,7 +537,11 @@ print(locline, file=fp) if isdocstring: print('#, docstring', file=fp) - print('msgid', normalize(k), file=fp) + msg, single = k + if single: + print('msgid', normalize_single(msg), file=fp) + else: + print('msgid', normalize(k), file=fp) print('msgstr ""\n', file=fp) @@ -502,9 +551,9 @@ try: opts, args = getopt.getopt( sys.argv[1:], - 'ad:DEhk:Kno:p:S:Vvw:x:X:', + 'ad:DEhk:Klno:p:S:Vvw:x:X:', ['extract-all', 'default-domain=', 'escape', 'help', - 'keyword=', 'no-default-keywords', + 'keyword=', 'keyword-single=', 'no-default-keywords', 'add-location', 'no-location', 'output=', 'output-dir=', 'style=', 'verbose', 'version', 'width=', 'exclude-file=', 'docstrings', 'no-docstrings', @@ -521,6 +570,7 @@ extractall = 0 # FIXME: currently this option has no effect at all. escape = 0 keywords = [] + keywords_single = [] outpath = '' outfile = 'messages.pot' writelocations = 1 @@ -550,6 +600,8 @@ options.docstrings = 1 elif opt in ('-k', '--keyword'): options.keywords.append(arg) + elif opt in ('-l', '--keyword-single'): + options.keywords_single.append(arg) elif opt in ('-K', '--no-default-keywords'): default_keywords = [] elif opt in ('-n', '--add-location'):