Edgewall Software

Ticket #156: genshi-doctype.diff

File genshi-doctype.diff, 3.5 KB (added by athomas, 16 years ago)

Updated to work with other serialisers.

  • genshi/output.py

     
    176176                                 stripped from the output
    177177        :note: Changed in 0.4.2: The  `doctype` parameter can now be a string.
    178178        """
    179         self.preamble = []
    180         if doctype:
    181             if isinstance(doctype, basestring):
    182                 doctype = DocType.get(doctype)
    183             self.preamble.append((DOCTYPE, doctype, (None, -1, -1)))
    184179        self.filters = [EmptyTagFilter()]
    185180        if strip_whitespace:
    186181            self.filters.append(WhitespaceFilter(self._PRESERVE_SPACE))
    187182        self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes))
     183        if doctype:
     184            self.filters.append(DocTypeInserter(doctype))
    188185
    189186    def __call__(self, stream):
    190187        have_decl = have_doctype = False
    191188        in_cdata = False
    192189
    193         stream = chain(self.preamble, stream)
    194190        for filter_ in self.filters:
    195191            stream = filter_(stream)
    196192        for kind, data, pos in stream:
     
    281277        namespace_prefixes = namespace_prefixes or {}
    282278        namespace_prefixes['http://www.w3.org/1999/xhtml'] = ''
    283279        self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes))
     280        if doctype:
     281            self.filters.append(DocTypeInserter(doctype))
    284282
    285283    def __call__(self, stream):
    286284        boolean_attrs = self._BOOLEAN_ATTRS
     
    288286        have_doctype = False
    289287        in_cdata = False
    290288
    291         stream = chain(self.preamble, stream)
    292289        for filter_ in self.filters:
    293290            stream = filter_(stream)
    294291        for kind, data, pos in stream:
     
    379376        self.filters.append(NamespaceFlattener(prefixes={
    380377            'http://www.w3.org/1999/xhtml': ''
    381378        }))
     379        if doctype:
     380            self.filters.append(DocTypeInserter(doctype))
    382381
    383382    def __call__(self, stream):
    384383        boolean_attrs = self._BOOLEAN_ATTRS
     
    387386        have_doctype = False
    388387        noescape = False
    389388
    390         stream = chain(self.preamble, stream)
    391389        for filter_ in self.filters:
    392390            stream = filter_(stream)
    393391        for kind, data, pos in stream:
     
    696694
    697695                if kind:
    698696                    yield kind, data, pos
     697
     698
     699class DocTypeInserter(object):
     700    """A filter that inserts the DOCTYPE declaration in the correct location,
     701    after the XML declaration.
     702    """
     703    def __init__(self, doctype):
     704        """Initialize the filter.
     705
     706        :param doctype: DOCTYPE as a string or DocType object.
     707        """
     708        if isinstance(doctype, basestring):
     709            doctype = DocType.get(doctype)
     710        self.doctype_event = (DOCTYPE, doctype, (None, -1, -1))
     711
     712    def __call__(self, stream):
     713        buffer = []
     714        doctype_inserted = False
     715        for kind, data, pos in stream:
     716            # Buffer whitespace TEXT and XML_DECL
     717            if not doctype_inserted:
     718                if kind is XML_DECL or (kind is TEXT and not data.strip()):
     719                    buffer.append((kind, data, pos))
     720                    continue
     721
     722                for event in buffer:
     723                    yield event
     724
     725                yield self.doctype_event
     726
     727                doctype_inserted = True
     728
     729            yield (kind, data, pos)
     730
     731        if not doctype_inserted:
     732            for event in buffer:
     733                yield event
     734            yield self.doctype_event