# 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]*(?