autoescape no longer is a plain boolean value but can also be a function
to enable or disable autoescaping for certain filenames (or file
extensions for that matter)

--HG--
branch : trunk
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 2952b66..117bd8c 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -761,7 +761,7 @@
 
     def visit_Template(self, node, frame=None):
         assert frame is None, 'no root frame allowed'
-        eval_ctx = EvalContext(self.environment)
+        eval_ctx = EvalContext(self.environment, self.name)
 
         from jinja2.runtime import __all__ as exported
         self.writeline('from __future__ import division')
diff --git a/jinja2/environment.py b/jinja2/environment.py
index a250185..25cec88 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -160,7 +160,13 @@
         `autoescape`
             If set to true the XML/HTML autoescaping feature is enabled by
             default.  For more details about auto escaping see
-            :class:`~jinja2.utils.Markup`.
+            :class:`~jinja2.utils.Markup`.  As of Jinja 2.4 this can also
+            be a callable that is passed the template name and has to
+            return `True` or `False` depending on autoescape should be
+            enabled by default.
+
+            .. versionchanged:: 2.4
+               `autoescape` can now be a function
 
         `loader`
             The template loader for this environment.
diff --git a/jinja2/nodes.py b/jinja2/nodes.py
index 15461e8..b6696c7 100644
--- a/jinja2/nodes.py
+++ b/jinja2/nodes.py
@@ -72,8 +72,11 @@
     to it in extensions.
     """
 
-    def __init__(self, environment):
-        self.autoescape = environment.autoescape
+    def __init__(self, environment, template_name=None):
+        if callable(environment.autoescape):
+            self.autoescape = environment.autoescape(template_name)
+        else:
+            self.autoescape = environment.autoescape
         self.volatile = False
 
     def save(self):
diff --git a/jinja2/runtime.py b/jinja2/runtime.py
index 318e654..fef7b25 100644
--- a/jinja2/runtime.py
+++ b/jinja2/runtime.py
@@ -77,7 +77,7 @@
 
     def __getitem__(self, name):
         blocks = self.__context.blocks[name]
-        wrap = self.__context.environment.autoescape and \
+        wrap = self.__context.eval_ctx.autoescape and \
                Markup or (lambda x: x)
         return BlockReference(name, self.__context, blocks, 0)
 
@@ -114,7 +114,7 @@
         self.parent = parent
         self.vars = {}
         self.environment = environment
-        self.eval_ctx = EvalContext(self.environment)
+        self.eval_ctx = EvalContext(self.environment, name)
         self.exported_vars = set()
         self.name = name
 
@@ -257,7 +257,7 @@
     @internalcode
     def __call__(self):
         rv = concat(self._stack[self._depth](self._context))
-        if self._context.environment.autoescape:
+        if self._context.eval_ctx.autoescape:
             rv = Markup(rv)
         return rv
 
diff --git a/jinja2/testsuite/api.py b/jinja2/testsuite/api.py
index 194e9a1..4b49819 100644
--- a/jinja2/testsuite/api.py
+++ b/jinja2/testsuite/api.py
@@ -17,7 +17,7 @@
 
 from jinja2 import Environment, Undefined, DebugUndefined, \
      StrictUndefined, UndefinedError, Template, meta, \
-     is_undefined, Template
+     is_undefined, Template, DictLoader
 from jinja2.utils import Cycler
 
 env = Environment()
@@ -76,6 +76,23 @@
         assert env.get_or_select_template([t]) is t
         assert env.get_or_select_template(t) is t
 
+    def test_autoescape_autoselect(self):
+        def select_autoescape(name):
+            if name is None or '.' not in name:
+                return False
+            return name.endswith('.html')
+        env = Environment(autoescape=select_autoescape,
+                          loader=DictLoader({
+            'test.txt':     '{{ foo }}',
+            'test.html':    '{{ foo }}'
+        }))
+        t = env.get_template('test.txt')
+        assert t.render(foo='<foo>') == '<foo>'
+        t = env.get_template('test.html')
+        assert t.render(foo='<foo>') == '&lt;foo&gt;'
+        t = env.from_string('{{ foo }}')
+        assert t.render(foo='<foo>') == '<foo>'
+
 
 class MetaTestCase(JinjaTestCase):