[svn] checked in changes from the last days regarding jinja, added jinja 1.1 notice for floor divison operator

--HG--
branch : trunk
diff --git a/CHANGES b/CHANGES
index 1fb0393..18545e5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,9 @@
 - added a bunch of new docstrings to the Jinja classes. Makes fun now to
   use pydoc :-)
 
+- fixed severe memcaching bug. Formerly it wasn't possible to use memcaching
+  without enabling disk cache.
+
 
 Version 1.0
 -----------
diff --git a/docs/src/designerdoc.txt b/docs/src/designerdoc.txt
index 959a79b..b8d7904 100644
--- a/docs/src/designerdoc.txt
+++ b/docs/src/designerdoc.txt
@@ -88,9 +88,9 @@
 
 .. admonition:: note
 
-    Filters have a pretty low priority. If you want to add fitered values
-    you have to put them into parentheses. The same applies if you want to access
-    attributes:
+    The filter operator has a pretty low priority. If you want to add fitered
+    values you have to put them into parentheses. The same applies if you want
+    to access attributes or return values:
 
     .. sourcecode:: jinja
 
@@ -104,6 +104,19 @@
         wrong:
             {{ foo|filter.attribute }}
 
+*new in Jinja 1.1*:
+
+Because the application can provide additional filters you can get a documentation
+of all the provided filters by calling ``debug.filters()``:
+
+.. sourcecode:: jinja
+
+    {{ debug.filters() }}
+        -> returns a plain text representation of all the filters
+
+    {{ debug.filters(False) }}
+        -> same as above but without the builtin ones.
+
 Tests
 =====
 
@@ -368,7 +381,8 @@
     ``/``   divide the left operand by the right one.
             ``{{ 1 / 2 }}`` would return ``0.5``.
     ``//``  divide the left operand by the right one and return a truncated
