annotate genshi/filters/i18n.py @ 902:09cc3627654c experimental-inline

Sync `experimental/inline` branch with [source:trunk@1126].
author cmlenz
date Fri, 23 Apr 2010 21:08:26 +0000
parents 1837f39efd6f
children
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 #
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
3 # Copyright (C) 2007-2010 Edgewall Software
820
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
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
14 """Directives and utilities for internationalization and localization of
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
15 templates.
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
16
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
17 :since: version 0.4
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
18 :note: Directives support added since version 0.6
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
19 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
20
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
21 try:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
22 any
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
23 except NameError:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
24 from genshi.util import any
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
25 from gettext import NullTranslations
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
26 import os
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
27 import re
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
28 from types import FunctionType
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
29
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
30 from genshi.core import Attrs, Namespace, QName, START, END, TEXT, \
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
31 XML_NAMESPACE, _ensure, StreamEventKind
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
32 from genshi.template.eval import _ast
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
33 from genshi.template.base import DirectiveFactory, EXPR, SUB, _apply_directives
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
34 from genshi.template.directives import Directive, StripDirective
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
35 from genshi.template.markup import MarkupTemplate, EXEC
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
36
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
37 __all__ = ['Translator', 'extract']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
38 __docformat__ = 'restructuredtext en'
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
39
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
40
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
41 I18N_NAMESPACE = Namespace('http://genshi.edgewall.org/i18n')
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
42
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
43 MSGBUF = StreamEventKind('MSGBUF')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
44 SUB_START = StreamEventKind('SUB_START')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
45 SUB_END = StreamEventKind('SUB_END')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
46
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
47 GETTEXT_FUNCTIONS = ('_', 'gettext', 'ngettext', 'dgettext', 'dngettext',
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
48 'ugettext', 'ungettext')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
49
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
50
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
51 class I18NDirective(Directive):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
52 """Simple interface for i18n directives to support messages extraction."""
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
53
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
54 def __call__(self, stream, directives, ctxt, **vars):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
55 return _apply_directives(stream, directives, ctxt, vars)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
56
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
57
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
58 class ExtractableI18NDirective(I18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
59 """Simple interface for directives to support messages extraction."""
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
60
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
61 def extract(self, translator, stream, gettext_functions=GETTEXT_FUNCTIONS,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
62 search_text=True, comment_stack=None):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
63 raise NotImplementedError
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
64
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
65
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
66 class CommentDirective(I18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
67 """Implementation of the ``i18n:comment`` template directive which adds
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
68 translation comments.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
69
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
70 >>> tmpl = MarkupTemplate('''<html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
71 ... <p i18n:comment="As in Foo Bar">Foo</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
72 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
73 >>> translator = Translator()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
74 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
75 >>> list(translator.extract(tmpl.stream))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
76 [(2, None, u'Foo', [u'As in Foo Bar'])]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
77 """
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
78 __slots__ = ['comment']
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
79
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
80 def __init__(self, value, template=None, namespaces=None, lineno=-1,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
81 offset=-1):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
82 Directive.__init__(self, None, template, namespaces, lineno, offset)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
83 self.comment = value
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
84
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
85
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
86 class MsgDirective(ExtractableI18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
87 r"""Implementation of the ``i18n:msg`` directive which marks inner content
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
88 as translatable. Consider the following examples:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
89
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
90 >>> tmpl = MarkupTemplate('''<html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
91 ... <div i18n:msg="">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
92 ... <p>Foo</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
93 ... <p>Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
94 ... </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
95 ... <p i18n:msg="">Foo <em>bar</em>!</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
96 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
97
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
98 >>> translator = Translator()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
99 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
100 >>> list(translator.extract(tmpl.stream))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
101 [(2, None, u'[1:Foo]\n [2:Bar]', []), (6, None, u'Foo [1:bar]!', [])]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
102 >>> print(tmpl.generate().render())
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
103 <html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
104 <div><p>Foo</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
105 <p>Bar</p></div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
106 <p>Foo <em>bar</em>!</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
107 </html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
108
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
109 >>> tmpl = MarkupTemplate('''<html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
110 ... <div i18n:msg="fname, lname">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
111 ... <p>First Name: ${fname}</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
112 ... <p>Last Name: ${lname}</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
113 ... </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
114 ... <p i18n:msg="">Foo <em>bar</em>!</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
115 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
116 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
117 >>> list(translator.extract(tmpl.stream)) #doctest: +NORMALIZE_WHITESPACE
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
118 [(2, None, u'[1:First Name: %(fname)s]\n [2:Last Name: %(lname)s]', []),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
119 (6, None, u'Foo [1:bar]!', [])]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
120
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
121 >>> tmpl = MarkupTemplate('''<html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
122 ... <div i18n:msg="fname, lname">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
123 ... <p>First Name: ${fname}</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
124 ... <p>Last Name: ${lname}</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
125 ... </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
126 ... <p i18n:msg="">Foo <em>bar</em>!</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
127 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
128 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
129 >>> print(tmpl.generate(fname='John', lname='Doe').render())
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
130 <html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
131 <div><p>First Name: John</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
132 <p>Last Name: Doe</p></div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
133 <p>Foo <em>bar</em>!</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
134 </html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
135
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
136 Starting and ending white-space is stripped of to make it simpler for
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
137 translators. Stripping it is not that important since it's on the html
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
138 source, the rendered output will remain the same.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
139 """
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
140 __slots__ = ['params', 'lineno']
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
141
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
142 def __init__(self, value, template=None, namespaces=None, lineno=-1,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
143 offset=-1):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
144 Directive.__init__(self, None, template, namespaces, lineno, offset)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
145 self.params = [param.strip() for param in value.split(',') if param]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
146 self.lineno = lineno
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
147
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
148 @classmethod
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
149 def attach(cls, template, stream, value, namespaces, pos):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
150 if type(value) is dict:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
151 value = value.get('params', '').strip()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
152 return super(MsgDirective, cls).attach(template, stream, value.strip(),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
153 namespaces, pos)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
154
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
155 def __call__(self, stream, directives, ctxt, **vars):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
156 gettext = ctxt.get('_i18n.gettext')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
157 if ctxt.get('_i18n.domain'):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
158 dgettext = ctxt.get('_i18n.dgettext')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
159 assert hasattr(dgettext, '__call__'), \
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
160 'No domain gettext function passed'
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
161 gettext = lambda msg: dgettext(ctxt.get('_i18n.domain'), msg)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
162
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
163 def _generate():
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
164 msgbuf = MessageBuffer(self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
165 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
166 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
167 yield previous
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
168 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
169 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
170 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
171 for kind, data, pos in stream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
172 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
173 previous = kind, data, pos
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
174 if previous[0] is not END:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
175 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
176 previous = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
177 for event in msgbuf.translate(gettext(msgbuf.format())):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
178 yield event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
179 if previous:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
180 yield previous
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
181
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
182 return _apply_directives(_generate(), directives, ctxt, vars)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
183
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
184 def extract(self, translator, stream, gettext_functions=GETTEXT_FUNCTIONS,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
185 search_text=True, comment_stack=None):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
186 msgbuf = MessageBuffer(self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
187 strip = False
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
188
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
189 stream = iter(stream)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
190 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
191 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
192 for message in translator._extract_attrs(previous,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
193 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
194 search_text=search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
195 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
196 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
197 strip = True
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
198 for event in stream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
199 if event[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
200 for message in translator._extract_attrs(event,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
201 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
202 search_text=search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
203 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
204 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
205 previous = event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
206 if not strip:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
207 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
208
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
209 yield self.lineno, None, msgbuf.format(), comment_stack[-1:]
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
210
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
211
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
212 class ChooseBranchDirective(I18NDirective):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
213 __slots__ = ['params']
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
214
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
215 def __call__(self, stream, directives, ctxt, **vars):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
216 self.params = ctxt.get('_i18n.choose.params', [])[:]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
217 msgbuf = MessageBuffer(self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
218 stream = _apply_directives(stream, directives, ctxt, vars)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
219
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
220 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
221 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
222 yield previous
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
223 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
224 msgbuf.append(*previous)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
225
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
226 try:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
227 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
228 except StopIteration:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
229 # For example <i18n:singular> or <i18n:plural> directives
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
230 yield MSGBUF, (), -1 # the place holder for msgbuf output
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
231 ctxt['_i18n.choose.%s' % self.tagname] = msgbuf
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
232 return
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
233
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
234 for event in stream:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
235 msgbuf.append(*previous)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
236 previous = event
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
237 yield MSGBUF, (), -1 # the place holder for msgbuf output
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
238
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
239 if previous[0] is END:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
240 yield previous # the outer end tag
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
241 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
242 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
243 ctxt['_i18n.choose.%s' % self.tagname] = msgbuf
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
244
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
245 def extract(self, translator, stream, gettext_functions=GETTEXT_FUNCTIONS,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
246 search_text=True, comment_stack=None, msgbuf=None):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
247 stream = iter(stream)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
248 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
249
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
250 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
251 # skip the enclosing element
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
252 for message in translator._extract_attrs(previous,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
253 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
254 search_text=search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
255 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
256 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
257
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
258 for event in stream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
259 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
260 for message in translator._extract_attrs(previous,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
261 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
262 search_text=search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
263 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
264 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
265 previous = event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
266
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
267 if previous[0] is not END:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
268 msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
269
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
270
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
271 class SingularDirective(ChooseBranchDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
272 """Implementation of the ``i18n:singular`` directive to be used with the
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
273 ``i18n:choose`` directive."""
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
274
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
275
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
276 class PluralDirective(ChooseBranchDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
277 """Implementation of the ``i18n:plural`` directive to be used with the
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
278 ``i18n:choose`` directive."""
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
279
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
280
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
281 class ChooseDirective(ExtractableI18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
282 """Implementation of the ``i18n:choose`` directive which provides plural
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
283 internationalisation of strings.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
284
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
285 This directive requires at least one parameter, the one which evaluates to
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
286 an integer which will allow to choose the plural/singular form. If you also
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
287 have expressions inside the singular and plural version of the string you
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
288 also need to pass a name for those parameters. Consider the following
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
289 examples:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
290
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
291 >>> tmpl = MarkupTemplate('''\
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
292 <html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
293 ... <div i18n:choose="num; num">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
294 ... <p i18n:singular="">There is $num coin</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
295 ... <p i18n:plural="">There are $num coins</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
296 ... </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
297 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
298 >>> translator = Translator()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
299 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
300 >>> list(translator.extract(tmpl.stream)) #doctest: +NORMALIZE_WHITESPACE
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
301 [(2, 'ngettext', (u'There is %(num)s coin',
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
302 u'There are %(num)s coins'), [])]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
303
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
304 >>> tmpl = MarkupTemplate('''\
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
305 <html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
306 ... <div i18n:choose="num; num">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
307 ... <p i18n:singular="">There is $num coin</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
308 ... <p i18n:plural="">There are $num coins</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
309 ... </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
310 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
311 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
312 >>> print(tmpl.generate(num=1).render())
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
313 <html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
314 <div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
315 <p>There is 1 coin</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
316 </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
317 </html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
318 >>> print(tmpl.generate(num=2).render())
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
319 <html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
320 <div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
321 <p>There are 2 coins</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
322 </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
323 </html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
324
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
325 When used as a element and not as an attribute:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
326
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
327 >>> tmpl = MarkupTemplate('''\
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
328 <html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
329 ... <i18n:choose numeral="num" params="num">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
330 ... <p i18n:singular="">There is $num coin</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
331 ... <p i18n:plural="">There are $num coins</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
332 ... </i18n:choose>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
333 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
334 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
335 >>> list(translator.extract(tmpl.stream)) #doctest: +NORMALIZE_WHITESPACE
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
336 [(2, 'ngettext', (u'There is %(num)s coin',
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
337 u'There are %(num)s coins'), [])]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
338 """
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
339 __slots__ = ['numeral', 'params', 'lineno']
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
340
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
341 def __init__(self, value, template=None, namespaces=None, lineno=-1,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
342 offset=-1):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
343 Directive.__init__(self, None, template, namespaces, lineno, offset)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
344 params = [v.strip() for v in value.split(';')]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
345 self.numeral = self._parse_expr(params.pop(0), template, lineno, offset)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
346 self.params = params and [name.strip() for name in
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
347 params[0].split(',') if name] or []
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
348 self.lineno = lineno
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
349
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
350 @classmethod
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
351 def attach(cls, template, stream, value, namespaces, pos):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
352 if type(value) is dict:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
353 numeral = value.get('numeral', '').strip()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
354 assert numeral is not '', "at least pass the numeral param"
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
355 params = [v.strip() for v in value.get('params', '').split(',')]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
356 value = '%s; ' % numeral + ', '.join(params)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
357 return super(ChooseDirective, cls).attach(template, stream, value,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
358 namespaces, pos)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
359
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
360 def __call__(self, stream, directives, ctxt, **vars):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
361 ctxt.push({'_i18n.choose.params': self.params,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
362 '_i18n.choose.singular': None,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
363 '_i18n.choose.plural': None})
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
364
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
365 ngettext = ctxt.get('_i18n.ngettext')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
366 assert hasattr(ngettext, '__call__'), 'No ngettext function available'
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
367 dngettext = ctxt.get('_i18n.dngettext')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
368 if not dngettext:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
369 dngettext = lambda d, s, p, n: ngettext(s, p, n)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
370
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
371 new_stream = []
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
372 singular_stream = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
373 singular_msgbuf = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
374 plural_stream = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
375 plural_msgbuf = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
376
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
377 numeral = self.numeral.evaluate(ctxt)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
378 is_plural = self._is_plural(numeral, ngettext)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
379
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
380 for event in stream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
381 if event[0] is SUB and any(isinstance(d, ChooseBranchDirective)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
382 for d in event[1][0]):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
383 subdirectives, substream = event[1]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
384
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
385 if isinstance(subdirectives[0], SingularDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
386 singular_stream = list(_apply_directives(substream,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
387 subdirectives,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
388 ctxt, vars))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
389 new_stream.append((MSGBUF, None, (None, -1, -1)))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
390
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
391 elif isinstance(subdirectives[0], PluralDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
392 if is_plural:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
393 plural_stream = list(_apply_directives(substream,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
394 subdirectives,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
395 ctxt, vars))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
396
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
397 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
398 new_stream.append(event)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
399
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
400 if ctxt.get('_i18n.domain'):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
401 ngettext = lambda s, p, n: dngettext(ctxt.get('_i18n.domain'),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
402 s, p, n)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
403
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
404 singular_msgbuf = ctxt.get('_i18n.choose.singular')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
405 if is_plural:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
406 plural_msgbuf = ctxt.get('_i18n.choose.plural')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
407 msgbuf, choice = plural_msgbuf, plural_stream
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
408 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
409 msgbuf, choice = singular_msgbuf, singular_stream
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
410 plural_msgbuf = MessageBuffer(self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
411
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
412 for kind, data, pos in new_stream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
413 if kind is MSGBUF:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
414 for event in choice:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
415 if event[0] is MSGBUF:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
416 translation = ngettext(singular_msgbuf.format(),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
417 plural_msgbuf.format(),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
418 numeral)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
419 for subevent in msgbuf.translate(translation):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
420 yield subevent
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
421 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
422 yield event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
423 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
424 yield kind, data, pos
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
425
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
426 ctxt.pop()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
427
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
428 def extract(self, translator, stream, gettext_functions=GETTEXT_FUNCTIONS,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
429 search_text=True, comment_stack=None):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
430 strip = False
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
431 stream = iter(stream)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
432 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
433
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
434 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
435 # skip the enclosing element
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
436 for message in translator._extract_attrs(previous,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
437 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
438 search_text=search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
439 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
440 previous = stream.next()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
441 strip = True
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
442
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
443 singular_msgbuf = MessageBuffer(self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
444 plural_msgbuf = MessageBuffer(self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
445
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
446 for event in stream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
447 if previous[0] is SUB:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
448 directives, substream = previous[1]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
449 for directive in directives:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
450 if isinstance(directive, SingularDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
451 for message in directive.extract(translator,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
452 substream, gettext_functions, search_text,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
453 comment_stack, msgbuf=singular_msgbuf):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
454 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
455 elif isinstance(directive, PluralDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
456 for message in directive.extract(translator,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
457 substream, gettext_functions, search_text,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
458 comment_stack, msgbuf=plural_msgbuf):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
459 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
460 elif not isinstance(directive, StripDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
461 singular_msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
462 plural_msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
463 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
464 if previous[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
465 for message in translator._extract_attrs(previous,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
466 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
467 search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
468 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
469 singular_msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
470 plural_msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
471 previous = event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
472
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
473 if not strip:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
474 singular_msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
475 plural_msgbuf.append(*previous)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
476
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
477 yield self.lineno, 'ngettext', \
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
478 (singular_msgbuf.format(), plural_msgbuf.format()), \
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
479 comment_stack[-1:]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
480
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
481 def _is_plural(self, numeral, ngettext):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
482 # XXX: should we test which form was chosen like this!?!?!?
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
483 # There should be no match in any catalogue for these singular and
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
484 # plural test strings
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
485 singular = u'O\x85\xbe\xa9\xa8az\xc3?\xe6\xa1\x02n\x84\x93'
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
486 plural = u'\xcc\xfb+\xd3Pn\x9d\tT\xec\x1d\xda\x1a\x88\x00'
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
487 return ngettext(singular, plural, numeral) == plural
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
488
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
489
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
490 class DomainDirective(I18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
491 """Implementation of the ``i18n:domain`` directive which allows choosing
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
492 another i18n domain(catalog) to translate from.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
493
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
494 >>> from genshi.filters.tests.i18n import DummyTranslations
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
495 >>> tmpl = MarkupTemplate('''\
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
496 <html xmlns:i18n="http://genshi.edgewall.org/i18n">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
497 ... <p i18n:msg="">Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
498 ... <div i18n:domain="foo">
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
499 ... <p i18n:msg="">FooBar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
500 ... <p>Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
501 ... <p i18n:domain="bar" i18n:msg="">Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
502 ... <p i18n:domain="">Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
503 ... </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
504 ... <p>Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
505 ... </html>''')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
506
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
507 >>> translations = DummyTranslations({'Bar': 'Voh'})
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
508 >>> translations.add_domain('foo', {'FooBar': 'BarFoo', 'Bar': 'foo_Bar'})
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
509 >>> translations.add_domain('bar', {'Bar': 'bar_Bar'})
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
510 >>> translator = Translator(translations)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
511 >>> translator.setup(tmpl)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
512
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
513 >>> print(tmpl.generate().render())
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
514 <html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
515 <p>Voh</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
516 <div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
517 <p>BarFoo</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
518 <p>foo_Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
519 <p>bar_Bar</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
520 <p>Voh</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
521 </div>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
522 <p>Voh</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
523 </html>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
524 """
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
525 __slots__ = ['domain']
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
526
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
527 def __init__(self, value, template=None, namespaces=None, lineno=-1,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
528 offset=-1):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
529 Directive.__init__(self, None, template, namespaces, lineno, offset)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
530 self.domain = value and value.strip() or '__DEFAULT__'
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
531
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
532 @classmethod
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
533 def attach(cls, template, stream, value, namespaces, pos):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
534 if type(value) is dict:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
535 value = value.get('name')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
536 return super(DomainDirective, cls).attach(template, stream, value,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
537 namespaces, pos)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
538
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
539 def __call__(self, stream, directives, ctxt, **vars):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
540 ctxt.push({'_i18n.domain': self.domain})
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
541 for event in _apply_directives(stream, directives, ctxt, vars):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
542 yield event
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
543 ctxt.pop()
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
544
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
545
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
546 class Translator(DirectiveFactory):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
547 """Can extract and translate localizable strings from markup streams and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
548 templates.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
549
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
550 For example, assume the following template:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
551
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
552 >>> tmpl = MarkupTemplate('''<html xmlns:py="http://genshi.edgewall.org/">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
553 ... <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
554 ... <title>Example</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
555 ... </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
556 ... <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
557 ... <h1>Example</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
558 ... <p>${_("Hello, %(name)s") % dict(name=username)}</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
559 ... </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
560 ... </html>''', filename='example.html')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
561
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
562 For demonstration, we define a dummy ``gettext``-style function with a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
563 hard-coded translation table, and pass that to the `Translator` initializer:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
564
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
565 >>> def pseudo_gettext(string):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
566 ... return {
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
567 ... 'Example': 'Beispiel',
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
568 ... 'Hello, %(name)s': 'Hallo, %(name)s'
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
569 ... }[string]
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
570 >>> translator = Translator(pseudo_gettext)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
571
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
572 Next, the translator needs to be prepended to any already defined filters
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
573 on the template:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
574
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
575 >>> tmpl.filters.insert(0, translator)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
576
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
577 When generating the template output, our hard-coded translations should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
578 applied as expected:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
579
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
580 >>> print(tmpl.generate(username='Hans', _=pseudo_gettext))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
581 <html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
582 <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
583 <title>Beispiel</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
584 </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
585 <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
586 <h1>Beispiel</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
587 <p>Hallo, Hans</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
588 </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
589 </html>
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
590
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
591 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
592 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
593 exclude specific parts of a template from being extracted and translated.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
594 """
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
595
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
596 directives = [
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
597 ('domain', DomainDirective),
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
598 ('comment', CommentDirective),
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
599 ('msg', MsgDirective),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
600 ('choose', ChooseDirective),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
601 ('singular', SingularDirective),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
602 ('plural', PluralDirective)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
603 ]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
604
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
605 IGNORE_TAGS = frozenset([
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
606 QName('script'), QName('http://www.w3.org/1999/xhtml}script'),
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
607 QName('style'), QName('http://www.w3.org/1999/xhtml}style')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
608 ])
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
609 INCLUDE_ATTRS = frozenset([
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
610 'abbr', 'alt', 'label', 'prompt', 'standby', 'summary', 'title'
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
611 ])
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
612 NAMESPACE = I18N_NAMESPACE
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
613
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
614 def __init__(self, translate=NullTranslations(), ignore_tags=IGNORE_TAGS,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
615 include_attrs=INCLUDE_ATTRS, extract_text=True):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
616 """Initialize the translator.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
617
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
618 :param translate: the translation function, for example ``gettext`` or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
619 ``ugettext``.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
620 :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
621 :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
622 :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
623 extracted, or only text in explicit ``gettext``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
624 function calls
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
625
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
626 :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
627 a ``gettext``-style function, or an object compatible with the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
628 ``NullTransalations`` or ``GNUTranslations`` interface
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
629 """
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
630 self.translate = translate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
631 self.ignore_tags = ignore_tags
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
632 self.include_attrs = include_attrs
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
633 self.extract_text = extract_text
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
634
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
635 def __call__(self, stream, ctxt=None, translate_text=True,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
636 translate_attrs=True):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
637 """Translate any localizable strings in the given stream.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
638
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
639 This function shouldn't be called directly. Instead, an instance of
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
640 the `Translator` class should be registered as a filter with the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
641 `Template` or the `TemplateLoader`, or applied as a regular stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
642 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
643 all the default filters.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
644
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
645 :param stream: the markup event stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
646 :param ctxt: the template context (not used)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
647 :param translate_text: whether text nodes should be translated (used
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
648 internally)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
649 :param translate_attrs: whether attribute values should be translated
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
650 (used internally)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
651 :return: the localized stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
652 """
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
653 ignore_tags = self.ignore_tags
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
654 include_attrs = self.include_attrs
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
655 skip = 0
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
656 xml_lang = XML_NAMESPACE['lang']
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
657 if not self.extract_text:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
658 translate_text = False
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
659 translate_attrs = False
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
660
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
661 if type(self.translate) is FunctionType:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
662 gettext = self.translate
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
663 if ctxt:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
664 ctxt['_i18n.gettext'] = gettext
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
665 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
666 gettext = self.translate.ugettext
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
667 ngettext = self.translate.ungettext
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
668 try:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
669 dgettext = self.translate.dugettext
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
670 dngettext = self.translate.dungettext
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
671 except AttributeError:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
672 dgettext = lambda _, y: gettext(y)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
673 dngettext = lambda _, s, p, n: ngettext(s, p, n)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
674 if ctxt:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
675 ctxt['_i18n.gettext'] = gettext
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
676 ctxt['_i18n.ngettext'] = ngettext
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
677 ctxt['_i18n.dgettext'] = dgettext
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
678 ctxt['_i18n.dngettext'] = dngettext
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
679
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
680 if ctxt and ctxt.get('_i18n.domain'):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
681 gettext = lambda msg: dgettext(ctxt.get('_i18n.domain'), msg)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
682
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
683 for kind, data, pos in stream:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
684
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
685 # skip chunks that should not be localized
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
686 if skip:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
687 if kind is START:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
688 skip += 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
689 elif kind is END:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
690 skip -= 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
691 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
692 continue
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
693
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
694 # handle different events that can be localized
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
695 if kind is START:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
696 tag, attrs = data
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
697 if tag in self.ignore_tags or \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
698 isinstance(attrs.get(xml_lang), basestring):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
699 skip += 1
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
700 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
701 continue
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
702
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
703 new_attrs = []
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
704 changed = False
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
705
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
706 for name, value in attrs:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
707 newval = value
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
708 if isinstance(value, basestring):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
709 if translate_attrs and name in include_attrs:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
710 newval = gettext(value)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
711 else:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
712 newval = list(
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
713 self(_ensure(value), ctxt, translate_text=False)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
714 )
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
715 if newval != value:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
716 value = newval
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
717 changed = True
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
718 new_attrs.append((name, value))
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
719 if changed:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
720 attrs = Attrs(new_attrs)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
721
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
722 yield kind, (tag, attrs), pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
723
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
724 elif translate_text and kind is TEXT:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
725 text = data.strip()
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
726 if text:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
727 data = data.replace(text, unicode(gettext(text)))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
728 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
729
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
730 elif kind is SUB:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
731 directives, substream = data
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
732 current_domain = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
733 for idx, directive in enumerate(directives):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
734 # Organize directives to make everything work
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
735 # FIXME: There's got to be a better way to do this!
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
736 if isinstance(directive, DomainDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
737 # Grab current domain and update context
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
738 current_domain = directive.domain
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
739 ctxt.push({'_i18n.domain': current_domain})
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
740 # Put domain directive as the first one in order to
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
741 # update context before any other directives evaluation
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
742 directives.insert(0, directives.pop(idx))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
743
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
744 # If this is an i18n directive, no need to translate text
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
745 # nodes here
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
746 is_i18n_directive = any([
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
747 isinstance(d, ExtractableI18NDirective)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
748 for d in directives
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
749 ])
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
750 substream = list(self(substream, ctxt,
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
751 translate_text=not is_i18n_directive,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
752 translate_attrs=translate_attrs))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
753 yield kind, (directives, substream), pos
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
754
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
755 if current_domain:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
756 ctxt.pop()
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
757 else:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
758 yield kind, data, pos
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
759
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
760 def extract(self, stream, gettext_functions=GETTEXT_FUNCTIONS,
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
761 search_text=True, comment_stack=None):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
762 """Extract localizable strings from the given template stream.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
763
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
764 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
765 message, comments)`` tuple, where:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
766
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
767 * ``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
768 * ``function`` is the name of the ``gettext`` function used (if the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
769 string was extracted from embedded Python code), and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
770 * ``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
771 of ``unicode`` objects for functions with multiple string
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
772 arguments).
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
773 * ``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
774 from ``i18n:comment`` attributes found in the markup
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
775
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
776 >>> tmpl = MarkupTemplate('''<html xmlns:py="http://genshi.edgewall.org/">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
777 ... <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
778 ... <title>Example</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
779 ... </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
780 ... <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
781 ... <h1>Example</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
782 ... <p>${_("Hello, %(name)s") % dict(name=username)}</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
783 ... <p>${ngettext("You have %d item", "You have %d items", num)}</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
784 ... </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
785 ... </html>''', filename='example.html')
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
786 >>> for line, func, msg, comments in Translator().extract(tmpl.stream):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
787 ... print('%d, %r, %r' % (line, func, msg))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
788 3, None, u'Example'
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
789 6, None, u'Example'
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
790 7, '_', u'Hello, %(name)s'
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
791 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
792
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
793 :param stream: the event stream to extract strings from; can be a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
794 regular stream or a template stream
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
795 :param gettext_functions: a sequence of function names that should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
796 treated as gettext-style localization
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
797 functions
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
798 :param search_text: whether the content of text nodes should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
799 extracted (used internally)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
800
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
801 :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
802 (such as ``ngettext``), a single item with a tuple of strings is
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
803 yielded, instead an item for each string argument.
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
804 :note: Changed in 0.6: The returned tuples now include a fourth
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
805 element, which is a list of comments for the translator.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
806 """
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
807 if not self.extract_text:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
808 search_text = False
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
809 if comment_stack is None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
810 comment_stack = []
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
811 skip = 0
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
812
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
813 xml_lang = XML_NAMESPACE['lang']
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
814
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
815 for kind, data, pos in stream:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
816 if skip:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
817 if kind is START:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
818 skip += 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
819 if kind is END:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
820 skip -= 1
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
821
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
822 if kind is START and not skip:
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
823 tag, attrs = data
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
824 if tag in self.ignore_tags or \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
825 isinstance(attrs.get(xml_lang), basestring):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
826 skip += 1
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
827 continue
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
828
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
829 for message in self._extract_attrs((kind, data, pos),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
830 gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
831 search_text=search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
832 yield message
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
833
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
834 elif not skip and search_text and kind is TEXT:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
835 text = data.strip()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
836 if text and [ch for ch in text if ch.isalpha()]:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
837 yield pos[1], None, text, comment_stack[-1:]
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
838
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
839 elif kind is EXPR or kind is EXEC:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
840 for funcname, strings in extract_from_code(data,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
841 gettext_functions):
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
842 # XXX: Do we need to grab i18n:comment from comment_stack ???
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
843 yield pos[1], funcname, strings, []
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
844
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
845 elif kind is SUB:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
846 directives, substream = data
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
847 in_comment = False
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
848
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
849 for idx, directive in enumerate(directives):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
850 # Do a first loop to see if there's a comment directive
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
851 # If there is update context and pop it from directives
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
852 if isinstance(directive, CommentDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
853 in_comment = True
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
854 comment_stack.append(directive.comment)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
855 if len(directives) == 1:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
856 # in case we're in the presence of something like:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
857 # <p i18n:comment="foo">Foo</p>
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
858 for message in self.extract(
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
859 substream, gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
860 search_text=search_text and not skip,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
861 comment_stack=comment_stack):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
862 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
863 directives.pop(idx)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
864 elif not isinstance(directive, I18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
865 # Remove all other non i18n directives from the process
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
866 directives.pop(idx)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
867
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
868 if not directives and not in_comment:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
869 # Extract content if there's no directives because
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
870 # strip was pop'ed and not because comment was pop'ed.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
871 # Extraction in this case has been taken care of.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
872 for message in self.extract(
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
873 substream, gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
874 search_text=search_text and not skip):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
875 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
876
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
877 for directive in directives:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
878 if isinstance(directive, ExtractableI18NDirective):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
879 for message in directive.extract(self,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
880 substream, gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
881 search_text=search_text and not skip,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
882 comment_stack=comment_stack):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
883 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
884 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
885 for message in self.extract(
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
886 substream, gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
887 search_text=search_text and not skip,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
888 comment_stack=comment_stack):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
889 yield message
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
890
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
891 if in_comment:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
892 comment_stack.pop()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
893
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
894 def get_directive_index(self, dir_cls):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
895 total = len(self._dir_order)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
896 if dir_cls in self._dir_order:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
897 return self._dir_order.index(dir_cls) - total
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
898 return total
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
899
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
900 def setup(self, template):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
901 """Convenience function to register the `Translator` filter and the
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
902 related directives with the given template.
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
903
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
904 :param template: a `Template` instance
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
905 """
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
906 template.filters.insert(0, self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
907 if hasattr(template, 'add_directives'):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
908 template.add_directives(Translator.NAMESPACE, self)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
909
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
910 def _extract_attrs(self, event, gettext_functions, search_text):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
911 for name, value in event[1][1]:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
912 if search_text and isinstance(value, basestring):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
913 if name in self.include_attrs:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
914 text = value.strip()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
915 if text:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
916 yield event[2][1], None, text, []
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
917 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
918 for message in self.extract(_ensure(value), gettext_functions,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
919 search_text=False):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
920 yield message
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
921
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
922
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
923 class MessageBuffer(object):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
924 """Helper class for managing internationalized mixed content.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
925
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
926 :since: version 0.5
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
927 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
928
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
929 def __init__(self, directive=None):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
930 """Initialize the message buffer.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
931
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
932 :param directive: the directive owning the buffer
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
933 :type directive: I18NDirective
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
934 """
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
935 # params list needs to be copied so that directives can be evaluated
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
936 # more than once
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
937 self.orig_params = self.params = directive.params[:]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
938 self.directive = directive
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
939 self.string = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
940 self.events = {}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
941 self.values = {}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
942 self.depth = 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
943 self.order = 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
944 self.stack = [0]
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
945 self.subdirectives = {}
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
946
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
947 def append(self, kind, data, pos):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
948 """Append a stream event to the buffer.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
949
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
950 :param kind: the stream event kind
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
951 :param data: the event data
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
952 :param pos: the position of the event in the source
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
953 """
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
954 if kind is SUB:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
955 # The order needs to be +1 because a new START kind event will
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
956 # happen and we we need to wrap those events into our custom kind(s)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
957 order = self.stack[-1] + 1
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
958 subdirectives, substream = data
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
959 # Store the directives that should be applied after translation
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
960 self.subdirectives.setdefault(order, []).extend(subdirectives)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
961 self.events.setdefault(order, []).append((SUB_START, None, pos))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
962 for skind, sdata, spos in substream:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
963 self.append(skind, sdata, spos)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
964 self.events.setdefault(order, []).append((SUB_END, None, pos))
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
965 elif kind is TEXT:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
966 if '[' in data or ']' in data:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
967 # Quote [ and ] if it ain't us adding it, ie, if the user is
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
968 # using those chars in his templates, escape them
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
969 data = data.replace('[', '\[').replace(']', '\]')
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
970 self.string.append(data)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
971 self.events.setdefault(self.stack[-1], []).append((kind, data, pos))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
972 elif kind is EXPR:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
973 if self.params:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
974 param = self.params.pop(0)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
975 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
976 params = ', '.join(['"%s"' % p for p in self.orig_params if p])
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
977 if params:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
978 params = "(%s)" % params
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
979 raise IndexError("%d parameters%s given to 'i18n:%s' but "
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
980 "%d or more expressions used in '%s', line %s"
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
981 % (len(self.orig_params), params,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
982 self.directive.tagname,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
983 len(self.orig_params) + 1,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
984 os.path.basename(pos[0] or
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
985 'In-memory Template'),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
986 pos[1]))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
987 self.string.append('%%(%s)s' % param)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
988 self.events.setdefault(self.stack[-1], []).append((kind, data, pos))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
989 self.values[param] = (kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
990 else:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
991 if kind is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
992 self.string.append('[%d:' % self.order)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
993 self.stack.append(self.order)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
994 self.events.setdefault(self.stack[-1],
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
995 []).append((kind, data, pos))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
996 self.depth += 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
997 self.order += 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
998 elif kind is END:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
999 self.depth -= 1
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1000 if self.depth:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1001 self.events[self.stack[-1]].append((kind, data, pos))
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1002 self.string.append(']')
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1003 self.stack.pop()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1004
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1005 def format(self):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1006 """Return a message identifier representing the content in the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1007 buffer.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1008 """
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1009 return ''.join(self.string).strip()
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1010
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1011 def translate(self, string, regex=re.compile(r'%\((\w+)\)s')):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1012 """Interpolate the given message translation with the events in the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1013 buffer and return the translated stream.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1014
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1015 :param string: the translated message string
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1016 """
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1017 substream = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1018
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1019 def yield_parts(string):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1020 for idx, part in enumerate(regex.split(string)):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1021 if idx % 2:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1022 yield self.values[part]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1023 elif part:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1024 yield (TEXT,
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1025 part.replace('\[', '[').replace('\]', ']'),
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1026 (None, -1, -1)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1027 )
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1028
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1029 parts = parse_msg(string)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1030 parts_counter = {}
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1031 for order, string in parts:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1032 parts_counter.setdefault(order, []).append(None)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1033
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1034 while parts:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1035 order, string = parts.pop(0)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1036 if len(parts_counter[order]) == 1:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1037 events = self.events[order]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1038 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1039 events = [self.events[order].pop(0)]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1040 parts_counter[order].pop()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1041
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1042 for event in events:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1043 if event[0] is SUB_START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1044 substream = []
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1045 elif event[0] is SUB_END:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1046 # Yield a substream which might have directives to be
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1047 # applied to it (after translation events)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1048 yield SUB, (self.subdirectives[order], substream), event[2]
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1049 substream = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1050 elif event[0] is TEXT:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1051 if string:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1052 for part in yield_parts(string):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1053 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1054 substream.append(part)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1055 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1056 yield part
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1057 # String handled, reset it
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1058 string = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1059 elif event[0] is START:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1060 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1061 substream.append(event)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1062 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1063 yield event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1064 if string:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1065 for part in yield_parts(string):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1066 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1067 substream.append(part)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1068 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1069 yield part
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1070 # String handled, reset it
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1071 string = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1072 elif event[0] is END:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1073 if string:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1074 for part in yield_parts(string):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1075 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1076 substream.append(part)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1077 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1078 yield part
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1079 # String handled, reset it
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1080 string = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1081 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1082 substream.append(event)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1083 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1084 yield event
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1085 elif event[0] is EXPR:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1086 # These are handled on the strings itself
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1087 continue
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1088 else:
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1089 if string:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1090 for part in yield_parts(string):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1091 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1092 substream.append(part)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1093 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1094 yield part
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1095 # String handled, reset it
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1096 string = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1097 if substream is not None:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1098 substream.append(event)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1099 else:
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1100 yield event
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1101
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1102
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1103 def parse_msg(string, regex=re.compile(r'(?:\[(\d+)\:)|(?<!\\)\]')):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1104 """Parse a translated message using Genshi mixed content message
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1105 formatting.
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1106
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1107 >>> parse_msg("See [1:Help].")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1108 [(0, 'See '), (1, 'Help'), (0, '.')]
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1109
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1110 >>> parse_msg("See [1:our [2:Help] page] for details.")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1111 [(0, 'See '), (1, 'our '), (2, 'Help'), (1, ' page'), (0, ' for details.')]
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1112
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1113 >>> parse_msg("[2:Details] finden Sie in [1:Hilfe].")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1114 [(2, 'Details'), (0, ' finden Sie in '), (1, 'Hilfe'), (0, '.')]
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1115
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1116 >>> parse_msg("[1:] Bilder pro Seite anzeigen.")
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1117 [(1, ''), (0, ' Bilder pro Seite anzeigen.')]
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1118
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1119 :param string: the translated message string
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1120 :return: a list of ``(order, string)`` tuples
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1121 :rtype: `list`
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1122 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1123 parts = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1124 stack = [0]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1125 while True:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1126 mo = regex.search(string)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1127 if not mo:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1128 break
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1129
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1130 if mo.start() or stack[-1]:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1131 parts.append((stack[-1], string[:mo.start()]))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1132 string = string[mo.end():]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1133
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1134 orderno = mo.group(1)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1135 if orderno is not None:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1136 stack.append(int(orderno))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1137 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1138 stack.pop()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1139 if not stack:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1140 break
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1141
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1142 if string:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1143 parts.append((stack[-1], string))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1144
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1145 return parts
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1146
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1147
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1148 def extract_from_code(code, gettext_functions):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1149 """Extract strings from Python bytecode.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1150
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1151 >>> from genshi.template.eval import Expression
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1152 >>> expr = Expression('_("Hello")')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1153 >>> list(extract_from_code(expr, GETTEXT_FUNCTIONS))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1154 [('_', u'Hello')]
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1155
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1156 >>> expr = Expression('ngettext("You have %(num)s item", '
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1157 ... '"You have %(num)s items", num)')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1158 >>> list(extract_from_code(expr, GETTEXT_FUNCTIONS))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1159 [('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
1160
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1161 :param code: the `Code` object
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1162 :type code: `genshi.template.eval.Code`
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1163 :param gettext_functions: a sequence of function names
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1164 :since: version 0.5
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1165 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1166 def _walk(node):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1167 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
1168 and node.func.id in gettext_functions:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1169 strings = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1170 def _add(arg):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1171 if isinstance(arg, _ast.Str) and isinstance(arg.s, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1172 strings.append(unicode(arg.s, 'utf-8'))
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1173 elif arg:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1174 strings.append(None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1175 [_add(arg) for arg in node.args]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1176 _add(node.starargs)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1177 _add(node.kwargs)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1178 if len(strings) == 1:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1179 strings = strings[0]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1180 else:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1181 strings = tuple(strings)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1182 yield node.func.id, strings
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1183 elif node._fields:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1184 children = []
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1185 for field in node._fields:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1186 child = getattr(node, field, None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1187 if isinstance(child, list):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1188 for elem in child:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1189 children.append(elem)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1190 elif isinstance(child, _ast.AST):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1191 children.append(child)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1192 for child in children:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1193 for funcname, strings in _walk(child):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1194 yield funcname, strings
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1195 return _walk(code.ast)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1196
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1197
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1198 def extract(fileobj, keywords, comment_tags, options):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1199 """Babel extraction method for Genshi templates.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1200
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1201 :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
1202 :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
1203 recognized as translation functions
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1204 :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
1205 in the results
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1206 :param options: a dictionary of additional options (optional)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1207 :return: an iterator over ``(lineno, funcname, message, comments)`` tuples
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1208 :rtype: ``iterator``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1209 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1210 template_class = options.get('template_class', MarkupTemplate)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1211 if isinstance(template_class, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1212 module, clsname = template_class.split(':', 1)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1213 template_class = getattr(__import__(module, {}, {}, [clsname]), clsname)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1214 encoding = options.get('encoding', None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1215
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1216 extract_text = options.get('extract_text', True)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1217 if isinstance(extract_text, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1218 extract_text = extract_text.lower() in ('1', 'on', 'yes', 'true')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1219
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1220 ignore_tags = options.get('ignore_tags', Translator.IGNORE_TAGS)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1221 if isinstance(ignore_tags, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1222 ignore_tags = ignore_tags.split()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1223 ignore_tags = [QName(tag) for tag in ignore_tags]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1224
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1225 include_attrs = options.get('include_attrs', Translator.INCLUDE_ATTRS)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1226 if isinstance(include_attrs, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1227 include_attrs = include_attrs.split()
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1228 include_attrs = [QName(attr) for attr in include_attrs]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1229
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1230 tmpl = template_class(fileobj, filename=getattr(fileobj, 'name', None),
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1231 encoding=encoding)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1232 tmpl.loader = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1233
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1234 translator = Translator(None, ignore_tags, include_attrs, extract_text)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1235 if hasattr(tmpl, 'add_directives'):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
1236 tmpl.add_directives(Translator.NAMESPACE, translator)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1237 for message in translator.extract(tmpl.stream, gettext_functions=keywords):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
1238 yield message
Copyright (C) 2012-2017 Edgewall Software