[svn] add first part of jinja documentation

--HG--
branch : trunk
diff --git a/docs/build/jinjabanner.png b/docs/build/jinjabanner.png
new file mode 100644
index 0000000..c672118
--- /dev/null
+++ b/docs/build/jinjabanner.png
Binary files differ
diff --git a/docs/build/jinjalogo.png b/docs/build/jinjalogo.png
new file mode 100644
index 0000000..17d6dc3
--- /dev/null
+++ b/docs/build/jinjalogo.png
Binary files differ
diff --git a/docs/build/style.css b/docs/build/style.css
new file mode 100644
index 0000000..64cba24
--- /dev/null
+++ b/docs/build/style.css
@@ -0,0 +1,196 @@
+body {
+    background-color: #333;
+    margin: 0;
+    padding: 0;
+    font-family: 'Georgia', serif;
+    font-size: 15px;
+    color: #111;
+}
+
+#content {
+    background-color: white;
+    background-image: url(watermark.png);
+    padding: 10px;
+    margin: 25px;
+    border: 4px solid #ddd;
+}
+
+h1 {
+    margin: 0;
+    padding: 0;
+    height: 80px;
+    background-image: url(jinjabanner.png);
+    background-repeat: no-repeat;
+}
+
+h1 span {
+    display: none;
+}
+
+h2.subheading {
+    margin: -55px 0 35px 200px;
+    font-weight: normal;
+    font-size: 30px;
+    color: #444;
+}
+
+h2.plain {
+    margin: 0;
+}
+
+#jinjalogo {
+    background-image: url(jinjalogo.png);
+    background-repeat: no-repeat;
+    width: 400px;
+    height: 160px;
+}
+
+#contentwrapper {
+    max-width: 700px;
+    padding: 0 0 20px 18px;
+}
+
+#contentwrapper h3,
+#contentwrapper h3 a {
+    color: #b41717;
+    font-size: 26px;
+    margin: 20px 0 0 -5px;
+}
+
+#contentwrapper h4,
+#contentwrapper h4 a {
+    color: #b41717;
+    font-size: 20px;
+    margin: 20px 0 0 0;
+}
+
+table.docutils {
+    border-collapse: collapse;
+    border: 2px solid #aaa;
+    margin: 0.5em 1.5em 0.5em 1.5em;
+}
+
+table.docutils td {
+    padding: 2px;
+    border: 1px solid #ddd;
+}
+
+p, li, dd, dt, blockquote {
+    color: #333;
+}
+
+p {
+    line-height: 150%;
+    margin-bottom: 0;
+    margin-top: 10px;
+    text-align: justify;
+}
+
+hr {
+    border-top: 1px solid #ccc;
+    border-bottom: 0;
+    border-right: 0;
+    border-left: 0;
+    margin-bottom: 10px;
+    margin-top: 20px;
+}
+
+dl {
+    margin-left: 10px;
+}
+
+li, dt {
+    margin-top: 5px;
+}
+
+dt {
+    font-weight: bold;
+}
+
+th {
+    text-align: left;
+    padding: 3px;
+    background-color: #f2f2f2;
+}
+
+a {
+    color: #b41717;
+}
+
+a:hover {
+    color: #444;
+}
+
+pre {
+    background-color: #f9f9f9;
+    border-top: 1px solid #ccc;
+    border-bottom: 1px solid #ccc;
+    padding: 5px;
+    font-size: 13px;
+    font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+}
+
+tt {
+    font-size: 13px;
+    font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+    color: black;
+    padding: 1px 2px 1px 2px;
+    background-color: #f0f0f0;
+}
+
+cite {
+    /* abusing <cite>, it's generated by ReST for `x` */
+    font-size: 13px;
+    font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+    font-weight: bold;
+    font-style: normal;
+}
+
+div.admonition {
+    margin: 10px 0 10px 0;
+    padding: 10px;
+    border: 1px solid #ccc;
+    background-color: #f8f8f8;
+}
+
+div.admonition p.admonition-title {
+    margin: -3px 0 5px 0;
+    font-weight: bold;
+    color: #b41717;
+    font-size: 16px;
+}
+
+div.admonition p {
+    margin: 0 0 0 40px;
+}
+
+#toc {
+    margin: 0 -10px 10px 15px;
+    padding: 10px;
+    width: 200px;
+    float: right;
+    background-color: #f8f8f8;
+    border: 1px solid #ccc;
+    border-right: none;
+}
+
+#toc h2 {
+    font-size: 20px;
+    margin: 0 0 10px 0;
+    padding: 0;
+    color: #444;
+}
+
+#toc ul {
+    margin: 0 0 0 30px;
+    padding: 0;
+}
+
+#toc ul + h2 {
+    margin-top: 10px;
+}
+
+#toc ul li {
+    padding: 0;
+    margin: 2px 0 2px 0;
+}
diff --git a/docs/build/watermark.png b/docs/build/watermark.png
new file mode 100644
index 0000000..297d899
--- /dev/null
+++ b/docs/build/watermark.png
Binary files differ
diff --git a/docs/generate.py b/docs/generate.py
new file mode 100755
index 0000000..0c155c0
--- /dev/null
+++ b/docs/generate.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    Generate Jinja Documentation
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Generates a bunch of html files containing the documentation.
+
+    :copyright: 2006-2007 by Armin Ronacher, Georg Brandl.
+    :license: BSD, see LICENSE for more details.
+"""
+import os
+import sys
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
+import re
+import inspect
+from datetime import datetime
+from cgi import escape
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.core import publish_parts
+from docutils.writers import html4css1
+
+from jinja import Environment
+
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name
+from pygments.formatters import HtmlFormatter
+
+def generate_list_of_filters():
+    from jinja.filters import FILTERS
+    result = []
+
+    filters = {}
+    for name, f in FILTERS.iteritems():
+        if not f in filters:
+            filters[f] = ([name], inspect.getdoc(f))
+        else:
+            filters[f][0].append(name)
+    for names, _ in filters.itervalues():
+        names.sort(key=lambda x: -len(x))
+
+    for names, doc in sorted(filters.values(), key=lambda x: x[0][0].lower()):
+        name = names[0]
+        if len(names) > 1:
+            aliases = '\n\n    :Aliases: %s\n' % ', '.join(names[1:])
+        else:
+            aliases = ''
+
+        doclines = []
+        for line in doc.splitlines():
+            doclines.append('    ' + line)
+        doc = '\n'.join(doclines)
+        result.append('`%s`\n%s%s' % (name, doc, aliases))
+
+    return '\n'.join(result)
+
+def generate_list_of_tests():
+    from jinja.tests import TESTS
+    result = []
+
+    tests = {}
+    for name, f in TESTS.iteritems():
+        if not f in tests:
+            tests[f] = ([name], inspect.getdoc(f))
+        else:
+            tests[f][0].append(name)
+    for names, _ in tests.itervalues():
+        names.sort(key=lambda x: -len(x))
+
+    for names, doc in sorted(tests.values(), key=lambda x: x[0][0].lower()):
+        name = names[0]
+        if len(names) > 1:
+            aliases = '\n\n    :Aliases: %s\n' % ', '.join(names[1:])
+        else:
+            aliases = ''
+
+        doclines = []
+        for line in doc.splitlines():
+            doclines.append('    ' + line)
+        doc = '\n'.join(doclines)
+        result.append('`%s`\n%s%s' % (name, doc, aliases))
+
+    return '\n'.join(result)
+
+def generate_list_of_loaders():
+    from jinja import loaders as loader_module
+
+    result = []
+    loaders = []
+    for item in loader_module.__all__:
+        loaders.append(getattr(loader_module, item))
+    loaders.sort(key=lambda x: x.__name__.lower())
+
+    for loader in loaders:
+        doclines = []
+        for line in inspect.getdoc(loader).splitlines():
+            doclines.append('    ' + line)
+        result.append('`%s`\n%s' % (loader.__name__, '\n'.join(doclines)))
+
+    return '\n\n'.join(result)
+
+e = Environment()
+
+PYGMENTS_FORMATTER = HtmlFormatter(style='pastie', cssclass='syntax')
+
+LIST_OF_FILTERS = generate_list_of_filters()
+LIST_OF_TESTS = generate_list_of_tests()
+LIST_OF_LOADERS = generate_list_of_loaders()
+
+TEMPLATE = e.from_string('''\
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>{{ title }} &mdash; Jinja Documentation</title>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <link rel="stylesheet" href="style.css" type="text/css">
+  <style type="text/css">
+    {{ style|e }}
+  </style>
+</head>
+<body>
+  <div id="content">
+    {% if file_id == 'index' %}
+      <div id="jinjalogo"></div>
+      <h2 class="subheading plain">{{ title }}</h2>
+    {% else %}
+      <h1 class="heading"><span>Jinja</span></h1>
+      <h2 class="subheading">{{ title }}</h2>
+    {% endif %}
+    {% if file_id != 'index' or toc %}
+    <div id="toc">
+      <h2>Navigation</h2>
+      <ul>
+        <li><a href="index.html">back to index</a></li>
+      </ul>
+      {% if toc %}
+        <h2>Contents</h2>
+        <ul class="contents">
+        {% for key, value in toc %}
+          <li><a href="{{ key }}">{{ value }}</a></li>
+        {% endfor %}
+        </ul>
+      {% endif %}
+    </div>
+    {% endif %}
+    <div id="contentwrapper">
+      {{ body }}
+    </div>
+  </div>
+</body>
+<!-- generated on: {{ generation_date }}
+     file id: {{ file_id }} -->
+</html>\
+''')
+
+def pygments_directive(name, arguments, options, content, lineno,
+                      content_offset, block_text, state, state_machine):
+    try:
+        lexer = get_lexer_by_name(arguments[0])
+    except ValueError:
+        # no lexer found
+        lexer = get_lexer_by_name('text')
+    parsed = highlight(u'\n'.join(content), lexer, PYGMENTS_FORMATTER)
+    return [nodes.raw('', parsed, format="html")]
+pygments_directive.arguments = (1, 0, 1)
+pygments_directive.content = 1
+directives.register_directive('sourcecode', pygments_directive)
+
+
+def create_translator(link_style):
+    class Translator(html4css1.HTMLTranslator):
+        def visit_reference(self, node):
+            refuri = node.get('refuri')
+            if refuri is not None and '/' not in refuri and refuri.endswith('.txt'):
+                node['refuri'] = link_style(refuri[:-4])
+            html4css1.HTMLTranslator.visit_reference(self, node)
+    return Translator
+
+
+class DocumentationWriter(html4css1.Writer):
+
+    def __init__(self, link_style):
+        html4css1.Writer.__init__(self)
+        self.translator_class = create_translator(link_style)
+
+    def translate(self):
+        html4css1.Writer.translate(self)
+        # generate table of contents
+        contents = self.build_contents(self.document)
+        contents_doc = self.document.copy()
+        contents_doc.children = contents
+        contents_visitor = self.translator_class(contents_doc)
+        contents_doc.walkabout(contents_visitor)
+        self.parts['toc'] = self._generated_toc
+
+    def build_contents(self, node, level=0):
+        sections = []
+        i = len(node) - 1
+        while i >= 0 and isinstance(node[i], nodes.section):
+            sections.append(node[i])
+            i -= 1
+        sections.reverse()
+        toc = []
+        for section in sections:
+            try:
+                reference = nodes.reference('', '', refid=section['ids'][0], *section[0])
+            except IndexError:
+                continue
+            ref_id = reference['refid']
+            text = escape(reference.astext().encode('utf-8'))
+            toc.append((ref_id, text))
+
+        self._generated_toc = [('#%s' % href, caption) for href, caption in toc]
+        # no further processing
+        return []
+
+
+def generate_documentation(data, link_style):
+    writer = DocumentationWriter(link_style)
+    data = data.replace('[[list_of_filters]]', LIST_OF_FILTERS)\
+               .replace('[[list_of_tests]]', LIST_OF_TESTS)\
+               .replace('[[list_of_loaders]]', LIST_OF_LOADERS)
+    parts = publish_parts(
+        data,
+        writer=writer,
+        settings_overrides={
+            'initial_header_level': 3,
+            'field_name_limit': 50,
+        }
+    )
+    return {
+        'title':        parts['title'].encode('utf-8'),
+        'body':         parts['body'].encode('utf-8'),
+        'toc':          parts['toc']
+    }
+
+
+def handle_file(filename, fp, dst):
+    now = datetime.now()
+    title = os.path.basename(filename)[:-4]
+    content = fp.read()
+    parts = generate_documentation(content, (lambda x: './%s.html' % x))
+    result = file(os.path.join(dst, title + '.html'), 'w')
+    c = dict(parts)
+    c['style'] = PYGMENTS_FORMATTER.get_style_defs('.syntax')
+    c['generation_date'] = now
+    c['file_id'] = title
+    result.write(TEMPLATE.render(c).encode('utf-8'))
+    result.close()
+
+
+def run(dst, sources=()):
+    path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))
+    if not sources:
+        sources = [os.path.join(path, fn) for fn in os.listdir(path)]
+    for fn in sources:
+        if not os.path.isfile(fn):
+            continue
+        print 'Processing %s' % fn
+        f = open(fn)
+        try:
+            handle_file(fn, f, dst)
+        finally:
+            f.close()
+
+
+def main(dst='build/', *sources):
+    return run(os.path.realpath(dst), sources)
+
+
+if __name__ == '__main__':
+    main(*sys.argv[1:])
diff --git a/docs/src/designerdoc.txt b/docs/src/designerdoc.txt
new file mode 100644
index 0000000..c3db752
--- /dev/null
+++ b/docs/src/designerdoc.txt
@@ -0,0 +1,432 @@
+======================
+Designer Documentation
+======================
+
+This part of the Jinja documentaton is meant for template designers.
+
+Basics
+======
+
+The Jinja template language is designed to strike a balance between content
+and application logic. Nevertheless you can use a python like statement
+language. You don't have to know how Python works to create Jinja templates,
+but if you know it you can use some additional statements you may know from
+Python.
+
+Here is a small example template:
+
+.. sourcecode:: html+jinja
+
+    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+    <head>
+        <title>My Webpage</title>
+    </head>
+    <body>
+        <ul id="navigation">
+        {% for item in navigation %}
+            <li><a href="{{ item.href|e }}">{{ item.caption|e }}</a></li>
+        {% endfor %}
+        </ul>
+
+        <h1>My Webpage</h1>
+        {{ variable }}
+    </body>
+    </html>
+
+This covers the default settings. The application developer might have changed
+the syntax from ``{% foo %}`` to ``<% foo %>`` or something similar. This
+documentation just covers the default values.
+
+A variable looks like ``{{ foobar }}`` where foobar is the variable name. Inside
+of statements (``{% some content here %}``) variables are just normal names
+without the braces around it. In fact ``{{ foobar }}`` is just an alias for
+the statement ``{% print foobar %}``.
+
+Variables are coming from the context provided by the application. Normally there
+should be a documentation regarding the context contents but if you want to know
+the content of the current context you can add this to your template:
+
+.. sourcecode:: html+jinja
+
+    <pre>{{ debug()|e }}</pre>
+
+A context isn't flat which means that each variable can has subvariables, as long
+as it is representable as python data structure. You can access attributes of
+a variable by using the dot and brace operators. The following examples show
+this:
+
+.. sourcecode:: jinja
+
+    {{ user.username }}
+        is the same as
+    {{ user['username'] }}
+        you can also use a variable to access an attribute:
+    {{ users[current_user].username }}
+        If you have numerical indices you have to use the [] syntax:
+    {{ users[0].username }}
+
+Filters
+=======
+
+In the examples above you might have noticed the pipe symbols. Pipe symbols tell
+the engine that it has to apply a filter on the variable. Here a small example:
+
+.. sourcecode:: jinja
+
+    {{ variable|replace('foo', 'bar')|escape }}
+
+If you like you can also put whitespace between the filters.
+
+This will look for a variable variable, passes it to the filter replace with the
+arguments ``'foo'`` and ``'bar'``, and passes the result to the filter `escape`
+that automatically xml escapes the value. The ``e`` filter is an alias for
+``escape``. Here the complete list of supported filters:
+
+[[list_of_filters]]
+
+Tests
+=====
+
+You can use the `is`-operator to perform tests on a value:
+
+.. sourcecode:: jinja
+
+    {{ 42 is numeric }} -> true
+    {{ "foobar" is numeric }} -> false
+    {{ 'FOO' is upper }} -> true
+
+Those tests are especially useful if used in `if`-conditions.
+
+[[list_of_tests]]
+
+Loops
+=====
+
+To iterate over a sequence you can use the `for`-loop. If basically looks like a
+normal python for loop and works pretty much the same:
+
+.. sourcecode:: html+jinja
+
+    <h1>Members</h1>
+    <ul>
+    {% for user in users %}
+      <li>{{ loop.index }} / {{ loop.length }} - {{ user.username|escape }}</li>
+    {% else %}
+      <li><em>no users found</em></li>
+    {% endfor %}
+    </ul>
+
+The optional ``else`` block is only executed if the template did not iterate
+because the sequence was empty.
+
+Inside of a for loop block you can access some special variables:
+
++----------------------+----------------------------------------+
+| Variable             | Description                            |
++======================+========================================+
+| ``loop.index``       | The current iteration of the loop.     |
++----------------------+----------------------------------------+
+| ``loop.index0``      | The current iteration of the loop,     |
+|                      | starting counting by 0.                |
++----------------------+----------------------------------------+
+| ``loop.revindex``    | The number of iterations from the end  |
+|                      | of the loop.                           |
++----------------------+----------------------------------------+
+| ``loop.revindex0``   | The number of iterations from the end  |
+|                      | of the loop, starting counting by 0.   |
++----------------------+----------------------------------------+
+| ``loop.first``       | True if first iteration.               |
++----------------------+----------------------------------------+
+| ``loop.last``        | True if last iteration.                |
++----------------------+----------------------------------------+
+| ``loop.even``        | True if current iteration is even.     |
++----------------------+----------------------------------------+
+| ``loop.odd``         | True if current iteration is odd.      |
++----------------------+----------------------------------------+
+| ``loop.length``      | Total number of items in the sequence. |
++----------------------+----------------------------------------+
+| ``loop.parent``      | The context of the parent loop.        |
++----------------------+----------------------------------------+
+
+Loops also support recursion. For example you have a sitemap where each item
+might have a number of child items. Such a template could look like this:
+
+.. sourcecode:: html+jinja
+
+    <h1>Sitemap
+    <ul id="sitemap">
+    {% for item in sitemap recursive %}
+      <li><a href="{{ item.url|e }}">{{ item.title|e }}</a>
+      {% if item.children %}<ul>{{ loop(item.children) }}</ul>{% endif %}</li>
+    {% endfor %}
+    </ul>
+
+Now. What happens here? Basically the first thing that is different to a normal
+loop is the additional ``recursive`` modifier in the `for`-loop declaration.
+It tells the template engine that we want recursion. If recursion is enabled
+the special loop variable is callable. If you call it with a sequence it will
+automatically render that loop at that position with the new sequence as argument.
+
+Cycling
+=======
+
+Sometimes you might want to have different classes for each row in a list. For
+example to have alternating row colors. You can easily do this by using the
+``{% cycle %}`` tag:
+
+.. sourcecode:: html+jinja
+
+    <ul id="messages">
+    {% for message in messages %}
+      <li class="{% cycle 'row1', 'row2' %}">{{ message|e }}</li>
+    {% endfor %}
+    </ul>
+
+Each time Jinja encounters a cycle tag it will evaluate cycle through the list
+of given items and return the next one. If you pass it one item jinja assumes
+that this item is a sequence from the context and uses this:
+
+.. sourcecode:: html+jinja
+
+    <li style="color: {% cycle rowcolors %}">...</li>
+
+Conditions
+==========
+
+Jinja supports python like ``if`` / ``elif`` / ``else`` constructs:
+
+.. sourcecode:: jinja
+
+    {% if user.active %}
+        user {{ user.name|e }} is active.
+    {% elif user.deleted %}
+        user {{ user.name|e }} was deleted some time ago.
+    {% else %}
+        i don't know what's wrong with {{ user.username|e }}
+    {% endif %}
+
+If the user is active the first block is rendered. If not and the user was
+deleted the second one, in all other cases the third one.
+
+You can also use comparison operators:
+
+.. sourcecode:: html+jinja
+
+    {% if amount < 0 %}
+        <span style="color: red">{{ amount }}</span>
+    {% else %}
+        <span style="color: black">{{ amount }}</span>
+    {% endif %}
+
+.. admonition:: Note
+
+    Of course you can use `or` / `and` and parenthesis to create more complex
+    conditions but usually the logic is already handled in the application and
+    you don't have to create such complex constucts in the template code. However
+    in some situations it might be a good thing to have the abilities to create
+    them.
+
+Operators
+=========
+
+Inside ``{{ variable }}`` blocks, `if`-conditions and many other parts you can
+can use Expressions. In expressions you can use any of the following operators:
+
+    ======= ===================================================================
+    ``+``   add the right operand to the left one.
+            ``{{ 1 + 2 }}`` would return three.
+    ``-``   substract the right operand from the left one.
+            ``{{ 1 - 1 }}`` would return zero.
+    ``/``   divide the right from the left operand.
+            ``{{ 1 / 2 }}`` would return 0.5
+    ``*``   multiply the left operand with the right.
+            ``{{ 2 * 2}}`` would return 4
+    ``**``  raise the left operand to the power of the right
+            operand. ``{{ 2**3 }}`` would return 8
+    ``is``  perform a test on the value. See the section about
+            tests for more information.
+    ``|``   apply a filter on the value. See the section about
+            filters for more information.
+    ``and`` return true if the left and the right operand is true.
+    ``or``  return true if the left or the right operand is true.
+    ``()``  call a callable. ``{{ user.get_username() }}``. Inside of the
+            parenthesis you can use variables: ``{{ user.get('username') }}``.
+    ======= ===================================================================
+
+Note that there is no support for any bit operation or something similar.
+
+Macros
+======
+
+If you want to use a partial template on more than one place you might want to
+create a macro out of it:
+
+.. sourcecode:: html+jinja
+
+    {% macro show_user user %}
+      <h1>{{ user.name|e }}</h1>
+      <div class="test">
+        {{ user.description }}
+      </div>
+    {% endmacro %}
+
+Now you can use it from everywhere in the code by passing it an item:
+
+.. sourcecode:: jinja
+    
+    {% for user in users %}
+        {{ show_user(user) }}
+    {% endfor %}
+
+You can also specify more then one value:
+
+.. sourcecode:: html+jinja
+
+    {% macro show_dialog title, text %}
+      <div class="dialog">
+        <h1>{{ title|e }}</h1>
+        <div class="test">{{ text|e }}</div>
+      </div>
+    {% endmacro %}
+
+    {{ show_dialog('Warning', 'something went wrong i guess') }}
+
+Inheritance
+===========
+
+The most powerful part of Jinja is template inheritance. Template inheritance
+allows you to build a base "skeleton" template that contains all the common
+elements of your site and defines **blocks** or **markers** that child
+templates can override.
+
+Sounds complicated but is very basic. It's easiest to understand it by starting
+with an example.
+
+Base Template
+-------------
+
+This template, which we'll call ``base.html``, defines a simple HTML skeleton
+document that you might use for a simple two-column page. It's the job of
+"child" templates to fill the empty blocks with content:
+
+.. sourcecode:: html+jinja
+
+    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+      <link rel="stylesheet" href="style.css" />
+      <title>{% block title %}{% endblock %} - My Webpage</title>
+      {% block html_head %}{% endblock %}
+    </head>
+    <body>
+      <div id="content">
+        {% block content %}{% endblock %}
+      </div>
+
+      <div id="footer">
+        {% block "footer" %}
+        &copy; Copyright 2006 by <a href="http://mydomain.tld">myself</a>.
+        {% endblock %}
+      </div>
+    </body>
+
+In this example, the ``{% block %}`` tags define four blocks that child templates
+can fill in. All the ``block`` tag does is to tell the template engine that a
+child template may override those portions of the template.
+
+Child Template
+--------------
+
+A child template might look like this:
+
+.. sourcecode:: html+jinja
+
+    {% extends "base.html" %}
+    {% block title %}Index{% endblock %}
+
+    {% block html_head %}
+      <style type="text/css">
+        .important {
+          color: #336699;
+        }
+      </style>
+    {% endblock %}
+    
+    {% block content %}
+        <h1>Index</h1>
+        <p class="important">
+          Welcome on my awsome homepage.
+        </p>
+    {% endblock %}
+
+The ``{% extends %}`` tag is the key here. It tells the template engine that
+this template "extends" another template. When the template system evaluates
+this template, first it locates the parent.
+
+The filename of the template depends on the template loader. For example the
+``FileSystemLoader`` allows you to access other templates by giving the
+filename. You can access subdirectory with an slash:
+
+.. sourcecode:: jinja
+
+    {% extends "layout/default.html" %}
+
+But this behavior can depend on the application using Jinja.
+
+Note that since the child template didn't define the ``footer`` block, the
+value from the parent template is used instead.
+
+.. admonition:: Note
+
+    You can't define multiple ``{% block %}`` tags with the same name in the
+    same template. This limitation exists because a block tag works in "both"
+    directions. That is, a block tag doesn't just provide a hole to fill - it
+    also defines the content that fills the hole in the *parent*. If there were
+    two similarly-named ``{% block %}`` tags in a template, that template's
+    parent wouldn't know which one of the blocks' content to use.
+
+Template Inclusion
+==================
+
+You can load another template at a given posiiton using ``{% include %}``.
+Usually it's a better idea to use inheritance but if you for example want to
+load macros ``include`` works better than ``extends``:
+
+.. sourcecode:: jinja
+
+    {% include "myhelpers.html" %}
+    {{ my_helper("foo") }}
+
+If you define a macro called ``my_helper`` in ``myhelpers.html`` you can now
+use it from the template as shown above.
+
+Filtering Blocks
+================
+
+Sometimes it could be a good idea to filter a complete block. For example if
+you want to escape some html code:
+
+.. sourcecode:: jinja
+
+    {% filter escape %}
+        <html>
+          <code>goes here</code>
+        </html>
+    {% endfilter %}
+
+Of course you can chain filters too.
+
+Defining Variables
+==================
+
+You can also define variables in the namespace using the ``{% set %}`` tag:
+
+.. sourcecode:: jinja
+
+    {% set foo = 'foobar' %}
+    {{ foo }}
+
+This should ouputput ``foobar``.
diff --git a/docs/src/devintro.txt b/docs/src/devintro.txt
new file mode 100644
index 0000000..157301c
--- /dev/null
+++ b/docs/src/devintro.txt
@@ -0,0 +1,139 @@
+====================
+Developer Quickstart
+====================
+
+This part of the documentation shows you how to embedd Jinja into your
+application.
+
+Starting Up
+===========
+
+Here the quickest way to create a template from a string and render it:
+
+.. sourcecode:: python
+
+    from jinja import Environment
+    env = Environment()
+    tmpl = env.from_string('Hello {{ name }}!')
+    print tmpl.render(name='John Doe')
+
+This example should output the following string after execution::
+
+    Hello John Doe!
+
+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.
+
+The Environment
+===============
+
+The core component of Jinja is the `Environment`. It helds important shared
+variables like configuration, filters, tests, globals and other stuff.
+
+Here the possible initialisation parameters:
+
+=========================== ==================================================
+``block_start_string`` *    the string marking the begin of a block. this
+                            defaults to ``'{%'``.
+``block_end_string`` *      the string marking the end of a block. defaults
+                            to ``'%}'``.
+``variable_start_string`` * the string marking the begin of a print
+                            statement. defaults to ``'{{'``.
+``comment_start_string`` *  the string marking the begin of a
+                            comment. defaults to ``'{#'``.
+``comment_end_string`` *    the string marking the end of a comment.
+                            defaults to ``'#}'``.
+``trim_blocks`` *           If this is set to ``True`` the first newline
+                            after a block is removed (block, not
+                            variable tag!). Defaults to ``False``.
+``auto_escape``             If this is set to ``True`` Jinja will
+                            automatically escape all variables using xml
+                            escaping methods. If you don't want to escape a
+                            string you have to wrap it in a ``Markup``
+                            object from the ``jinja.datastructure`` module.
+``template_charset``        The charset of the templates. Defaults
+                            to ``'utf-8'``.
+``charset``                 Charset of all string input data. Defaults
+                            to ``'utf-8'``.
+``namespace``               Global namespace for all templates.
+``loader``                  Specify a template loader.
+``filters``                 dict of filters or the default filters if not
+                            defined.
+``tests``                   dict of tests of the default tests if not defined.
+=========================== ==================================================
+
+All of this variables except those marked with a star(*) are modifyable after
+environment initialisation.
+
+The environment provides the following useful functions and properties
+additional to the initialisation values:
+
+=========================== ==================================================
+``parse(source, filename)`` Parse the sourcecode and return the abstract
+                            syntax tree. This tree of nodes is used by the
+                            `translators`_ to convert the template into
+                            executable source- or bytecode.
+``from_string(source)``     Load and parse a template source and translate it
+                            into evaluable python code. This code is wrapped
+                            with in a `Template` class that allows you to
+                            render it.
+``get_template(name)``      load a template from a loader. If the template
+                            does not exist you will get a `TemplateNotFound`
+                            exception.
+=========================== ==================================================
+
+There are also some internal functions on the environment used by the template
+evaluation code to keep it sandboxed.
+
+Loading Templates From Files
+============================
+
+Loading templates from a string is always a bad idea. It doesn't allow template
+inheritance and is also slow since it parses and compiles the template again
+and again whereas loaders can cache the template code.
+
+All you have to do is to define a loader and use the `get_template` function.
+
+.. sourcecode:: python
+
+    from jinja import Environment, FileSystemLoader
+    env = Environment(loader=FileSystemLoader('templates'))
+    tmpl = env.get_template('index.html')
+    print tmpl.render(name='John Doe')
+
+This tells jinja to look for templates in the ``templates`` folder. It's a
+better idea to use an absolute path here though. For a list of supported
+loaders or how to write your own, head over to the `loader`_ documentation.
+
+Adding Filters
+==============
+
+If you want to add additional filters to the environment the best way is to
+modify the ``filters`` attribute and not to pass a dict to the environment.
+If you pass it a dict it will not include the default filters!
+
+.. sourcecode:: python
+
+    from mylib import my_cool_filter
+    env.filters['mycoolfilter'] = my_cool_filter
+
+Writing filter functions is explained in the `filter development`_ section.
+
+Adding Tests
+============
+
+Adding additional tests works analog to filters:
+
+.. sourcecode:: python
+
+    from mylib import my_cool_test
+    env.tests['mycooltest'] = my_cool_test
+
+Writing tests is explained in the `test development`_ section.
+
+
+.. _installation: installation.txt
+.. _translators: translators.txt
+.. _loader: loaders.txt
+.. _filter development: filters.txt
+.. _test development: tests.txt
diff --git a/docs/src/fromdjango.txt b/docs/src/fromdjango.txt
new file mode 100644
index 0000000..71b2068
--- /dev/null
+++ b/docs/src/fromdjango.txt
@@ -0,0 +1,108 @@
+===============================
+Differences To Django Templates
+===============================
+
+If you have previously worked with Django templates you should feel very
+familiar. In fact most of the syntax elements look and work the same.
+
+However Jinja provides some more syntax elements covered in the documentation
+and some work a bit different.
+
+Method Calls
+============
+
+In Django method calls work implicit. With Jinja you have to tell it that you
+want to call it. Thus this Django code:
+
+.. sourcecode:: django
+
+    {% for page in user.get_created_pages %}
+      ...
+    {% endfor %}
+
+will look like this in Jinja:
+
+.. sourcecode:: jinja
+
+    {% for page in user.get_created_pages() %}
+      ...
+    {% endfor %}
+
+This allows you to pass variables to the function which is also used for
+macros and loop recursion, both features that don't exist in Django.
+
+Conditions
+==========
+
+In Django you can use the following constructs to check for equality:
+
+.. sourcecode:: django
+
+    {% ifequals foo "bar" %}
+        ...
+    {% else %}
+        ...
+    {% endifequals %}
+
+In Jinja you can use the normal ``if`` statement in combination with
+operators:
+
+.. sourcecode:: jinja
+
+    {% if foo == 'bar' %}
+        ...
+    {% else %}
+        ...
+    {% endif %}
+
+You can also have multiple ``elif`` branches in your template:
+
+.. sourcecode:: jinja
+
+    {% if something %}
+        ...
+    {% elif otherthing %}
+        ...
+    {% elif foothing %}
+        ...
+    {% else %}
+        ...
+    {% endif %}
+
+Filter Arguments
+================
+
+Jinja provides more than one argument for a filter. Also the syntax for argument
+passing is different. A template that looks like this in Django:
+
+.. sourcecode:: django
+
+    {{ items|join:", " }}
+
+looks like this in jinja:
+
+.. sourcecode:: jinja
+
+    {{ items|join(', ') }}
+
+In fact it's a bit more to write but it allows different type of arguments including
+variables and more then one of them.
+
+Tests
+=====
+
+Additionally to filters there also exists tests you can perform using the `is`
+operator. Here some examples:
+
+.. sourcecode:: jinja
+
+    {% if user.user_id is odd %}
+        {{ user.username|e }} is odd
+    {% else %}
+        hmm. {{ user.username|e }} looks pretty normal
+    {% endif %}
+
+For a list of supported tests head over to the `syntax reference`_.
+
+
+.. _syntax reference: designerdoc.txt
diff --git a/docs/src/index.txt b/docs/src/index.txt
new file mode 100644
index 0000000..250a5a3
--- /dev/null
+++ b/docs/src/index.txt
@@ -0,0 +1,25 @@
+======================
+Documentation Overview
+======================
+
+Welcome in the Jinja documentation.
+
+- `Installing Jinja <installation.txt>`_
+
+- Application Developer Documentation:
+
+  - `Quickstart <devintro.txt>`_
+
+  - `Template Loaders <loaders.txt>`_
+
+  - `Filter Functions <filters.txt>`_
+
+  - `Test Functions <tests.txt>`_
+
+  - `Translators <translators.txt>`_
+
+- Template Designer Documentation:
+
+  - `Syntax Reference <designerdoc.txt>`_
+
+  - `Differences To Django <fromdjango.txt>`_
diff --git a/docs/src/loaders.txt b/docs/src/loaders.txt
new file mode 100644
index 0000000..dbe4df3
--- /dev/null
+++ b/docs/src/loaders.txt
@@ -0,0 +1,10 @@
+================
+Template Loaders
+================
+
+This part of the documentation explains how to use and write a template loader.
+
+Builtin Loaders
+===============
+
+[[list_of_loaders]]