Mercurial > babel > mirror
comparison babel/messages/extract.py @ 569:1b801a0cb2cb trunk
Support for context-aware methods during message extraction (fixes #229, patch by David Rios)
author | fschwarz |
---|---|
date | Mon, 26 Sep 2011 20:01:01 +0000 |
parents | 86524be05b60 |
children | 99983baf1067 |
comparison
equal
deleted
inserted
replaced
568:39ff5164e8ea | 569:1b801a0cb2cb |
---|---|
39 'ngettext': (1, 2), | 39 'ngettext': (1, 2), |
40 'ugettext': None, | 40 'ugettext': None, |
41 'ungettext': (1, 2), | 41 'ungettext': (1, 2), |
42 'dgettext': (2,), | 42 'dgettext': (2,), |
43 'dngettext': (2, 3), | 43 'dngettext': (2, 3), |
44 'N_': None | 44 'N_': None, |
45 'pgettext': ((1, 'c'), 2) | |
45 } | 46 } |
46 | 47 |
47 DEFAULT_MAPPING = [('**.py', 'python')] | 48 DEFAULT_MAPPING = [('**.py', 'python')] |
48 | 49 |
49 empty_msgid_warning = ( | 50 empty_msgid_warning = ( |
128 performed; the function is passed the filename, the name | 129 performed; the function is passed the filename, the name |
129 of the extraction method and and the options dictionary as | 130 of the extraction method and and the options dictionary as |
130 positional arguments, in that order | 131 positional arguments, in that order |
131 :param strip_comment_tags: a flag that if set to `True` causes all comment | 132 :param strip_comment_tags: a flag that if set to `True` causes all comment |
132 tags to be removed from the collected comments. | 133 tags to be removed from the collected comments. |
133 :return: an iterator over ``(filename, lineno, funcname, message)`` tuples | 134 :return: an iterator over ``(filename, lineno, funcname, message, context)`` |
135 tuples | |
134 :rtype: ``iterator`` | 136 :rtype: ``iterator`` |
135 :see: `pathmatch` | 137 :see: `pathmatch` |
136 """ | 138 """ |
137 if options_map is None: | 139 if options_map is None: |
138 options_map = {} | 140 options_map = {} |
156 for opattern, odict in options_map.items(): | 158 for opattern, odict in options_map.items(): |
157 if pathmatch(opattern, filename): | 159 if pathmatch(opattern, filename): |
158 options = odict | 160 options = odict |
159 if callback: | 161 if callback: |
160 callback(filename, method, options) | 162 callback(filename, method, options) |
161 for lineno, message, comments in \ | 163 for lineno, message, comments, context in \ |
162 extract_from_file(method, filepath, | 164 extract_from_file(method, filepath, |
163 keywords=keywords, | 165 keywords=keywords, |
164 comment_tags=comment_tags, | 166 comment_tags=comment_tags, |
165 options=options, | 167 options=options, |
166 strip_comment_tags= | 168 strip_comment_tags= |
167 strip_comment_tags): | 169 strip_comment_tags): |
168 yield filename, lineno, message, comments | 170 yield filename, lineno, message, comments, context |
169 break | 171 break |
170 | 172 |
171 | 173 |
172 def extract_from_file(method, filename, keywords=DEFAULT_KEYWORDS, | 174 def extract_from_file(method, filename, keywords=DEFAULT_KEYWORDS, |
173 comment_tags=(), options=None, strip_comment_tags=False): | 175 comment_tags=(), options=None, strip_comment_tags=False): |
217 ... ''' | 219 ... ''' |
218 | 220 |
219 >>> from StringIO import StringIO | 221 >>> from StringIO import StringIO |
220 >>> for message in extract('python', StringIO(source)): | 222 >>> for message in extract('python', StringIO(source)): |
221 ... print message | 223 ... print message |
222 (3, u'Hello, world!', []) | 224 (3, u'Hello, world!', [], None) |
223 | 225 |
224 :param method: a string specifying the extraction method (.e.g. "python"); | 226 :param method: a string specifying the extraction method (.e.g. "python"); |
225 if this is a simple name, the extraction function will be | 227 if this is a simple name, the extraction function will be |
226 looked up by entry point; if it is an explicit reference | 228 looked up by entry point; if it is an explicit reference |
227 to a function (of the form ``package.module:funcname`` or | 229 to a function (of the form ``package.module:funcname`` or |
277 messages = [messages] | 279 messages = [messages] |
278 if not messages: | 280 if not messages: |
279 continue | 281 continue |
280 | 282 |
281 # Validate the messages against the keyword's specification | 283 # Validate the messages against the keyword's specification |
284 context = None | |
282 msgs = [] | 285 msgs = [] |
283 invalid = False | 286 invalid = False |
284 # last_index is 1 based like the keyword spec | 287 # last_index is 1 based like the keyword spec |
285 last_index = len(messages) | 288 last_index = len(messages) |
286 for index in spec: | 289 for index in spec: |
290 if isinstance(index, tuple): | |
291 context = messages[index[0] - 1] | |
292 continue | |
287 if last_index < index: | 293 if last_index < index: |
288 # Not enough arguments | 294 # Not enough arguments |
289 invalid = True | 295 invalid = True |
290 break | 296 break |
291 message = messages[index - 1] | 297 message = messages[index - 1] |
294 break | 300 break |
295 msgs.append(message) | 301 msgs.append(message) |
296 if invalid: | 302 if invalid: |
297 continue | 303 continue |
298 | 304 |
299 first_msg_index = spec[0] - 1 | 305 # keyword spec indexes are 1 based, therefore '-1' |
306 if isinstance(spec[0], tuple): | |
307 # context-aware *gettext method | |
308 first_msg_index = spec[1] - 1 | |
309 else: | |
310 first_msg_index = spec[0] - 1 | |
300 if not messages[first_msg_index]: | 311 if not messages[first_msg_index]: |
301 # An empty string msgid isn't valid, emit a warning | 312 # An empty string msgid isn't valid, emit a warning |
302 where = '%s:%i' % (hasattr(fileobj, 'name') and \ | 313 where = '%s:%i' % (hasattr(fileobj, 'name') and \ |
303 fileobj.name or '(unknown)', lineno) | 314 fileobj.name or '(unknown)', lineno) |
304 print >> sys.stderr, empty_msgid_warning % where | 315 print >> sys.stderr, empty_msgid_warning % where |
308 if len(messages) == 1: | 319 if len(messages) == 1: |
309 messages = messages[0] | 320 messages = messages[0] |
310 | 321 |
311 if strip_comment_tags: | 322 if strip_comment_tags: |
312 _strip_comment_tags(comments, comment_tags) | 323 _strip_comment_tags(comments, comment_tags) |
313 yield lineno, messages, comments | 324 yield lineno, messages, comments, context |
314 | 325 |
315 | 326 |
316 def extract_nothing(fileobj, keywords, comment_tags, options): | 327 def extract_nothing(fileobj, keywords, comment_tags, options): |
317 """Pseudo extractor that does not actually extract anything, but simply | 328 """Pseudo extractor that does not actually extract anything, but simply |
318 returns an empty list. | 329 returns an empty list. |