comparison genshi/output.py @ 524:7553760b58af trunk

Add special handling for `xml:lang` to HTML/XHTML serialization.
author cmlenz
date Mon, 18 Jun 2007 11:22:24 +0000
parents 942d73ba938c
children 5df08e5195b8 acf7c5ee36e7
comparison
equal deleted inserted replaced
522:082535e5087c 524:7553760b58af
277 tag, attrib = data 277 tag, attrib = data
278 buf = ['<', tag] 278 buf = ['<', tag]
279 for attr, value in attrib: 279 for attr, value in attrib:
280 if attr in boolean_attrs: 280 if attr in boolean_attrs:
281 value = attr 281 value = attr
282 elif attr == u'xml:lang' and u'lang' not in attrib:
283 buf += [' lang="', escape(value), '"']
282 buf += [' ', attr, '="', escape(value), '"'] 284 buf += [' ', attr, '="', escape(value), '"']
283 if kind is EMPTY: 285 if kind is EMPTY:
284 if tag in empty_elems: 286 if tag in empty_elems:
285 buf.append(' />') 287 buf.append(' />')
286 else: 288 else:
352 super(HTMLSerializer, self).__init__(doctype, False) 354 super(HTMLSerializer, self).__init__(doctype, False)
353 self.filters = [EmptyTagFilter()] 355 self.filters = [EmptyTagFilter()]
354 if strip_whitespace: 356 if strip_whitespace:
355 self.filters.append(WhitespaceFilter(self._PRESERVE_SPACE, 357 self.filters.append(WhitespaceFilter(self._PRESERVE_SPACE,
356 self._NOESCAPE_ELEMS)) 358 self._NOESCAPE_ELEMS))
357 self.filters.append(NamespaceStripper('http://www.w3.org/1999/xhtml')) 359 self.filters.append(NamespaceFlattener(prefixes={
360 'http://www.w3.org/1999/xhtml': ''
361 }))
358 362
359 def __call__(self, stream): 363 def __call__(self, stream):
360 boolean_attrs = self._BOOLEAN_ATTRS 364 boolean_attrs = self._BOOLEAN_ATTRS
361 empty_elems = self._EMPTY_ELEMS 365 empty_elems = self._EMPTY_ELEMS
362 noescape_elems = self._NOESCAPE_ELEMS 366 noescape_elems = self._NOESCAPE_ELEMS
373 buf = ['<', tag] 377 buf = ['<', tag]
374 for attr, value in attrib: 378 for attr, value in attrib:
375 if attr in boolean_attrs: 379 if attr in boolean_attrs:
376 if value: 380 if value:
377 buf += [' ', attr] 381 buf += [' ', attr]
378 else: 382 elif ':' in attr:
383 if attr == 'xml:lang' and u'lang' not in attrib:
384 buf += [' lang="', escape(value), '"']
385 elif attr != 'xmlns':
379 buf += [' ', attr, '="', escape(value), '"'] 386 buf += [' ', attr, '="', escape(value), '"']
380 buf.append('>') 387 buf.append('>')
381 if kind is EMPTY: 388 if kind is EMPTY:
382 if tag not in empty_elems: 389 if tag not in empty_elems:
383 buf.append('</%s>' % tag) 390 buf.append('</%s>' % tag)
582 if attr in ns_attrs: 589 if attr in ns_attrs:
583 ns_attrs.remove(attr) 590 ns_attrs.remove(attr)
584 591
585 else: 592 else:
586 yield kind, data, pos 593 yield kind, data, pos
587
588
589 class NamespaceStripper(object):
590 r"""Stream filter that removes all namespace information from a stream, and
591 optionally strips out all tags not in a given namespace.
592
593 :param namespace: the URI of the namespace that should not be stripped. If
594 not set, only elements with no namespace are included in
595 the output.
596
597 >>> from genshi.input import XML
598 >>> xml = XML('''<doc xmlns="NS1" xmlns:two="NS2">
599 ... <two:item/>
600 ... </doc>''')
601 >>> for kind, data, pos in NamespaceStripper(Namespace('NS1'))(xml):
602 ... print kind, repr(data)
603 START (u'doc', Attrs())
604 TEXT u'\n '
605 TEXT u'\n'
606 END u'doc'
607 """
608
609 def __init__(self, namespace=None):
610 if namespace is not None:
611 self.namespace = Namespace(namespace)
612 else:
613 self.namespace = {}
614
615 def __call__(self, stream):
616 namespace = self.namespace
617
618 for kind, data, pos in stream:
619
620 if kind is START or kind is EMPTY:
621 tag, attrs = data
622 if tag.namespace and tag not in namespace:
623 continue
624
625 new_attrs = []
626 for attr, value in attrs:
627 if not attr.namespace or attr in namespace:
628 new_attrs.append((attr, value))
629
630 data = tag.localname, Attrs(new_attrs)
631
632 elif kind is END:
633 if data.namespace and data not in namespace:
634 continue
635 data = data.localname
636
637 elif kind is START_NS or kind is END_NS:
638 continue
639
640 yield kind, data, pos
641 594
642 595
643 class WhitespaceFilter(object): 596 class WhitespaceFilter(object):
644 """A filter that removes extraneous ignorable white space from the 597 """A filter that removes extraneous ignorable white space from the
645 stream. 598 stream.
Copyright (C) 2012-2017 Edgewall Software