summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2008-06-14 14:19:47 +0200
committerArmin Ronacher <armin.ronacher@active-4.com>2008-06-14 14:19:47 +0200
commitd02fc7db91a3f67f04489ddade7d9387d90eeab1 (patch)
tree65ebb6b855282e662a9a84e61ae30de1e4b92d3c /ext
parent3e3a9be203c713cd83e0eaa24a58ea394c5eb0a9 (diff)
downloadjinja2-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.py78
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)