Ticket #156: genshi-doctype.diff
| File genshi-doctype.diff, 3.5 KB (added by athomas, 16 years ago) |
|---|
-
genshi/output.py
176 176 stripped from the output 177 177 :note: Changed in 0.4.2: The `doctype` parameter can now be a string. 178 178 """ 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)))184 179 self.filters = [EmptyTagFilter()] 185 180 if strip_whitespace: 186 181 self.filters.append(WhitespaceFilter(self._PRESERVE_SPACE)) 187 182 self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes)) 183 if doctype: 184 self.filters.append(DocTypeInserter(doctype)) 188 185 189 186 def __call__(self, stream): 190 187 have_decl = have_doctype = False 191 188 in_cdata = False 192 189 193 stream = chain(self.preamble, stream)194 190 for filter_ in self.filters: 195 191 stream = filter_(stream) 196 192 for kind, data, pos in stream: … … 281 277 namespace_prefixes = namespace_prefixes or {} 282 278 namespace_prefixes['http://www.w3.org/1999/xhtml'] = '' 283 279 self.filters.append(NamespaceFlattener(prefixes=namespace_prefixes)) 280 if doctype: 281 self.filters.append(DocTypeInserter(doctype)) 284 282 285 283 def __call__(self, stream): 286 284 boolean_attrs = self._BOOLEAN_ATTRS … … 288 286 have_doctype = False 289 287 in_cdata = False 290 288 291 stream = chain(self.preamble, stream)292 289 for filter_ in self.filters: 293 290 stream = filter_(stream) 294 291 for kind, data, pos in stream: … … 379 376 self.filters.append(NamespaceFlattener(prefixes={ 380 377 'http://www.w3.org/1999/xhtml': '' 381 378 })) 379 if doctype: 380 self.filters.append(DocTypeInserter(doctype)) 382 381 383 382 def __call__(self, stream): 384 383 boolean_attrs = self._BOOLEAN_ATTRS … … 387 386 have_doctype = False 388 387 noescape = False 389 388 390 stream = chain(self.preamble, stream)391 389 for filter_ in self.filters: 392 390 stream = filter_(stream) 393 391 for kind, data, pos in stream: … … 696 694 697 695 if kind: 698 696 yield kind, data, pos 697 698 699 class 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
