even more tests, fixed severe bug with autoescaping.

--HG--
branch : trunk
diff --git a/jinja2/_speedups.c b/jinja2/_speedups.c
index 61bdec7..112e600 100644
--- a/jinja2/_speedups.c
+++ b/jinja2/_speedups.c
@@ -2,10 +2,11 @@
  * jinja2._speedups
  * ~~~~~~~~~~~~~~~~
  *
- * This module implements a few functions in C for better performance.  It
- * also defines a `tb_set_next` function that is used to patch the debug
- * traceback.  If the speedups module is not compiled a ctypes implementation
- * is used.
+ * This module implements functions for automatic escaping in C for better
+ * performance.  Additionally it defines a `tb_set_next` function to patch the
+ * debug traceback.  If the speedups module is not compiled a ctypes
+ * implementation of `tb_set_next` and Python implementations of the other
+ * functions are used.
  *
  * :copyright: 2008 by Armin Ronacher, Mickaël Guérin.
  * :license: BSD.
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 83afc34..9d68e4c 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -680,7 +680,7 @@
                 self.writeline('if parent_template is not None:')
             self.indent()
             self.writeline('for event in parent_template.'
-                           '_root_render_func(context):')
+                           'root_render_func(context):')
             self.indent()
             self.writeline('yield event')
             self.outdent(2 + (not self.has_known_extends))
@@ -784,7 +784,7 @@
             self.writeline('template = environment.get_template(', node)
             self.visit(node.template, frame)
             self.write(', %r)' % self.name)
-            self.writeline('for event in template._root_render_func('
+            self.writeline('for event in template.root_render_func('
                            'template.new_context(context.parent, True)):')
         else:
             self.writeline('for event in environment.get_template(', node)
@@ -1191,6 +1191,9 @@
         else:
             self.write(repr(val))
 
+    def visit_TemplateData(self, node, frame):
+        self.write(repr(node.as_const()))
+
     def visit_Tuple(self, node, frame):
         self.write('(')
         idx = -1
diff --git a/jinja2/environment.py b/jinja2/environment.py
index 45d684d..5ec8cb5 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -405,7 +405,7 @@
 
     def make_globals(self, d):
         """Return a dict for the globals."""
-        if d is None:
+        if not d:
             return self.globals
         return dict(self.globals, **d)
 
@@ -482,7 +482,7 @@
         t.blocks = namespace['blocks']
 
         # render function and module 
-        t._root_render_func = namespace['root']
+        t.root_render_func = namespace['root']
         t._module = None
 
         # debug and loader helpers
@@ -503,7 +503,7 @@
         """
         vars = dict(*args, **kwargs)
         try:
-            return concat(self._root_render_func(self.new_context(vars)))
+            return concat(self.root_render_func(self.new_context(vars)))
         except:
             from jinja2.debug import translate_exception
             exc_type, exc_value, tb = translate_exception(sys.exc_info())
@@ -525,7 +525,7 @@
         """
         vars = dict(*args, **kwargs)
         try:
-            for event in self._root_render_func(self.new_context(vars)):
+            for event in self.root_render_func(self.new_context(vars)):
                 yield event
         except:
             from jinja2.debug import translate_exception
@@ -533,7 +533,7 @@
             raise exc_type, exc_value, tb
 
     def new_context(self, vars=None, shared=False):
-        """Create a new template context for this template.  The vars
+        """Create a new :class:`Context` for this template.  The vars
         provided will be passed to the template.  Per default the globals
         are added to the context, if shared is set to `True` the data
         provided is used as parent namespace.  This is used to share the
@@ -611,12 +611,12 @@
     """
 
     def __init__(self, template, context):
-        self._body_stream = list(template._root_render_func(context))
+        self._body_stream = list(template.root_render_func(context))
         self.__dict__.update(context.get_exported())
         self.__name__ = template.name
 
-    __html__ = lambda x: Markup(concat(x._body_stream))
     __unicode__ = lambda x: concat(x._body_stream)
+    __html__ = lambda x: Markup(concat(x._body_stream))
 
     def __str__(self):
         return unicode(self).encode('utf-8')
diff --git a/jinja2/filters.py b/jinja2/filters.py
index ed3d57c..de15b53 100644
--- a/jinja2/filters.py
+++ b/jinja2/filters.py
@@ -598,6 +598,11 @@
     return Markup(value)
 
 
+def do_mark_unsafe(value):
+    """Mark a value as unsafe.  This is the reverse operation for :func:`safe`."""
+    return unicode(value)
+
+
 def do_reverse(value):
     """Reverse the object or return an iterator the iterates over it the other
     way round.
diff --git a/jinja2/nodes.py b/jinja2/nodes.py
index 9eb5460..0cccddf 100644
--- a/jinja2/nodes.py
+++ b/jinja2/nodes.py
@@ -431,6 +431,16 @@
         return cls(value, lineno=lineno, environment=environment)
 
 
+class TemplateData(Literal):
+    """A constant template string."""
+    fields = ('data',)
+
+    def as_const(self):
+        if self.environment.autoescape:
+            return Markup(self.data)
+        return self.data
+
+
 class Tuple(Literal):
     """For loop unpacking and some other things like multiple arguments
     for subscripts.  Like for :class:`Name` `ctx` specifies if the tuple
diff --git a/jinja2/parser.py b/jinja2/parser.py
index 8ca1bd2..fcc684b 100644
--- a/jinja2/parser.py
+++ b/jinja2/parser.py
@@ -723,7 +723,8 @@
             token = self.stream.current
             if token.type is 'data':
                 if token.value:
-                    add_data(nodes.Const(token.value, lineno=token.lineno))
+                    add_data(nodes.TemplateData(token.value,
+                                                lineno=token.lineno))
                 self.stream.next()
             elif token.type is 'variable_begin':
                 self.stream.next()
diff --git a/jinja2/runtime.py b/jinja2/runtime.py
index 1325b17..590bed9 100644
--- a/jinja2/runtime.py
+++ b/jinja2/runtime.py
@@ -110,7 +110,7 @@
 
     def get_all(self):
         """Return a copy of the complete context as dict including the
-        global variables.
+        exported variables.
         """
         return dict(self.parent, **self.vars)