Index: markup/template.py
===================================================================
--- markup/template.py	(revision 268)
+++ markup/template.py	(working copy)
@@ -753,7 +753,7 @@
             self.filepath = None
 
         self.filters = []
-        self.parse()
+        self.stream = self.parse()
 
     def __repr__(self):
         return '<%s "%s">' % (self.__class__.__name__, self.filename)
@@ -851,7 +851,7 @@
             else:
                 stream.append((kind, data, pos))
 
-        self.stream = stream
+        return stream
 
     _FULL_EXPR_RE = re.compile(r'(?<!\$)\$\{(.+?)\}', re.DOTALL)
     _SHORT_EXPR_RE = re.compile(r'(?<!\$)\$([a-zA-Z][a-zA-Z0-9_\.]*)')
@@ -1049,6 +1049,71 @@
                 yield kind, data, pos
 
 
+class TextTemplate(Template):
+    """
+    >>> tmpl = TextTemplate('''Dear $name,
+    ... 
+    ... We have the following items for you:
+    ... #for item in items
+    ...  * $item
+    ... #endfor
+    ... 
+    ... All the best,
+    ... Foobar
+    ... #endif''')
+    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text')
+    Dear Joe,
+    <BLANKLINE>
+    We have the following items for you:
+     * 1
+     * 2
+     * 3
+    <BLANKLINE>
+    All the best,
+    Foobar
+    <BLANKLINE>
+    """
+
+    _DIRECTIVE_RE = re.compile('^#(\w+.*)\n?', re.MULTILINE)
+
+    def parse(self):
+        stream = [] # list of events of the "compiled" template
+        dirmap = {} # temporary mapping of directives to elements
+        depth = 0
+
+        source = self.source.read()
+        for idx, part in enumerate(self._DIRECTIVE_RE.split(source)):
+
+            if idx % 2:
+                directive = part.split(None, 1)
+                if len(directive) > 1:
+                    command, value = directive
+                else:
+                    command, value = directive[0], None
+
+                if not command.startswith('end'):
+                    cls = self._dir_by_name.get(command)
+                    if cls is None:
+                        raise BadDirectiveError(command)
+                    directive = cls(value, None, -1, -1)
+                    dirmap[depth] = (directive, len(stream))
+                    depth += 1
+                else:
+                    depth -= 1
+                    command = command[3:]
+                    if depth in dirmap:
+                        directive, start_offset = dirmap.pop(depth)
+                        substream = stream[start_offset:]
+                        stream[start_offset:] = [(SUB, ([directive], substream),
+                                                  (None, -1, -1))]
+
+            else:
+                for kind, data, pos in self._interpolate(part):
+                    stream.append((kind, data, (None, -1, -1)))
+
+        return stream
+
+
 EXPR = Template.EXPR
 SUB = Template.SUB
 
