Mercurial > genshi > mirror
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. |