<s> """<STR_LIT>""" <EOL> from itertools import chain <EOL> import re <EOL> from genshi . core import escape , Attrs , Markup , Namespace , QName , StreamEventKind <EOL> from genshi . core import START , END , TEXT , XML_DECL , DOCTYPE , START_NS , END_NS , START_CDATA , END_CDATA , PI , COMMENT , XML_NAMESPACE <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> __docformat__ = '<STR_LIT>' <EOL> def encode ( iterator , method = '<STR_LIT>' , encoding = None , out = None ) : <EOL> """<STR_LIT>""" <EOL> if encoding is not None : <EOL> errors = '<STR_LIT:replace>' <EOL> if method != '<STR_LIT:text>' and not isinstance ( method , TextSerializer ) : <EOL> errors = '<STR_LIT>' <EOL> _encode = lambda string : string . encode ( encoding , errors ) <EOL> else : <EOL> _encode = lambda string : string <EOL> if out is None : <EOL> return _encode ( '<STR_LIT>' . join ( list ( iterator ) ) ) <EOL> for chunk in iterator : <EOL> out . write ( _encode ( chunk ) ) <EOL> def get_serializer ( method = '<STR_LIT>' , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( method , basestring ) : <EOL> method = { '<STR_LIT>' : XMLSerializer , <EOL> '<STR_LIT>' : XHTMLSerializer , <EOL> '<STR_LIT:html>' : HTMLSerializer , <EOL> '<STR_LIT:text>' : TextSerializer } [ method . lower ( ) ] <EOL> return method ( ** kwargs ) <EOL> def _prepare_cache ( use_cache = True ) : <EOL> """<STR_LIT>""" <EOL> cache = { } <EOL> if use_cache : <EOL> def _emit ( kind , input , output ) : <EOL> cache [ kind , input ] = output <EOL> return output <EOL> _get = cache . get <EOL> else : <EOL> def _emit ( kind , input , output ) : <EOL> return output <EOL> def _get ( key ) : <EOL> pass <EOL> return _emit , _get , cache <EOL> class DocType ( object ) : <EOL> """<STR_LIT>""" <EOL> HTML_STRICT = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> HTML_TRANSITIONAL = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> HTML_FRAMESET = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> HTML = HTML_STRICT <EOL> HTML5 = ( '<STR_LIT:html>' , None , None ) <EOL> XHTML_STRICT = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> XHTML_TRANSITIONAL = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> XHTML_FRAMESET = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> XHTML = XHTML_STRICT <EOL> XHTML11 = ( <EOL> '<STR_LIT:html>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> SVG_FULL = ( <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> SVG_BASIC = ( <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> SVG_TINY = ( <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> SVG = SVG_FULL <EOL> @ classmethod <EOL> def get ( cls , name ) : <EOL> """<STR_LIT>""" <EOL> return { <EOL> '<STR_LIT:html>' : cls . HTML , '<STR_LIT>' : cls . HTML_STRICT , <EOL> '<STR_LIT>' : DocType . HTML_TRANSITIONAL , <EOL> '<STR_LIT>' : DocType . HTML_FRAMESET , <EOL> '<STR_LIT>' : cls . HTML5 , <EOL> '<STR_LIT>' : cls . XHTML , '<STR_LIT>' : cls . XHTML_STRICT , <EOL> '<STR_LIT>' : cls . XHTML_TRANSITIONAL , <EOL> '<STR_LIT>' : cls . XHTML_FRAMESET , <EOL> '<STR_LIT>' : cls . XHTML11 , <EOL> '<STR_LIT>' : cls . SVG , '<STR_LIT>' : cls . SVG_FULL , <EOL> '<STR_LIT>' : cls . SVG_BASIC , <EOL> '<STR_LIT>' : cls . SVG_TINY <EOL> } . get ( name . lower ( ) ) <EOL> class XMLSerializer ( object ) : <EOL> """<STR_LIT>""" <EOL> _PRESERVE_SPACE = frozenset ( ) <EOL> def __init__ ( self , doctype = None , strip_whitespace = True , <EOL> namespace_prefixes = None , cache = True ) : <EOL> """<STR_LIT>""" <EOL> self . filters = [ EmptyTagFilter ( ) ] <EOL> if strip_whitespace : <EOL> self . filters . append ( WhitespaceFilter ( self . _PRESERVE_SPACE ) ) <EOL> self . filters . append ( NamespaceFlattener ( prefixes = namespace_prefixes , <EOL> cache = cache ) ) <EOL> if doctype : <EOL> self . filters . append ( DocTypeInserter ( doctype ) ) <EOL> self . cache = cache <EOL> def _prepare_cache ( self ) : <EOL> return _prepare_cache ( self . cache ) [ : <NUM_LIT:2> ] <EOL> def __call__ ( self , stream ) : <EOL> have_decl = have_doctype = False <EOL> in_cdata = False <EOL> _emit , _get = self . _prepare_cache ( ) <EOL> for filter_ in self . filters : <EOL> stream = filter_ ( stream ) <EOL> for kind , data , pos in stream : <EOL> if kind is TEXT and isinstance ( data , Markup ) : <EOL> yield data <EOL> continue <EOL> cached = _get ( ( kind , data ) ) <EOL> if cached is not None : <EOL> yield cached <EOL> elif kind is START or kind is EMPTY : <EOL> tag , attrib = data <EOL> buf = [ '<STR_LIT:<>' , tag ] <EOL> for attr , value in attrib : <EOL> buf += [ '<STR_LIT:U+0020>' , attr , '<STR_LIT>' , escape ( value ) , '<STR_LIT:">' ] <EOL> buf . append ( kind is EMPTY and '<STR_LIT>' or '<STR_LIT:>>' ) <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' . join ( buf ) ) ) <EOL> elif kind is END : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> elif kind is TEXT : <EOL> if in_cdata : <EOL> yield _emit ( kind , data , data ) <EOL> else : <EOL> yield _emit ( kind , data , escape ( data , quotes = False ) ) <EOL> elif kind is COMMENT : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> elif kind is XML_DECL and not have_decl : <EOL> version , encoding , standalone = data <EOL> buf = [ '<STR_LIT>' % version ] <EOL> if encoding : <EOL> buf . append ( '<STR_LIT>' % encoding ) <EOL> if standalone != - <NUM_LIT:1> : <EOL> standalone = standalone and '<STR_LIT:yes>' or '<STR_LIT>' <EOL> buf . append ( '<STR_LIT>' % standalone ) <EOL> buf . append ( '<STR_LIT>' ) <EOL> yield Markup ( '<STR_LIT>' . join ( buf ) ) <EOL> have_decl = True <EOL> elif kind is DOCTYPE and not have_doctype : <EOL> name , pubid , sysid = data <EOL> buf = [ '<STR_LIT>' ] <EOL> if pubid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> elif sysid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> if sysid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> buf . append ( '<STR_LIT>' ) <EOL> yield Markup ( '<STR_LIT>' . join ( buf ) ) % tuple ( [ p for p in data if p ] ) <EOL> have_doctype = True <EOL> elif kind is START_CDATA : <EOL> yield Markup ( '<STR_LIT>' ) <EOL> in_cdata = True <EOL> elif kind is END_CDATA : <EOL> yield Markup ( '<STR_LIT>' ) <EOL> in_cdata = False <EOL> elif kind is PI : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> class XHTMLSerializer ( XMLSerializer ) : <EOL> """<STR_LIT>""" <EOL> _EMPTY_ELEMS = frozenset ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:input>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) <EOL> _BOOLEAN_ATTRS = frozenset ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> _PRESERVE_SPACE = frozenset ( [ <EOL> QName ( '<STR_LIT>' ) , QName ( '<STR_LIT>' ) , <EOL> QName ( '<STR_LIT>' ) , QName ( '<STR_LIT>' ) <EOL> ] ) <EOL> def __init__ ( self , doctype = None , strip_whitespace = True , <EOL> namespace_prefixes = None , drop_xml_decl = True , cache = True ) : <EOL> super ( XHTMLSerializer , self ) . __init__ ( doctype , False ) <EOL> self . filters = [ EmptyTagFilter ( ) ] <EOL> if strip_whitespace : <EOL> self . filters . append ( WhitespaceFilter ( self . _PRESERVE_SPACE ) ) <EOL> namespace_prefixes = namespace_prefixes or { } <EOL> namespace_prefixes [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> self . filters . append ( NamespaceFlattener ( prefixes = namespace_prefixes , <EOL> cache = cache ) ) <EOL> if doctype : <EOL> self . filters . append ( DocTypeInserter ( doctype ) ) <EOL> self . drop_xml_decl = drop_xml_decl <EOL> self . cache = cache <EOL> def __call__ ( self , stream ) : <EOL> boolean_attrs = self . _BOOLEAN_ATTRS <EOL> empty_elems = self . _EMPTY_ELEMS <EOL> drop_xml_decl = self . drop_xml_decl <EOL> have_decl = have_doctype = False <EOL> in_cdata = False <EOL> _emit , _get = self . _prepare_cache ( ) <EOL> for filter_ in self . filters : <EOL> stream = filter_ ( stream ) <EOL> for kind , data , pos in stream : <EOL> if kind is TEXT and isinstance ( data , Markup ) : <EOL> yield data <EOL> continue <EOL> cached = _get ( ( kind , data ) ) <EOL> if cached is not None : <EOL> yield cached <EOL> elif kind is START or kind is EMPTY : <EOL> tag , attrib = data <EOL> buf = [ '<STR_LIT:<>' , tag ] <EOL> for attr , value in attrib : <EOL> if attr in boolean_attrs : <EOL> value = attr <EOL> elif attr == '<STR_LIT>' and '<STR_LIT>' not in attrib : <EOL> buf += [ '<STR_LIT>' , escape ( value ) , '<STR_LIT:">' ] <EOL> elif attr == '<STR_LIT>' : <EOL> continue <EOL> buf += [ '<STR_LIT:U+0020>' , attr , '<STR_LIT>' , escape ( value ) , '<STR_LIT:">' ] <EOL> if kind is EMPTY : <EOL> if tag in empty_elems : <EOL> buf . append ( '<STR_LIT>' ) <EOL> else : <EOL> buf . append ( '<STR_LIT>' % tag ) <EOL> else : <EOL> buf . append ( '<STR_LIT:>>' ) <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' . join ( buf ) ) ) <EOL> elif kind is END : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> elif kind is TEXT : <EOL> if in_cdata : <EOL> yield _emit ( kind , data , data ) <EOL> else : <EOL> yield _emit ( kind , data , escape ( data , quotes = False ) ) <EOL> elif kind is COMMENT : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> elif kind is DOCTYPE and not have_doctype : <EOL> name , pubid , sysid = data <EOL> buf = [ '<STR_LIT>' ] <EOL> if pubid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> elif sysid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> if sysid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> buf . append ( '<STR_LIT>' ) <EOL> yield Markup ( '<STR_LIT>' . join ( buf ) ) % tuple ( [ p for p in data if p ] ) <EOL> have_doctype = True <EOL> elif kind is XML_DECL and not have_decl and not drop_xml_decl : <EOL> version , encoding , standalone = data <EOL> buf = [ '<STR_LIT>' % version ] <EOL> if encoding : <EOL> buf . append ( '<STR_LIT>' % encoding ) <EOL> if standalone != - <NUM_LIT:1> : <EOL> standalone = standalone and '<STR_LIT:yes>' or '<STR_LIT>' <EOL> buf . append ( '<STR_LIT>' % standalone ) <EOL> buf . append ( '<STR_LIT>' ) <EOL> yield Markup ( '<STR_LIT>' . join ( buf ) ) <EOL> have_decl = True <EOL> elif kind is START_CDATA : <EOL> yield Markup ( '<STR_LIT>' ) <EOL> in_cdata = True <EOL> elif kind is END_CDATA : <EOL> yield Markup ( '<STR_LIT>' ) <EOL> in_cdata = False <EOL> elif kind is PI : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> class HTMLSerializer ( XHTMLSerializer ) : <EOL> """<STR_LIT>""" <EOL> _NOESCAPE_ELEMS = frozenset ( [ <EOL> QName ( '<STR_LIT>' ) , QName ( '<STR_LIT>' ) , <EOL> QName ( '<STR_LIT>' ) , QName ( '<STR_LIT>' ) <EOL> ] ) <EOL> def __init__ ( self , doctype = None , strip_whitespace = True , cache = True ) : <EOL> """<STR_LIT>""" <EOL> super ( HTMLSerializer , self ) . __init__ ( doctype , False ) <EOL> self . filters = [ EmptyTagFilter ( ) ] <EOL> if strip_whitespace : <EOL> self . filters . append ( WhitespaceFilter ( self . _PRESERVE_SPACE , <EOL> self . _NOESCAPE_ELEMS ) ) <EOL> self . filters . append ( NamespaceFlattener ( prefixes = { <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } , cache = cache ) ) <EOL> if doctype : <EOL> self . filters . append ( DocTypeInserter ( doctype ) ) <EOL> self . cache = True <EOL> def __call__ ( self , stream ) : <EOL> boolean_attrs = self . _BOOLEAN_ATTRS <EOL> empty_elems = self . _EMPTY_ELEMS <EOL> noescape_elems = self . _NOESCAPE_ELEMS <EOL> have_doctype = False <EOL> noescape = False <EOL> _emit , _get = self . _prepare_cache ( ) <EOL> for filter_ in self . filters : <EOL> stream = filter_ ( stream ) <EOL> for kind , data , _ in stream : <EOL> if kind is TEXT and isinstance ( data , Markup ) : <EOL> yield data <EOL> continue <EOL> output = _get ( ( kind , data ) ) <EOL> if output is not None : <EOL> yield output <EOL> if ( kind is START or kind is EMPTY ) and data [ <NUM_LIT:0> ] in noescape_elems : <EOL> noescape = True <EOL> elif kind is END : <EOL> noescape = False <EOL> elif kind is START or kind is EMPTY : <EOL> tag , attrib = data <EOL> buf = [ '<STR_LIT:<>' , tag ] <EOL> for attr , value in attrib : <EOL> if attr in boolean_attrs : <EOL> if value : <EOL> buf += [ '<STR_LIT:U+0020>' , attr ] <EOL> elif '<STR_LIT::>' in attr : <EOL> if attr == '<STR_LIT>' and '<STR_LIT>' not in attrib : <EOL> buf += [ '<STR_LIT>' , escape ( value ) , '<STR_LIT:">' ] <EOL> elif attr != '<STR_LIT>' : <EOL> buf += [ '<STR_LIT:U+0020>' , attr , '<STR_LIT>' , escape ( value ) , '<STR_LIT:">' ] <EOL> buf . append ( '<STR_LIT:>>' ) <EOL> if kind is EMPTY : <EOL> if tag not in empty_elems : <EOL> buf . append ( '<STR_LIT>' % tag ) <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' . join ( buf ) ) ) <EOL> if tag in noescape_elems : <EOL> noescape = True <EOL> elif kind is END : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> noescape = False <EOL> elif kind is TEXT : <EOL> if noescape : <EOL> yield _emit ( kind , data , data ) <EOL> else : <EOL> yield _emit ( kind , data , escape ( data , quotes = False ) ) <EOL> elif kind is COMMENT : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> elif kind is DOCTYPE and not have_doctype : <EOL> name , pubid , sysid = data <EOL> buf = [ '<STR_LIT>' ] <EOL> if pubid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> elif sysid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> if sysid : <EOL> buf . append ( '<STR_LIT>' ) <EOL> buf . append ( '<STR_LIT>' ) <EOL> yield Markup ( '<STR_LIT>' . join ( buf ) ) % tuple ( [ p for p in data if p ] ) <EOL> have_doctype = True <EOL> elif kind is PI : <EOL> yield _emit ( kind , data , Markup ( '<STR_LIT>' % data ) ) <EOL> class TextSerializer ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , strip_markup = False ) : <EOL> """<STR_LIT>""" <EOL> self . strip_markup = strip_markup <EOL> def __call__ ( self , stream ) : <EOL> strip_markup = self . strip_markup <EOL> for event in stream : <EOL> if event [ <NUM_LIT:0> ] is TEXT : <EOL> data = event [ <NUM_LIT:1> ] <EOL> if strip_markup and type ( data ) is Markup : <EOL> data = data . striptags ( ) . stripentities ( ) <EOL> yield unicode ( data ) <EOL> class EmptyTagFilter ( object ) : <EOL> """<STR_LIT>""" <EOL> EMPTY = StreamEventKind ( '<STR_LIT>' ) <EOL> def __call__ ( self , stream ) : <EOL> prev = ( None , None , None ) <EOL> for ev in stream : <EOL> if prev [ <NUM_LIT:0> ] is START : <EOL> if ev [ <NUM_LIT:0> ] is END : <EOL> prev = EMPTY , prev [ <NUM_LIT:1> ] , prev [ <NUM_LIT:2> ] <EOL> yield prev <EOL> continue <EOL> else : <EOL> yield prev <EOL> if ev [ <NUM_LIT:0> ] is not START : <EOL> yield ev <EOL> prev = ev <EOL> EMPTY = EmptyTagFilter . EMPTY <EOL> class NamespaceFlattener ( object ) : <EOL> r"""<STR_LIT>""" <EOL> def __init__ ( self , prefixes = None , cache = True ) : <EOL> self . prefixes = { XML_NAMESPACE . uri : '<STR_LIT>' } <EOL> if prefixes is not None : <EOL> self . prefixes . update ( prefixes ) <EOL> self . cache = cache <EOL> def __call__ ( self , stream ) : <EOL> prefixes = dict ( [ ( v , [ k ] ) for k , v in self . prefixes . items ( ) ] ) <EOL> namespaces = { XML_NAMESPACE . uri : [ '<STR_LIT>' ] } <EOL> _emit , _get , cache = _prepare_cache ( self . cache ) <EOL> def _push_ns ( prefix , uri ) : <EOL> namespaces . setdefault ( uri , [ ] ) . append ( prefix ) <EOL> prefixes . setdefault ( prefix , [ ] ) . append ( uri ) <EOL> cache . clear ( ) <EOL> def _pop_ns ( prefix ) : <EOL> uris = prefixes . get ( prefix ) <EOL> uri = uris . pop ( ) <EOL> if not uris : <EOL> del prefixes [ prefix ] <EOL> if uri not in uris or uri != uris [ - <NUM_LIT:1> ] : <EOL> uri_prefixes = namespaces [ uri ] <EOL> uri_prefixes . pop ( ) <EOL> if not uri_prefixes : <EOL> del namespaces [ uri ] <EOL> cache . clear ( ) <EOL> return uri <EOL> ns_attrs = [ ] <EOL> _push_ns_attr = ns_attrs . append <EOL> def _make_ns_attr ( prefix , uri ) : <EOL> return '<STR_LIT>' % ( prefix and '<STR_LIT>' % prefix or '<STR_LIT>' ) , uri <EOL> def _gen_prefix ( ) : <EOL> val = <NUM_LIT:0> <EOL> while <NUM_LIT:1> : <EOL> val += <NUM_LIT:1> <EOL> yield '<STR_LIT>' % val <EOL> _gen_prefix = _gen_prefix ( ) . next <EOL> for kind , data , pos in stream : <EOL> if kind is TEXT and isinstance ( data , Markup ) : <EOL> yield kind , data , pos <EOL> continue <EOL> output = _get ( ( kind , data ) ) <EOL> if output is not None : <EOL> yield kind , output , pos <EOL> elif kind is START or kind is EMPTY : <EOL> tag , attrs = data <EOL> tagname = tag . localname <EOL> tagns = tag . namespace <EOL> if tagns : <EOL> if tagns in namespaces : <EOL> prefix = namespaces [ tagns ] [ - <NUM_LIT:1> ] <EOL> if prefix : <EOL> tagname = '<STR_LIT>' % ( prefix , tagname ) <EOL> else : <EOL> _push_ns_attr ( ( '<STR_LIT>' , tagns ) ) <EOL> _push_ns ( '<STR_LIT>' , tagns ) <EOL> new_attrs = [ ] <EOL> for attr , value in attrs : <EOL> attrname = attr . localname <EOL> attrns = attr . namespace <EOL> if attrns : <EOL> if attrns not in namespaces : <EOL> prefix = _gen_prefix ( ) <EOL> _push_ns ( prefix , attrns ) <EOL> _push_ns_attr ( ( '<STR_LIT>' % prefix , attrns ) ) <EOL> else : <EOL> prefix = namespaces [ attrns ] [ - <NUM_LIT:1> ] <EOL> if prefix : <EOL> attrname = '<STR_LIT>' % ( prefix , attrname ) <EOL> new_attrs . append ( ( attrname , value ) ) <EOL> data = _emit ( kind , data , ( tagname , Attrs ( ns_attrs + new_attrs ) ) ) <EOL> yield kind , data , pos <EOL> del ns_attrs [ : ] <EOL> elif kind is END : <EOL> tagname = data . localname <EOL> tagns = data . namespace <EOL> if tagns : <EOL> prefix = namespaces [ tagns ] [ - <NUM_LIT:1> ] <EOL> if prefix : <EOL> tagname = '<STR_LIT>' % ( prefix , tagname ) <EOL> yield kind , _emit ( kind , data , tagname ) , pos <EOL> elif kind is START_NS : <EOL> prefix , uri = data <EOL> if uri not in namespaces : <EOL> prefix = prefixes . get ( uri , [ prefix ] ) [ - <NUM_LIT:1> ] <EOL> _push_ns_attr ( _make_ns_attr ( prefix , uri ) ) <EOL> _push_ns ( prefix , uri ) <EOL> elif kind is END_NS : <EOL> if data in prefixes : <EOL> uri = _pop_ns ( data ) <EOL> if ns_attrs : <EOL> attr = _make_ns_attr ( data , uri ) <EOL> if attr in ns_attrs : <EOL> ns_attrs . remove ( attr ) <EOL> else : <EOL> yield kind , data , pos <EOL> class WhitespaceFilter ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , preserve = None , noescape = None ) : <EOL> """<STR_LIT>""" <EOL> if preserve is None : <EOL> preserve = [ ] <EOL> self . preserve = frozenset ( preserve ) <EOL> if noescape is None : <EOL> noescape = [ ] <EOL> self . noescape = frozenset ( noescape ) <EOL> def __call__ ( self , stream , ctxt = None , space = XML_NAMESPACE [ '<STR_LIT>' ] , <EOL> trim_trailing_space = re . compile ( '<STR_LIT>' ) . sub , <EOL> collapse_lines = re . compile ( '<STR_LIT>' ) . sub ) : <EOL> mjoin = Markup ( '<STR_LIT>' ) . join <EOL> preserve_elems = self . preserve <EOL> preserve = <NUM_LIT:0> <EOL> noescape_elems = self . noescape <EOL> noescape = False <EOL> textbuf = [ ] <EOL> push_text = textbuf . append <EOL> pop_text = textbuf . pop <EOL> for kind , data , pos in chain ( stream , [ ( None , None , None ) ] ) : <EOL> if kind is TEXT : <EOL> if noescape : <EOL> data = Markup ( data ) <EOL> push_text ( data ) <EOL> else : <EOL> if textbuf : <EOL> if len ( textbuf ) > <NUM_LIT:1> : <EOL> text = mjoin ( textbuf , escape_quotes = False ) <EOL> del textbuf [ : ] <EOL> else : <EOL> text = escape ( pop_text ( ) , quotes = False ) <EOL> if not preserve : <EOL> text = collapse_lines ( '<STR_LIT:\n>' , trim_trailing_space ( '<STR_LIT>' , text ) ) <EOL> yield TEXT , Markup ( text ) , pos <EOL> if kind is START : <EOL> tag , attrs = data <EOL> if preserve or ( tag in preserve_elems or <EOL> attrs . get ( space ) == '<STR_LIT>' ) : <EOL> preserve += <NUM_LIT:1> <EOL> if not noescape and tag in noescape_elems : <EOL> noescape = True <EOL> elif kind is END : <EOL> noescape = False <EOL> if preserve : <EOL> preserve -= <NUM_LIT:1> <EOL> elif kind is START_CDATA : <EOL> noescape = True <EOL> elif kind is END_CDATA : <EOL> noescape = False <EOL> if kind : <EOL> yield kind , data , pos <EOL> class DocTypeInserter ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , doctype ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( doctype , basestring ) : <EOL> doctype = DocType . get ( doctype ) <EOL> self . doctype_event = ( DOCTYPE , doctype , ( None , - <NUM_LIT:1> , - <NUM_LIT:1> ) ) <EOL> def __call__ ( self , stream ) : <EOL> doctype_inserted = False <EOL> for kind , data , pos in stream : <EOL> if not doctype_inserted : <EOL> doctype_inserted = True <EOL> if kind is XML_DECL : <EOL> yield ( kind , data , pos ) <EOL> yield self . doctype_event <EOL> continue <EOL> yield self . doctype_event <EOL> yield ( kind , data , pos ) <EOL> if not doctype_inserted : <EOL> yield self . doctype_event </s>
