diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2008-06-14 14:19:47 +0200 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2008-06-14 14:19:47 +0200 |
commit | d02fc7db91a3f67f04489ddade7d9387d90eeab1 (patch) | |
tree | 65ebb6b855282e662a9a84e61ae30de1e4b92d3c /ext | |
parent | 3e3a9be203c713cd83e0eaa24a58ea394c5eb0a9 (diff) | |
download | jinja2-d02fc7db91a3f67f04489ddade7d9387d90eeab1.tar.gz |
Added example extension that uses the stream filtering and added unittests.
--HG--
branch : trunk
Diffstat (limited to 'ext')
-rw-r--r-- | ext/inlinegettext.py | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/ext/inlinegettext.py b/ext/inlinegettext.py new file mode 100644 index 0000000..049ab3b --- /dev/null +++ b/ext/inlinegettext.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +""" + Inline Gettext + ~~~~~~~~~~~~~~ + + An example extension for Jinja2 that supports inline gettext calls. + Requires the i18n extension to be loaded. + + :copyright: Copyright 2008 by Armin Ronacher. + :license: BSD. +""" +import re +from jinja2.ext import Extension +from jinja2.lexer import Token, count_newlines +from jinja2.exceptions import TemplateSyntaxError + + +_outside_re = re.compile(r'\\?(gettext|_)\(') +_inside_re = re.compile(r'\\?[()]') + + +class InlineGettext(Extension): + """This extension implements support for inline gettext blocks:: + + <h1>_(Welcome)</h1> + <p>_(This is a paragraph)</p> + + Requires the i18n extension to be loaded and configured. + """ + + def filter_stream(self, stream): + paren_stack = 0 + + for token in stream: + if token.type is not 'data': + yield token + continue + + pos = 0 + lineno = token.lineno + + while 1: + if not paren_stack: + match = _outside_re.search(token.value, pos) + else: + match = _inside_re.search(token.value, pos) + if match is None: + break + new_pos = match.start() + if new_pos > pos: + preval = token.value[pos:new_pos] + yield Token(lineno, 'data', preval) + lineno += count_newlines(preval) + gtok = match.group() + if gtok[0] == '\\': + yield Token(lineno, 'data', gtok[1:]) + elif not paren_stack: + yield Token(lineno, 'block_begin', None) + yield Token(lineno, 'name', 'trans') + yield Token(lineno, 'block_end', None) + paren_stack = 1 + else: + if gtok == '(' or paren_stack > 1: + yield Token(lineno, 'data', gtok) + paren_stack += gtok == ')' and -1 or 1 + if not paren_stack: + yield Token(lineno, 'block_begin', None) + yield Token(lineno, 'name', 'endtrans') + yield Token(lineno, 'block_end', None) + pos = match.end() + + if pos < len(token.value): + yield Token(lineno, 'data', token.value[pos:]) + + if paren_stack: + raise TemplateSyntaxError('unclosed gettext expression', + token.lineno, stream.name, + stream.filename) |