some documentation improvements, jinja escapes " and ' now, both into charpoints and no named entities for html 3.2 support ;-)

--HG--
branch : trunk
diff --git a/jinja2/_speedups.c b/jinja2/_speedups.c
index 3c74bba..dcf7248 100644
--- a/jinja2/_speedups.c
+++ b/jinja2/_speedups.c
@@ -23,20 +23,20 @@
 static int
 init_constants(void)
 {
-	memset(escaped_chars_delta_len, 0, sizeof (escaped_chars_delta_len));
-
-	escaped_chars_delta_len['"'] = 5;
-	escaped_chars_repl['"'] = UNICHR(""");
-
-	escaped_chars_delta_len['&'] = 4;
+	/* happing of characters to replace */
+	escaped_chars_repl['"'] = UNICHR(""");
+	escaped_chars_repl['\''] = UNICHR("'");
 	escaped_chars_repl['&'] = UNICHR("&");
-	
-	escaped_chars_delta_len['<'] = 3;
 	escaped_chars_repl['<'] = UNICHR("&lt;");
-	
-	escaped_chars_delta_len['>'] = 3;
 	escaped_chars_repl['>'] = UNICHR("&gt;");
+
+	/* lengths of those characters when replaced - 1 */
+	memset(escaped_chars_delta_len, 0, sizeof (escaped_chars_delta_len));
+	escaped_chars_delta_len['"'] = escaped_chars_delta_len['\''] = \
+		escaped_chars_delta_len['&'] = 4;
+	escaped_chars_delta_len['<'] = escaped_chars_delta_len['>'] = 3;
 	
+	/* import markup type so that we can mark the return value */
 	PyObject *module = PyImport_ImportModule("jinja2.utils");
 	if (!module)
 		return 0;
@@ -109,16 +109,6 @@
 
 
 static PyObject*
-soft_unicode(PyObject *self, PyObject *s)
-{
-	if (!PyUnicode_Check(s))
-		return PyObject_Unicode(s);
-	Py_INCREF(s);
-	return s;
-}
-
-
-static PyObject*
 escape(PyObject *self, PyObject *text)
 {
 	PyObject *s = NULL, *rv = NULL;
@@ -156,6 +146,16 @@
 }
 
 
+static PyObject*
+soft_unicode(PyObject *self, PyObject *s)
+{
+	if (!PyUnicode_Check(s))
+		return PyObject_Unicode(s);
+	Py_INCREF(s);
+	return s;
+}
+
+
 static PyObject *
 tb_set_next(PyObject *self, PyObject *args)
 {
@@ -187,7 +187,7 @@
 	{"escape", (PyCFunction)escape, METH_O,
 	 "escape(s) -> markup\n\n"
 	 "Convert the characters &, <, >, and \" in string s to HTML-safe\n"
-	 "sequences. Use this if you need to display text that might contain\n"
+	 "sequences.  Use this if you need to display text that might contain\n"
 	 "such characters in HTML.  Marks return value as markup string."},
 	{"soft_unicode", (PyCFunction)soft_unicode, METH_O,
 	 "soft_unicode(object) -> string\n\n"
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 8b4abf6..d90d4ac 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -461,7 +461,7 @@
     def pull_locals(self, frame):
         """Pull all the references identifiers into the local scope."""
         for name in frame.identifiers.undeclared:
-            self.writeline('l_%s = context[%r]' % (name, name))
+            self.writeline('l_%s = context.resolve(%r)' % (name, name))
 
     def pull_dependencies(self, nodes):
         """Pull all the dependencies."""
diff --git a/jinja2/environment.py b/jinja2/environment.py
index a129c38..35bbb15 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -103,7 +103,7 @@
 
     `line_statement_prefix`
         If given and a string, this will be used as prefix for line based
-        statements.
+        statements.  See also :ref:`line-statements`.
 
     `trim_blocks`
         If this is set to ``True`` the first newline after a block is
diff --git a/jinja2/runtime.py b/jinja2/runtime.py
index 4b9ce6d..829de41 100644
--- a/jinja2/runtime.py
+++ b/jinja2/runtime.py
@@ -51,8 +51,10 @@
     and are allowed to access the context read-only.
 
     The template context supports read only dict operations (`get`,
-    `__getitem__`, `__contains__`) however `__getitem__` doesn't fail with
-    a `KeyError` but returns an :attr:`Undefined` object.
+    `keys`, `values`, `items`, `iterkeys`, `itervalues`, `iteritems`,
+    `__getitem__`, `__contains__`).  Additionally there is a :meth:`resolve`
+    method that doesn't fail with a `KeyError` but returns an
+    :class:`Undefined` object for missing variables.
     """
 
     def __init__(self, environment, parent, name, blocks):
@@ -95,11 +97,20 @@
         """Returns an item from the template context, if it doesn't exist
         `default` is returned.
         """
+        try:
+            return self[key]
+        except KeyError:
+            return default
+
+    def resolve(self, key):
+        """Looks up a variable like `__getitem__` or `get` but returns an
+        :class:`Undefined` object with the name of the name looked up.
+        """
         if key in self.vars:
             return self.vars[key]
         if key in self.parent:
             return self.parent[key]
-        return default
+        return self.environment.undefined(name=key)
 
     def get_exported(self):
         """Get a new dict with the exported variables."""
@@ -111,15 +122,29 @@
         """
         return dict(self.parent, **self.vars)
 
+    def _all(meth):
+        def proxy(self):
+            return getattr(self.get_all(), meth)()
+        proxy.__doc__ = getattr(dict, meth).__doc__
+        proxy.__name__ = meth
+        return proxy
+
+    keys = _all('keys')
+    values = _all('values')
+    items = _all('items')
+    iterkeys = _all('iterkeys')
+    itervalues = _all('itervalues')
+    iteritems = _all('iteritems')
+    del _all
+
     def __contains__(self, name):
         return name in self.vars or name in self.parent
 
     def __getitem__(self, key):
+        """Lookup a variable or raise `KeyError`."""
         if key in self.vars:
             return self.vars[key]
-        if key in self.parent:
-            return self.parent[key]
-        return self.environment.undefined(name=key)
+        return self.parent[key]
 
     def __repr__(self):
         return '<%s %s of %r>' % (
diff --git a/jinja2/utils.py b/jinja2/utils.py
index 13b67f9..cc60211 100644
--- a/jinja2/utils.py
+++ b/jinja2/utils.py
@@ -303,6 +303,14 @@
         stripped = u' '.join(_striptags_re.sub('', self).split())
         return Markup(stripped).unescape()
 
+    @classmethod
+    def escape(cls, s):
+        """Escape the string.  Works like :func:`escape`."""
+        rv = escape(s)
+        if rv.__class__ is not cls:
+            return cls(rv)
+        return rv
+
     def make_wrapper(name):
         orig = getattr(unicode, name)
         def func(self, *args, **kwargs):
@@ -478,8 +486,8 @@
     from jinja2._speedups import escape, soft_unicode
 except ImportError:
     def escape(s):
-        """Convert the characters &, <, >, and " in string s to HTML-safe
-        sequences. Use this if you need to display text that might contain
+        """Convert the characters &, <, >, ' and " in string s to HTML-safe
+        sequences.  Use this if you need to display text that might contain
         such characters in HTML.  Marks return value as markup string.
         """
         if hasattr(s, '__html__'):
@@ -488,6 +496,7 @@
             .replace('&', '&amp;')
             .replace('>', '&gt;')
             .replace('<', '&lt;')
+            .replace("'", '&#39;')
             .replace('"', '&quot;')
         )