Mercurial > genshi > mirror
changeset 461:af0122a5aa4b stable-0.4.x
Port [558] to 0.4.x.
author | cmlenz |
---|---|
date | Wed, 25 Apr 2007 19:42:12 +0000 |
parents | 9101eb8a68b6 |
children | 55d6a5a5e972 |
files | ChangeLog genshi/core.py genshi/input.py genshi/output.py genshi/template/tests/markup.py genshi/tests/input.py |
diffstat | 6 files changed, 53 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ * Fix incorrect reference to translation function in the I18N filter. * 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). Version 0.4
--- a/genshi/core.py +++ b/genshi/core.py @@ -56,6 +56,7 @@ START = StreamEventKind('START') #: a start tag END = StreamEventKind('END') #: an end tag TEXT = StreamEventKind('TEXT') #: literal text + XML_DECL = StreamEventKind('XML_DECL') #: XML declaration DOCTYPE = StreamEventKind('DOCTYPE') #: doctype declaration START_NS = StreamEventKind('START_NS') #: start namespace mapping END_NS = StreamEventKind('END_NS') #: end namespace mapping @@ -208,6 +209,7 @@ START = Stream.START END = Stream.END TEXT = Stream.TEXT +XML_DECL = Stream.XML_DECL DOCTYPE = Stream.DOCTYPE START_NS = Stream.START_NS END_NS = Stream.END_NS
--- a/genshi/input.py +++ b/genshi/input.py @@ -26,7 +26,7 @@ from StringIO import StringIO from genshi.core import Attrs, QName, Stream, stripentities -from genshi.core import DOCTYPE, START, END, START_NS, END_NS, TEXT, \ +from genshi.core import START, END, XML_DECL, DOCTYPE, TEXT, START_NS, END_NS, \ START_CDATA, END_CDATA, PI, COMMENT __all__ = ['ET', 'ParseError', 'XMLParser', 'XML', 'HTMLParser', 'HTML'] @@ -123,6 +123,7 @@ parser.StartCdataSectionHandler = self._handle_start_cdata parser.EndCdataSectionHandler = self._handle_end_cdata parser.ProcessingInstructionHandler = self._handle_pi + parser.XmlDeclHandler = self._handle_xml_decl parser.CommentHandler = self._handle_comment # Tell Expat that we'll handle non-XML entities ourselves @@ -216,6 +217,9 @@ def _handle_data(self, text): self._enqueue(TEXT, text) + def _handle_xml_decl(self, version, encoding, standalone): + self._enqueue(XML_DECL, (version, encoding, standalone)) + def _handle_doctype(self, name, sysid, pubid, has_internal_subset): self._enqueue(DOCTYPE, (name, pubid, sysid))
--- a/genshi/output.py +++ b/genshi/output.py @@ -23,7 +23,7 @@ import re from genshi.core import escape, Attrs, Markup, Namespace, QName, StreamEventKind -from genshi.core import DOCTYPE, START, END, START_NS, END_NS, TEXT, \ +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', @@ -87,7 +87,7 @@ self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes)) def __call__(self, stream): - have_doctype = False + have_decl = have_doctype = False in_cdata = False stream = chain(self.preamble, stream) @@ -115,6 +115,18 @@ elif kind is COMMENT: yield Markup('<!--%s-->' % data) + elif kind is XML_DECL and not have_decl: + version, encoding, standalone = data + buf = ['<?xml version="%s"' % version] + if encoding: + buf.append(' encoding="%s"' % encoding) + if standalone != -1: + standalone = standalone and 'yes' or 'no' + buf.append(' standalone="%s"' % standalone) + buf.append('?>\n') + yield Markup(u''.join(buf)) + have_decl = True + elif kind is DOCTYPE and not have_doctype: name, pubid, sysid = data buf = ['<!DOCTYPE %s']
--- a/genshi/template/tests/markup.py +++ b/genshi/template/tests/markup.py @@ -183,7 +183,7 @@ <div xmlns:py="http://genshi.edgewall.org/"> \xf6 </div>""".encode('iso-8859-1'), encoding='iso-8859-1') - self.assertEqual(u"""<div> + self.assertEqual(u"""<?xml version="1.0" encoding="iso-8859-1"?>\n<div> \xf6 </div>""", unicode(tmpl.generate())) @@ -228,7 +228,7 @@ <Size py:if="0" xmlns:t="test">Size</Size> <Item/> </Test>""") - self.assertEqual("""<Test> + self.assertEqual("""<?xml version="1.0"?>\n<Test> <Item/> </Test>""", str(tmpl.generate()))
--- a/genshi/tests/input.py +++ b/genshi/tests/input.py @@ -71,7 +71,7 @@ <div>\xf6</div> """.encode('iso-8859-1') events = list(XMLParser(StringIO(text))) - kind, data, pos = events[1] + kind, data, pos = events[2] self.assertEqual(Stream.TEXT, kind) self.assertEqual(u'\xf6', data) @@ -181,6 +181,33 @@ self.assertEqual(u'php', target) self.assertEqual(u'echo "Foobar"', data) + def test_xmldecl(self): + text = '<?xml version="1.0" ?><root />' + events = list(XMLParser(StringIO(text))) + kind, (version, encoding, standalone), pos = events[0] + self.assertEqual(Stream.XML_DECL, kind) + self.assertEqual(u'1.0', version) + self.assertEqual(None, encoding) + self.assertEqual(-1, standalone) + + def test_xmldecl_encoding(self): + text = '<?xml version="1.0" encoding="utf-8" ?><root />' + events = list(XMLParser(StringIO(text))) + kind, (version, encoding, standalone), pos = events[0] + self.assertEqual(Stream.XML_DECL, kind) + self.assertEqual(u'1.0', version) + self.assertEqual(u'utf-8', encoding) + self.assertEqual(-1, standalone) + + def test_xmldecl_standalone(self): + text = '<?xml version="1.0" standalone="yes" ?><root />' + events = list(XMLParser(StringIO(text))) + kind, (version, encoding, standalone), pos = events[0] + self.assertEqual(Stream.XML_DECL, kind) + self.assertEqual(u'1.0', version) + self.assertEqual(None, encoding) + self.assertEqual(1, standalone) + def test_processing_instruction_trailing_qmark(self): text = '<?php echo "Foobar" ??>' events = list(HTMLParser(StringIO(text)))