# HG changeset patch # User cmlenz # Date 1177578932 0 # Node ID e3de6dd7f9c2a26c21b5efc371339c6d6fdf9fe3 # Parent 2b21ecd769d4d59e6c1653e9d5c6410a4268d8f9 Ported [560] to 0.4.x. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,9 @@ * The `ET()` function now correctly handles attributes with a namespace. * XML declarations are now processed internally, as well as written to the output when XML serialization is used (ticket #111). + * Added the functions `encode()` and `get_serializer()` to the `genshi.output` + module, which provide a lower-level API to the functionality previously only + available through `Stream.render()` and `Stream.serialize()`. Version 0.4 diff --git a/genshi/core.py b/genshi/core.py --- a/genshi/core.py +++ b/genshi/core.py @@ -149,14 +149,9 @@ :see: XMLSerializer.__init__, XHTMLSerializer.__init__, HTMLSerializer.__init__, TextSerializer.__init__ """ + from genshi.output import encode generator = self.serialize(method=method, **kwargs) - output = u''.join(list(generator)) - if encoding is not None: - errors = 'replace' - if method != 'text': - errors = 'xmlcharrefreplace' - return output.encode(encoding, errors) - return output + return encode(generator, method=method, encoding=encoding) def select(self, path, namespaces=None, variables=None): """Return a new stream that contains the events matching the given @@ -190,14 +185,8 @@ :see: XMLSerializer.__init__, XHTMLSerializer.__init__, HTMLSerializer.__init__, TextSerializer.__init__ """ - from genshi import output - cls = method - if isinstance(method, basestring): - cls = {'xml': output.XMLSerializer, - 'xhtml': output.XHTMLSerializer, - 'html': output.HTMLSerializer, - 'text': output.TextSerializer}[method] - return cls(**kwargs)(_ensure(self)) + from genshi.output import get_serializer + return get_serializer(method, **kwargs)(_ensure(self)) def __str__(self): return self.render() diff --git a/genshi/output.py b/genshi/output.py --- a/genshi/output.py +++ b/genshi/output.py @@ -26,10 +26,49 @@ from genshi.core import START, END, TEXT, XML_DECL, DOCTYPE, START_NS, END_NS, \ START_CDATA, END_CDATA, PI, COMMENT, XML_NAMESPACE -__all__ = ['DocType', 'XMLSerializer', 'XHTMLSerializer', 'HTMLSerializer', - 'TextSerializer'] +__all__ = ['encode', 'get_serializer', 'DocType', 'XMLSerializer', + 'XHTMLSerializer', 'HTMLSerializer', 'TextSerializer'] __docformat__ = 'restructuredtext en' +def encode(iterator, method='xml', encoding='utf-8'): + """Encode serializer output into a string. + + :param iterator: the iterator returned from serializing a stream (basically + any iterator that yields unicode objects) + :param method: the serialization method; determines how characters not + representable in the specified encoding are treated + :param encoding: how the output string should be encoded; if set to `None`, + this method returns a `unicode` object + :return: a string or unicode object (depending on the `encoding` parameter) + :since: version 0.4.1 + """ + output = u''.join(list(iterator)) + if encoding is not None: + errors = 'replace' + if method != 'text' and not isinstance(method, TextSerializer): + errors = 'xmlcharrefreplace' + return output.encode(encoding, errors) + return output + +def get_serializer(method='xml', **kwargs): + """Return a serializer object for the given method. + + :param method: the serialization method; can be either "xml", "xhtml", + "html", "text", or a custom serializer class + + Any additional keyword arguments are passed to the serializer, and thus + depend on the `method` parameter value. + + :see: `XMLSerializer`, `XHTMLSerializer`, `HTMLSerializer`, `TextSerializer` + :since: version 0.4.1 + """ + if isinstance(method, basestring): + method = {'xml': XMLSerializer, + 'xhtml': XHTMLSerializer, + 'html': HTMLSerializer, + 'text': TextSerializer}[method.lower()] + return method(**kwargs) + class DocType(object): """Defines a number of commonly used DOCTYPE declarations as constants."""