annotate genshi/filters/i18n.py @ 820:1837f39efd6f experimental-inline

Sync (old) experimental inline branch with trunk@1027.
author cmlenz
date Wed, 11 Mar 2009 17:51:06 +0000
parents 0742f421caba
children 09cc3627654c
rev   line source
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1 # -*- coding: utf-8 -*-
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
2 #
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
3 # Copyright (C) 2007 Edgewall Software
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
4 # All rights reserved.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
5 #
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
6 # This software is licensed as described in the file COPYING, which
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
7 # you should have received as part of this distribution. The terms
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
9 #
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
10 # This software consists of voluntary contributions made by many
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
11 # individuals. For the exact contribution history, see the revision
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
13
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
14 """Utilities for internationalization and localization of templates.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
15
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
16 :since: version 0.4
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
17 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
18
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
19 from gettext import NullTranslations
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
20 import re
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
21 from types import FunctionType
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
22
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
23 from genshi.core import Attrs, Namespace, QName, START, END, TEXT, START_NS, \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
24 END_NS, XML_NAMESPACE, _ensure
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
25 from genshi.template.eval import _ast
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
26 from genshi.template.base import DirectiveFactory, EXPR, SUB, _apply_directives
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
27 from genshi.template.directives import Directive
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
28 from genshi.template.markup import MarkupTemplate, EXEC
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
29
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
30 __all__ = ['Translator', 'extract']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
31 __docformat__ = 'restructuredtext en'
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
32
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
33 I18N_NAMESPACE = Namespace('http://genshi.edgewall.org/i18n')
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
34
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
35
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
36 class CommentDirective(Directive):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
37
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
38 __slots__ = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
39
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
40 @classmethod
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
41 def attach(cls, template, stream, value, namespaces, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
42 return None, stream
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
43
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
44
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
45 class MsgDirective(Directive):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
46
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
47 __slots__ = ['params']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
48
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
49 def __init__(self, value, template, hints=None, namespaces=None,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
50 lineno=-1, offset=-1):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
51 Directive.__init__(self, None, template, namespaces, lineno, offset)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
52 self.params = [name.strip() for name in value.split(',')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
53
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
54 def __call__(self, stream, directives, ctxt, **vars):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
55 msgbuf = MessageBuffer(self.params)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
56
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
57 stream = iter(stream)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
58 yield stream.next() # the outer start tag
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
59 previous = stream.next()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
60 for event in stream:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
61 msgbuf.append(*previous)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
62 previous = event
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
63
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
64 gettext = ctxt.get('_i18n.gettext')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
65 for event in msgbuf.translate(gettext(msgbuf.format())):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
66 yield event
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
67
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
68 yield previous # the outer end tag
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
69
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
70
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
71 class Translator(DirectiveFactory):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
72 """Can extract and translate localizable strings from markup streams and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
73 templates.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
74
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
75 For example, assume the followng template:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
76
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
77 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
78 >>>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
79 >>> tmpl = MarkupTemplate('''<html xmlns:py="http://genshi.edgewall.org/">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
80 ... <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
81 ... <title>Example</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
82 ... </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
83 ... <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
84 ... <h1>Example</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
85 ... <p>${_("Hello, %(name)s") % dict(name=username)}</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
86 ... </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
87 ... </html>''', filename='example.html')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
88
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
89 For demonstration, we define a dummy ``gettext``-style function with a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
90 hard-coded translation table, and pass that to the `Translator` initializer:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
91
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
92 >>> def pseudo_gettext(string):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
93 ... return {
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
94 ... 'Example': 'Beispiel',
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
95 ... 'Hello, %(name)s': 'Hallo, %(name)s'
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
96 ... }[string]
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
97 >>>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
98 >>> translator = Translator(pseudo_gettext)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
99
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
100 Next, the translator needs to be prepended to any already defined filters
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
101 on the template:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
102
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
103 >>> tmpl.filters.insert(0, translator)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
104
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
105 When generating the template output, our hard-coded translations should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
106 applied as expected:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
107
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
108 >>> print tmpl.generate(username='Hans', _=pseudo_gettext)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
109 <html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
110 <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
111 <title>Beispiel</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
112 </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
113 <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
114 <h1>Beispiel</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
115 <p>Hallo, Hans</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
116 </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
117 </html>
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
118
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
119 Note that elements defining ``xml:lang`` attributes that do not contain
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
120 variable expressions are ignored by this filter. That can be used to
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
121 exclude specific parts of a template from being extracted and translated.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
122 """
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
123
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
124 directives = [
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
125 ('comment', CommentDirective),
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
126 ('msg', MsgDirective)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
127 ]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
128
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
129 IGNORE_TAGS = frozenset([
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
130 QName('script'), QName('http://www.w3.org/1999/xhtml}script'),
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
131 QName('style'), QName('http://www.w3.org/1999/xhtml}style')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
132 ])
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
133 INCLUDE_ATTRS = frozenset(['abbr', 'alt', 'label', 'prompt', 'standby',
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
134 'summary', 'title'])
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
135 NAMESPACE = I18N_NAMESPACE
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
136
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
137 def __init__(self, translate=NullTranslations(), ignore_tags=IGNORE_TAGS,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
138 include_attrs=INCLUDE_ATTRS, extract_text=True):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
139 """Initialize the translator.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
140
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
141 :param translate: the translation function, for example ``gettext`` or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
142 ``ugettext``.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
143 :param ignore_tags: a set of tag names that should not be localized
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
144 :param include_attrs: a set of attribute names should be localized
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
145 :param extract_text: whether the content of text nodes should be
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
146 extracted, or only text in explicit ``gettext``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
147 function calls
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
148
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
149 :note: Changed in 0.6: the `translate` parameter can now be either
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
150 a ``gettext``-style function, or an object compatible with the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
151 ``NullTransalations`` or ``GNUTranslations`` interface
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
152 """
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
153 self.translate = translate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
154 self.ignore_tags = ignore_tags
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
155 self.include_attrs = include_attrs
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
156 self.extract_text = extract_text
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
157
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
158 def __call__(self, stream, ctxt=None, search_text=True):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
159 """Translate any localizable strings in the given stream.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
160
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
161 This function shouldn't be called directly. Instead, an instance of
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
162 the `Translator` class should be registered as a filter with the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
163 `Template` or the `TemplateLoader`, or applied as a regular stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
164 filter. If used as a template filter, it should be inserted in front of
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
165 all the default filters.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
166
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
167 :param stream: the markup event stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
168 :param ctxt: the template context (not used)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
169 :param search_text: whether text nodes should be translated (used
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
170 internally)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
171 :return: the localized stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
172 """
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
173 ignore_tags = self.ignore_tags
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
174 include_attrs = self.include_attrs
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
175 skip = 0
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
176 xml_lang = XML_NAMESPACE['lang']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
177
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
178 if type(self.translate) is FunctionType:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
179 gettext = self.translate
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
180 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
181 gettext = self.translate.ugettext
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
182 if ctxt:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
183 ctxt['_i18n.gettext'] = gettext
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
184
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
185 extract_text = self.extract_text
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
186 if not extract_text:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
187 search_text = False
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
188
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
189 for kind, data, pos in stream:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
190
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
191 # skip chunks that should not be localized
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
192 if skip:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
193 if kind is START:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
194 skip += 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
195 elif kind is END:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
196 skip -= 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
197 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
198 continue
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
199
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
200 # handle different events that can be localized
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
201 if kind is START:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
202 tag, attrs = data
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
203 if tag in self.ignore_tags or \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
204 isinstance(attrs.get(xml_lang), basestring):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
205 skip += 1
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
206 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
207 continue
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
208
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
209 new_attrs = []
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
210 changed = False
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
211 for name, value in attrs:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
212 newval = value
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
213 if extract_text and isinstance(value, basestring):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
214 if name in include_attrs:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
215 newval = gettext(value)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
216 else:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
217 newval = list(self(_ensure(value), ctxt,
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
218 search_text=False)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
219 )
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
220 if newval != value:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
221 value = newval
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
222 changed = True
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
223 new_attrs.append((name, value))
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
224 if changed:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
225 attrs = Attrs(new_attrs)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
226
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
227 yield kind, (tag, attrs), pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
228
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
229 elif search_text and kind is TEXT:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
230 text = data.strip()
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
231 if text:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
232 data = data.replace(text, unicode(gettext(text)))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
233 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
234
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
235 elif kind is SUB:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
236 directives, substream = data
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
237 # If this is an i18n:msg directive, no need to translate text
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
238 # nodes here
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
239 is_msg = filter(None, [isinstance(d, MsgDirective)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
240 for d in directives])
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
241 substream = list(self(substream, ctxt,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
242 search_text=not is_msg))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
243 yield kind, (directives, substream), pos
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
244
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
245 else:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
246 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
247
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
248 GETTEXT_FUNCTIONS = ('_', 'gettext', 'ngettext', 'dgettext', 'dngettext',
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
249 'ugettext', 'ungettext')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
250
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
251 def extract(self, stream, gettext_functions=GETTEXT_FUNCTIONS,
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
252 search_text=True, msgbuf=None):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
253 """Extract localizable strings from the given template stream.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
254
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
255 For every string found, this function yields a ``(lineno, function,
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
256 message, comments)`` tuple, where:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
257
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
258 * ``lineno`` is the number of the line on which the string was found,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
259 * ``function`` is the name of the ``gettext`` function used (if the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
260 string was extracted from embedded Python code), and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
261 * ``message`` is the string itself (a ``unicode`` object, or a tuple
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
262 of ``unicode`` objects for functions with multiple string
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
263 arguments).
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
264 * ``comments`` is a list of comments related to the message, extracted
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
265 from ``i18n:comment`` attributes found in the markup
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
266
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
267 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
268 >>>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
269 >>> tmpl = MarkupTemplate('''<html xmlns:py="http://genshi.edgewall.org/">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
270 ... <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
271 ... <title>Example</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
272 ... </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
273 ... <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
274 ... <h1>Example</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
275 ... <p>${_("Hello, %(name)s") % dict(name=username)}</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
276 ... <p>${ngettext("You have %d item", "You have %d items", num)}</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
277 ... </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
278 ... </html>''', filename='example.html')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
279 >>>
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
280 >>> for line, func, msg, comments in Translator().extract(tmpl.stream):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
281 ... print "%d, %r, %r" % (line, func, msg)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
282 3, None, u'Example'
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
283 6, None, u'Example'
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
284 7, '_', u'Hello, %(name)s'
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
285 8, 'ngettext', (u'You have %d item', u'You have %d items', None)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
286
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
287 :param stream: the event stream to extract strings from; can be a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
288 regular stream or a template stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
289 :param gettext_functions: a sequence of function names that should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
290 treated as gettext-style localization
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
291 functions
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
292 :param search_text: whether the content of text nodes should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
293 extracted (used internally)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
294
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
295 :note: Changed in 0.4.1: For a function with multiple string arguments
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
296 (such as ``ngettext``), a single item with a tuple of strings is
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
297 yielded, instead an item for each string argument.
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
298 :note: Changed in 0.6: The returned tuples now include a 4th element,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
299 which is a list of comments for the translator
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
300 """
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
301 if not self.extract_text:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
302 search_text = False
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
303 skip = 0
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
304 i18n_comment = I18N_NAMESPACE['comment']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
305 i18n_msg = I18N_NAMESPACE['msg']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
306 xml_lang = XML_NAMESPACE['lang']
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
307
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
308 for kind, data, pos in stream:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
309
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
310 if skip:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
311 if kind is START:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
312 skip += 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
313 if kind is END:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
314 skip -= 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
315
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
316 if kind is START and not skip:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
317 tag, attrs = data
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
318
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
319 if tag in self.ignore_tags or \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
320 isinstance(attrs.get(xml_lang), basestring):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
321 skip += 1
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
322 continue
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
323
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
324 for name, value in attrs:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
325 if search_text and isinstance(value, basestring):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
326 if name in self.include_attrs:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
327 text = value.strip()
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
328 if text:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
329 yield pos[1], None, text, []
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
330 else:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
331 for lineno, funcname, text, comments in self.extract(
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
332 _ensure(value), gettext_functions,
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
333 search_text=False):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
334 yield lineno, funcname, text, comments
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
335
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
336 if msgbuf:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
337 msgbuf.append(kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
338 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
339 msg_params = attrs.get(i18n_msg)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
340 if msg_params is not None:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
341 if type(msg_params) is list: # event tuple
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
342 msg_params = msg_params[0][1]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
343 msgbuf = MessageBuffer(
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
344 msg_params, attrs.get(i18n_comment), pos[1]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
345 )
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
346
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
347 elif not skip and search_text and kind is TEXT:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
348 if not msgbuf:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
349 text = data.strip()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
350 if text and filter(None, [ch.isalpha() for ch in text]):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
351 yield pos[1], None, text, []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
352 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
353 msgbuf.append(kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
354
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
355 elif not skip and msgbuf and kind is END:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
356 msgbuf.append(kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
357 if not msgbuf.depth:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
358 yield msgbuf.lineno, None, msgbuf.format(), \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
359 filter(None, [msgbuf.comment])
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
360 msgbuf = None
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
361
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
362 elif kind is EXPR or kind is EXEC:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
363 if msgbuf:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
364 msgbuf.append(kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
365 for funcname, strings in extract_from_code(data,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
366 gettext_functions):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
367 yield pos[1], funcname, strings, []
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
368
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
369 elif kind is SUB:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
370 subkind, substream = data
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
371 messages = self.extract(substream, gettext_functions,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
372 search_text=search_text and not skip,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
373 msgbuf=msgbuf)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
374 for lineno, funcname, text, comments in messages:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
375 yield lineno, funcname, text, comments
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
376
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
377
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
378 class MessageBuffer(object):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
379 """Helper class for managing internationalized mixed content.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
380
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
381 :since: version 0.5
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
382 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
383
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
384 def __init__(self, params=u'', comment=None, lineno=-1):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
385 """Initialize the message buffer.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
386
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
387 :param params: comma-separated list of parameter names
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
388 :type params: `basestring`
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
389 :param lineno: the line number on which the first stream event
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
390 belonging to the message was found
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
391 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
392 if isinstance(params, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
393 params = [name.strip() for name in params.split(',')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
394 self.params = params
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
395 self.comment = comment
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
396 self.lineno = lineno
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
397 self.string = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
398 self.events = {}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
399 self.values = {}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
400 self.depth = 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
401 self.order = 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
402 self.stack = [0]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
403
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
404 def append(self, kind, data, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
405 """Append a stream event to the buffer.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
406
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
407 :param kind: the stream event kind
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
408 :param data: the event data
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
409 :param pos: the position of the event in the source
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
410 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
411 if kind is TEXT:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
412 self.string.append(data)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
413 self.events.setdefault(self.stack[-1], []).append(None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
414 elif kind is EXPR:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
415 param = self.params.pop(0)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
416 self.string.append('%%(%s)s' % param)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
417 self.events.setdefault(self.stack[-1], []).append(None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
418 self.values[param] = (kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
419 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
420 if kind is START:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
421 self.string.append(u'[%d:' % self.order)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
422 self.events.setdefault(self.order, []).append((kind, data, pos))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
423 self.stack.append(self.order)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
424 self.depth += 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
425 self.order += 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
426 elif kind is END:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
427 self.depth -= 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
428 if self.depth:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
429 self.events[self.stack[-1]].append((kind, data, pos))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
430 self.string.append(u']')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
431 self.stack.pop()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
432
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
433 def format(self):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
434 """Return a message identifier representing the content in the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
435 buffer.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
436 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
437 return u''.join(self.string).strip()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
438
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
439 def translate(self, string, regex=re.compile(r'%\((\w+)\)s')):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
440 """Interpolate the given message translation with the events in the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
441 buffer and return the translated stream.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
442
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
443 :param string: the translated message string
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
444 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
445 parts = parse_msg(string)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
446 for order, string in parts:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
447 events = self.events[order]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
448 while events:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
449 event = events.pop(0)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
450 if event:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
451 yield event
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
452 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
453 if not string:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
454 break
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
455 for idx, part in enumerate(regex.split(string)):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
456 if idx % 2:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
457 yield self.values[part]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
458 elif part:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
459 yield TEXT, part, (None, -1, -1)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
460 if not self.events[order] or not self.events[order][0]:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
461 break
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
462
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
463
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
464 def parse_msg(string, regex=re.compile(r'(?:\[(\d+)\:)|\]')):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
465 """Parse a translated message using Genshi mixed content message
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
466 formatting.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
467
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
468 >>> parse_msg("See [1:Help].")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
469 [(0, 'See '), (1, 'Help'), (0, '.')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
470
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
471 >>> parse_msg("See [1:our [2:Help] page] for details.")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
472 [(0, 'See '), (1, 'our '), (2, 'Help'), (1, ' page'), (0, ' for details.')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
473
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
474 >>> parse_msg("[2:Details] finden Sie in [1:Hilfe].")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
475 [(2, 'Details'), (0, ' finden Sie in '), (1, 'Hilfe'), (0, '.')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
476
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
477 >>> parse_msg("[1:] Bilder pro Seite anzeigen.")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
478 [(1, ''), (0, ' Bilder pro Seite anzeigen.')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
479
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
480 :param string: the translated message string
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
481 :return: a list of ``(order, string)`` tuples
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
482 :rtype: `list`
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
483 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
484 parts = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
485 stack = [0]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
486 while True:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
487 mo = regex.search(string)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
488 if not mo:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
489 break
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
490
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
491 if mo.start() or stack[-1]:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
492 parts.append((stack[-1], string[:mo.start()]))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
493 string = string[mo.end():]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
494
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
495 orderno = mo.group(1)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
496 if orderno is not None:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
497 stack.append(int(orderno))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
498 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
499 stack.pop()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
500 if not stack:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
501 break
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
502
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
503 if string:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
504 parts.append((stack[-1], string))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
505
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
506 return parts
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
507
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
508
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
509 def extract_from_code(code, gettext_functions):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
510 """Extract strings from Python bytecode.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
511
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
512 >>> from genshi.template.eval import Expression
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
513
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
514 >>> expr = Expression('_("Hello")')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
515 >>> list(extract_from_code(expr, Translator.GETTEXT_FUNCTIONS))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
516 [('_', u'Hello')]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
517
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
518 >>> expr = Expression('ngettext("You have %(num)s item", '
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
519 ... '"You have %(num)s items", num)')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
520 >>> list(extract_from_code(expr, Translator.GETTEXT_FUNCTIONS))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
521 [('ngettext', (u'You have %(num)s item', u'You have %(num)s items', None))]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
522
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
523 :param code: the `Code` object
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
524 :type code: `genshi.template.eval.Code`
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
525 :param gettext_functions: a sequence of function names
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
526 :since: version 0.5
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
527 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
528 def _walk(node):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
529 if isinstance(node, _ast.Call) and isinstance(node.func, _ast.Name) \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
530 and node.func.id in gettext_functions:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
531 strings = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
532 def _add(arg):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
533 if isinstance(arg, _ast.Str) and isinstance(arg.s, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
534 strings.append(unicode(arg.s, 'utf-8'))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
535 elif arg:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
536 strings.append(None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
537 [_add(arg) for arg in node.args]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
538 _add(node.starargs)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
539 _add(node.kwargs)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
540 if len(strings) == 1:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
541 strings = strings[0]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
542 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
543 strings = tuple(strings)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
544 yield node.func.id, strings
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
545 elif node._fields:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
546 children = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
547 for field in node._fields:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
548 child = getattr(node, field, None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
549 if isinstance(child, list):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
550 for elem in child:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
551 children.append(elem)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
552 elif isinstance(child, _ast.AST):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
553 children.append(child)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
554 for child in children:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
555 for funcname, strings in _walk(child):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
556 yield funcname, strings
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
557 return _walk(code.ast)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
558
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
559
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
560 def extract(fileobj, keywords, comment_tags, options):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
561 """Babel extraction method for Genshi templates.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
562
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
563 :param fileobj: the file-like object the messages should be extracted from
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
564 :param keywords: a list of keywords (i.e. function names) that should be
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
565 recognized as translation functions
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
566 :param comment_tags: a list of translator tags to search for and include
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
567 in the results
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
568 :param options: a dictionary of additional options (optional)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
569 :return: an iterator over ``(lineno, funcname, message, comments)`` tuples
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
570 :rtype: ``iterator``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
571 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
572 template_class = options.get('template_class', MarkupTemplate)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
573 if isinstance(template_class, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
574 module, clsname = template_class.split(':', 1)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
575 template_class = getattr(__import__(module, {}, {}, [clsname]), clsname)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
576 encoding = options.get('encoding', None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
577
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
578 extract_text = options.get('extract_text', True)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
579 if isinstance(extract_text, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
580 extract_text = extract_text.lower() in ('1', 'on', 'yes', 'true')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
581
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
582 ignore_tags = options.get('ignore_tags', Translator.IGNORE_TAGS)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
583 if isinstance(ignore_tags, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
584 ignore_tags = ignore_tags.split()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
585 ignore_tags = [QName(tag) for tag in ignore_tags]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
586
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
587 include_attrs = options.get('include_attrs', Translator.INCLUDE_ATTRS)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
588 if isinstance(include_attrs, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
589 include_attrs = include_attrs.split()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
590 include_attrs = [QName(attr) for attr in include_attrs]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
591
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
592 tmpl = template_class(fileobj, filename=getattr(fileobj, 'name', None),
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
593 encoding=encoding)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
594 translator = Translator(None, ignore_tags, include_attrs, extract_text)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
595 for message in translator.extract(tmpl.stream, gettext_functions=keywords):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
596 yield message
Copyright (C) 2012-2017 Edgewall Software