# HG changeset patch
# User cmlenz
# Date 1164279134 0
# Node ID b146277eb54a8c3f63338508050dc698e164fa8f
# Parent 37e45862f814bb8a3ba7214ff2c4901a80e7ee65
`MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -27,6 +27,8 @@
are callable.
* Instances of the `genshi.core.Attrs` class are now immutable (they are
subclasses of `tuple` instead of `list`).
+ * `MarkupTemplate`s can now be instantiated from markup streams, in addition
+ to strings and file-like objects (ticket #69).
Version 0.3.5
diff --git a/genshi/template/core.py b/genshi/template/core.py
--- a/genshi/template/core.py
+++ b/genshi/template/core.py
@@ -170,10 +170,6 @@
def __init__(self, source, basedir=None, filename=None, loader=None,
encoding=None):
"""Initialize a template from either a string or a file-like object."""
- if isinstance(source, basestring):
- self.source = StringIO(source)
- else:
- self.source = source
self.basedir = basedir
self.filename = filename
if basedir and filename:
@@ -182,13 +178,17 @@
self.filepath = filename
self.loader = loader
+ if isinstance(source, basestring):
+ source = StringIO(source)
+ else:
+ source = source
+ self.stream = list(self._prepare(self._parse(source, encoding)))
self.filters = [self._flatten, self._eval]
- self.stream = list(self._prepare(self._parse(encoding)))
def __repr__(self):
return '<%s "%s">' % (self.__class__.__name__, self.filename)
- def _parse(self, encoding):
+ def _parse(self, source, encoding):
"""Parse the template.
The parsing stage parses the template and constructs a list of
diff --git a/genshi/template/markup.py b/genshi/template/markup.py
--- a/genshi/template/markup.py
+++ b/genshi/template/markup.py
@@ -63,7 +63,7 @@
if loader:
self.filters.append(self._include)
- def _parse(self, encoding):
+ def _parse(self, source, encoding):
"""Parse the template from an XML document."""
stream = [] # list of events of the "compiled" template
dirmap = {} # temporary mapping of directives to elements
@@ -73,8 +73,11 @@
fallback_stream = None
include_href = None
- for kind, data, pos in XMLParser(self.source, filename=self.filename,
- encoding=encoding):
+ if not isinstance(source, Stream):
+ source = XMLParser(source, filename=self.filename,
+ encoding=encoding)
+
+ for kind, data, pos in source:
if kind is START_NS:
# Strip out the namespace declaration for template directives
diff --git a/genshi/template/tests/markup.py b/genshi/template/tests/markup.py
--- a/genshi/template/tests/markup.py
+++ b/genshi/template/tests/markup.py
@@ -14,11 +14,13 @@
import doctest
import os
import shutil
+from StringIO import StringIO
import sys
import tempfile
import unittest
from genshi.core import Markup
+from genshi.input import XML
from genshi.template.core import BadDirectiveError, TemplateSyntaxError
from genshi.template.loader import TemplateLoader
from genshi.template.markup import MarkupTemplate
@@ -27,6 +29,16 @@
class MarkupTemplateTestCase(unittest.TestCase):
"""Tests for markup template processing."""
+ def test_parse_fileobj(self):
+ fileobj = StringIO(' ${var} $var')
+ tmpl = MarkupTemplate(fileobj)
+ self.assertEqual(' 42 42', str(tmpl.generate(var=42)))
+
+ def test_parse_stream(self):
+ stream = XML(' ${var} $var')
+ tmpl = MarkupTemplate(stream)
+ self.assertEqual(' 42 42', str(tmpl.generate(var=42)))
+
def test_interpolate_mixed3(self):
tmpl = MarkupTemplate(' ${var} $var')
self.assertEqual(' 42 42', str(tmpl.generate(var=42)))
diff --git a/genshi/template/text.py b/genshi/template/text.py
--- a/genshi/template/text.py
+++ b/genshi/template/text.py
@@ -54,7 +54,7 @@
r'(?:^[ \t]*(?