-            integer result: ``{{ 20 // 7 }}`` is ``2``.
+            integer result: ``{{ 20 // 7 }}`` is ``2``. (*new in
+	    Jinja 1.1*)
     ``*``   multiply the left operand with the right one.
             ``{{ 2 * 2 }}`` would return ``4``.
     ``**``  raise the left operand to the power of the right
diff --git a/docs/src/devintro.txt b/docs/src/devintro.txt
index 9bf7b41..11cf2f0 100644
--- a/docs/src/devintro.txt
+++ b/docs/src/devintro.txt
@@ -24,6 +24,26 @@
 If you receive an error, check if you have a typo in your code. If not, have
 a look at the `installation`_ page for troubleshooting.
 
+Basically the important method on a template is the `render` method. It
+takes either a dict or keyword arguments. All keyword arguments appear
+in the template as variables.
+
+So these two snippets do the same:
+
+.. sourcecode:: python
+
+    tmpl.render(
+        knights='we say nih',
+        spam='and eggs'
+    )
+
+.. sourcecode:: python
+
+    tmpl.render({
+        'knights':  'we say nih',
+        'spam':     'and eggs'
+    })
+
 The Environment
 ===============
 
diff --git a/docs/src/index.txt b/docs/src/index.txt
index 3a81e17..6253ec8 100644
--- a/docs/src/index.txt
+++ b/docs/src/index.txt
@@ -30,6 +30,8 @@
 
   - `Internationalization <i18n.txt>`_
 
+  - `Recipies <devrecipies.txt>`_
+
 - Template Designer Documentation:
 
   - `Syntax Reference <designerdoc.txt>`_
diff --git a/jinja/datastructure.py b/jinja/datastructure.py
index e59cda9..432e9df 100644
--- a/jinja/datastructure.py
+++ b/jinja/datastructure.py
@@ -182,7 +182,7 @@
 
 class Context(object):
     """
-    Dict like object.
+    Dict like object containing the variables for the template.
     """
 
     def __init__(self, _environment_, *args, **kwargs):
@@ -190,6 +190,9 @@
         self._stack = [_environment_.globals, dict(*args, **kwargs), {}]
         self.globals, self.initial, self.current = self._stack
 
+        # translator function added by the environment rendering function
+        self.translate_func = None
+
         # cache object used for filters and tests
         self.cache = {}
 
diff --git a/jinja/defaults.py b/jinja/defaults.py
index 7d13c60..43b67a1 100644
--- a/jinja/defaults.py
+++ b/jinja/defaults.py
@@ -10,7 +10,7 @@
 """
 from jinja.filters import FILTERS as DEFAULT_FILTERS
 from jinja.tests import TESTS as DEFAULT_TESTS
-from jinja.utils import debug_context, safe_range, generate_lorem_ipsum, \
+from jinja.utils import debug_helper, safe_range, generate_lorem_ipsum, \
      watch_changes, flush
 
 
@@ -19,7 +19,7 @@
 
 DEFAULT_NAMESPACE = {
     'range':                safe_range,
-    'debug':                debug_context,
+    'debug':                debug_helper,
     'lipsum':               generate_lorem_ipsum,
     'watchchanges':         watch_changes,
     'flush':                flush
diff --git a/jinja/parser.py b/jinja/parser.py
index ec09e60..033b101 100644
--- a/jinja/parser.py
+++ b/jinja/parser.py
@@ -474,6 +474,8 @@
                 # if a string is ASCII only we yield it as string
                 # in other cases as unicode. This works around
                 # problems with datetimeobj.strftime()
+                # also escape newlines in strings
+                t_data = t_data.replace('\n', '\\n')
                 try:
                     str(t_data)
                 except UnicodeError:
diff --git a/jinja/translators/python.py b/jinja/translators/python.py
index 1fe6335..d58537f 100644
--- a/jinja/translators/python.py
+++ b/jinja/translators/python.py
@@ -416,7 +416,8 @@
                 '    def translate(s, p=None, n=None, r=None):\n'
                 '        if p is None:\n'
                 '            return translator.gettext(s) % (r or {})\n'
-                '        return translator.ngettext(s, p, r[n]) % (r or {})'
+                '        return translator.ngettext(s, p, r[n]) % (r or {})\n'
+                '    context.translate_func = translate'
             )
 
         # add body lines and "generator hook"
@@ -585,7 +586,7 @@
         buf = []
         write = lambda x: buf.append(self.indent(x))
 
-        write('if not %r in context.current:' % name)
+        write('if %r not in context.current:' % name)
         self.indention += 1
         write(self.nodeinfo(node))
         if node.seq.__class__ in (ast.Tuple, ast.List):
@@ -683,7 +684,7 @@
         self.indention += 1
         write('yield None')
         self.indention -= 2
-        write('yield %s' % self.filter('u\'\'.join(filtered())',
+        write('yield %s' % self.filter('buffereater(filtered)()',
                                        node.filters))
         return '\n'.join(buf)
 
@@ -734,7 +735,7 @@
         else:
             replacements = 'None'
         return self.indent(self.nodeinfo(node)) + '\n' +\
-               self.indent('yield translate(%r, %r, %r, %s)' % (
+               self.indent('yield context.translate_func(%r, %r, %r, %s)' % (
             node.singular,
             node.plural,
             node.indicator,
@@ -751,7 +752,7 @@
             return self.constants[node.name]
         elif node.name == '_':
             self.require_translations = True
-            return 'translate'
+            return 'context.translate_func'
         return 'context[%r]' % node.name
 
     def handle_compare(self, node):
diff --git a/jinja/utils.py b/jinja/utils.py
index 45b19d1..33afac7 100644
--- a/jinja/utils.py
+++ b/jinja/utils.py
@@ -29,6 +29,11 @@
 else:
     deque = None
 
+try:
+    set
+except NameError:
+    from sets import Set as set
+
 #: number of maximal range items
 MAX_RANGE = 1000000
 
@@ -123,15 +128,6 @@
     return getattr(obj, name)
 
 
-def debug_context(env, context):
-    """
-    Use this function in templates to get a printed context.
-    """
-    from pprint import pformat
-    return pformat(context.to_dict())
-debug_context.jinja_context_callable = True
-
-
 def safe_range(start, stop=None, step=None):
     """
     "Safe" form of range that does not generate too large lists.
@@ -370,6 +366,48 @@
     return result
 
 
+class DebugHelper(object):
+    """
+    Debugging Helper. Available in the template as "debug".
+    """
+    jinja_context_callable = True
+    jinja_allowed_attributes = ['filters']
+
+    def __init__(self):
+        raise TypeError('cannot create %r instances' %
+                        self.__class__.__name__)
+
+    def __call__(self, env, context):
+        """Print a nice representation of the context."""
+        from pprint import pformat
+        return pformat(context.to_dict())
+
+    def filters(self, env, context, builtins=True):
+        """List the filters."""
+        from inspect import getdoc
+        strip = set()
+        if not builtins:
+            from jinja.defaults import DEFAULT_FILTERS
+            strip = set(DEFAULT_FILTERS.values())
+        filters = env.filters.items()
+        filters.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
+        result = []
+        for name, f in filters:
+            if f in strip:
+                continue
+            doc = '\n'.join('    ' + x for x in (getdoc(f) or '').splitlines())
+            result.append('`%s`\n\n%s' % (name, doc))
+        return '\n\n'.join(result)
+    filters.jinja_context_callable = True
+
+    def __str__(self):
+        print 'use debug() for debugging the context'
+
+
+#: the singleton instance of `DebugHelper`
+debug_helper = object.__new__(DebugHelper)
+
+
 class TracebackLoader(object):
     """
     Fake importer that just returns the source of a template.