<s> """<STR_LIT>""" <EOL> from itertools import chain <EOL> from genshi . core import Attrs , Markup , Namespace , Stream , StreamEventKind <EOL> from genshi . core import START , END , START_NS , END_NS , TEXT , PI , COMMENT <EOL> from genshi . input import XMLParser <EOL> from genshi . template . base import BadDirectiveError , Template , TemplateSyntaxError , _apply_directives , EXEC , INCLUDE , SUB <EOL> from genshi . template . eval import Suite <EOL> from genshi . template . interpolation import interpolate <EOL> from genshi . template . directives import * <EOL> from genshi . template . text import NewTextTemplate <EOL> __all__ = [ '<STR_LIT>' ] <EOL> __docformat__ = '<STR_LIT>' <EOL> class MarkupTemplate ( Template ) : <EOL> """<STR_LIT>""" <EOL> DIRECTIVE_NAMESPACE = '<STR_LIT>' <EOL> XINCLUDE_NAMESPACE = '<STR_LIT>' <EOL> directives = [ ( '<STR_LIT>' , DefDirective ) , <EOL> ( '<STR_LIT>' , MatchDirective ) , <EOL> ( '<STR_LIT>' , WhenDirective ) , <EOL> ( '<STR_LIT>' , OtherwiseDirective ) , <EOL> ( '<STR_LIT>' , ForDirective ) , <EOL> ( '<STR_LIT>' , IfDirective ) , <EOL> ( '<STR_LIT>' , ChooseDirective ) , <EOL> ( '<STR_LIT>' , WithDirective ) , <EOL> ( '<STR_LIT:replace>' , ReplaceDirective ) , <EOL> ( '<STR_LIT:content>' , ContentDirective ) , <EOL> ( '<STR_LIT>' , AttrsDirective ) , <EOL> ( '<STR_LIT>' , StripDirective ) ] <EOL> serializer = '<STR_LIT>' <EOL> _number_conv = Markup <EOL> def __init__ ( self , source , filepath = None , filename = None , loader = None , <EOL> encoding = None , lookup = '<STR_LIT:strict>' , allow_exec = True ) : <EOL> Template . __init__ ( self , source , filepath = filepath , filename = filename , <EOL> loader = loader , encoding = encoding , lookup = lookup , <EOL> allow_exec = allow_exec ) <EOL> self . add_directives ( self . DIRECTIVE_NAMESPACE , self ) <EOL> def _init_filters ( self ) : <EOL> Template . _init_filters ( self ) <EOL> if self . loader : <EOL> self . filters . remove ( self . _include ) <EOL> self . filters += [ self . _match ] <EOL> if self . loader : <EOL> self . filters . append ( self . _include ) <EOL> def _parse ( self , source , encoding ) : <EOL> if not isinstance ( source , Stream ) : <EOL> source = XMLParser ( source , filename = self . filename , <EOL> encoding = encoding ) <EOL> stream = [ ] <EOL> for kind , data , pos in source : <EOL> if kind is TEXT : <EOL> for kind , data , pos in interpolate ( data , self . filepath , pos [ <NUM_LIT:1> ] , <EOL> pos [ <NUM_LIT:2> ] , lookup = self . lookup ) : <EOL> stream . append ( ( kind , data , pos ) ) <EOL> elif kind is PI and data [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> if not self . allow_exec : <EOL> raise TemplateSyntaxError ( '<STR_LIT>' , <EOL> self . filepath , * pos [ <NUM_LIT:1> : ] ) <EOL> try : <EOL> suite = Suite ( data [ <NUM_LIT:1> ] , self . filepath , pos [ <NUM_LIT:1> ] , <EOL> lookup = self . lookup ) <EOL> except SyntaxError , err : <EOL> raise TemplateSyntaxError ( err , self . filepath , <EOL> pos [ <NUM_LIT:1> ] + ( err . lineno or <NUM_LIT:1> ) - <NUM_LIT:1> , <EOL> pos [ <NUM_LIT:2> ] + ( err . offset or <NUM_LIT:0> ) ) <EOL> stream . append ( ( EXEC , suite , pos ) ) <EOL> elif kind is COMMENT : <EOL> if not data . lstrip ( ) . startswith ( '<STR_LIT:!>' ) : <EOL> stream . append ( ( kind , data , pos ) ) <EOL> else : <EOL> stream . append ( ( kind , data , pos ) ) <EOL> return stream <EOL> def _extract_directives ( self , stream , namespace , factory ) : <EOL> depth = <NUM_LIT:0> <EOL> dirmap = { } <EOL> new_stream = [ ] <EOL> ns_prefix = { } <EOL> for kind , data , pos in stream : <EOL> if kind is START : <EOL> tag , attrs = data <EOL> directives = [ ] <EOL> strip = False <EOL> if tag . namespace == namespace : <EOL> cls = factory . get_directive ( tag . localname ) <EOL> if cls is None : <EOL> raise BadDirectiveError ( tag . localname , <EOL> self . filepath , pos [ <NUM_LIT:1> ] ) <EOL> args = dict ( [ ( name . localname , value ) for name , value <EOL> in attrs if not name . namespace ] ) <EOL> directives . append ( ( cls , args , ns_prefix . copy ( ) , pos ) ) <EOL> strip = True <EOL> new_attrs = [ ] <EOL> for name , value in attrs : <EOL> if name . namespace == namespace : <EOL> cls = factory . get_directive ( name . localname ) <EOL> if cls is None : <EOL> raise BadDirectiveError ( name . localname , <EOL> self . filepath , pos [ <NUM_LIT:1> ] ) <EOL> if type ( value ) is list and len ( value ) == <NUM_LIT:1> : <EOL> value = value [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> directives . append ( ( cls , value , ns_prefix . copy ( ) , <EOL> pos ) ) <EOL> else : <EOL> new_attrs . append ( ( name , value ) ) <EOL> new_attrs = Attrs ( new_attrs ) <EOL> if directives : <EOL> directives . sort ( self . compare_directives ( ) ) <EOL> dirmap [ ( depth , tag ) ] = ( directives , len ( new_stream ) , <EOL> strip ) <EOL> new_stream . append ( ( kind , ( tag , new_attrs ) , pos ) ) <EOL> depth += <NUM_LIT:1> <EOL> elif kind is END : <EOL> depth -= <NUM_LIT:1> <EOL> new_stream . append ( ( kind , data , pos ) ) <EOL> if ( depth , data ) in dirmap : <EOL> directives , offset , strip = dirmap . pop ( ( depth , data ) ) <EOL> substream = new_stream [ offset : ] <EOL> if strip : <EOL> substream = substream [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> new_stream [ offset : ] = [ <EOL> ( SUB , ( directives , substream ) , pos ) <EOL> ] <EOL> elif kind is SUB : <EOL> directives , substream = data <EOL> substream = self . _extract_directives ( substream , namespace , <EOL> factory ) <EOL> if len ( substream ) == <NUM_LIT:1> and substream [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] is SUB : <EOL> added_directives , substream = substream [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> directives += added_directives <EOL> new_stream . append ( ( kind , ( directives , substream ) , pos ) ) <EOL> elif kind is START_NS : <EOL> prefix , uri = data <EOL> ns_prefix [ prefix ] = uri <EOL> if uri != namespace : <EOL> new_stream . append ( ( kind , data , pos ) ) <EOL> elif kind is END_NS : <EOL> uri = ns_prefix . pop ( data , None ) <EOL> if uri and uri != namespace : <EOL> new_stream . append ( ( kind , data , pos ) ) <EOL> else : <EOL> new_stream . append ( ( kind , data , pos ) ) <EOL> return new_stream <EOL> def _extract_includes ( self , stream ) : <EOL> streams = [ [ ] ] <EOL> prefixes = { } <EOL> fallbacks = [ ] <EOL> includes = [ ] <EOL> xinclude_ns = Namespace ( self . XINCLUDE_NAMESPACE ) <EOL> for kind , data , pos in stream : <EOL> stream = streams [ - <NUM_LIT:1> ] <EOL> if kind is START : <EOL> tag , attrs = data <EOL> if tag in xinclude_ns : <EOL> if tag . localname == '<STR_LIT>' : <EOL> include_href = attrs . get ( '<STR_LIT>' ) <EOL> if not include_href : <EOL> raise TemplateSyntaxError ( '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> self . filepath , * pos [ <NUM_LIT:1> : ] ) <EOL> includes . append ( ( include_href , attrs . get ( '<STR_LIT>' ) ) ) <EOL> streams . append ( [ ] ) <EOL> elif tag . localname == '<STR_LIT>' : <EOL> streams . append ( [ ] ) <EOL> fallbacks . append ( streams [ - <NUM_LIT:1> ] ) <EOL> else : <EOL> stream . append ( ( kind , ( tag , attrs ) , pos ) ) <EOL> elif kind is END : <EOL> if fallbacks and data == xinclude_ns [ '<STR_LIT>' ] : <EOL> assert streams . pop ( ) is fallbacks [ - <NUM_LIT:1> ] <EOL> elif data == xinclude_ns [ '<STR_LIT>' ] : <EOL> fallback = None <EOL> if len ( fallbacks ) == len ( includes ) : <EOL> fallback = fallbacks . pop ( ) <EOL> streams . pop ( ) <EOL> stream = streams [ - <NUM_LIT:1> ] <EOL> href , parse = includes . pop ( ) <EOL> try : <EOL> cls = { <EOL> '<STR_LIT>' : MarkupTemplate , <EOL> '<STR_LIT:text>' : NewTextTemplate <EOL> } [ parse or '<STR_LIT>' ] <EOL> except KeyError : <EOL> raise TemplateSyntaxError ( '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> self . filepath , * pos [ <NUM_LIT:1> : ] ) <EOL> stream . append ( ( INCLUDE , ( href , cls , fallback ) , pos ) ) <EOL> else : <EOL> stream . append ( ( kind , data , pos ) ) <EOL> elif kind is START_NS and data [ <NUM_LIT:1> ] == xinclude_ns : <EOL> prefixes [ data [ <NUM_LIT:0> ] ] = data [ <NUM_LIT:1> ] <EOL> elif kind is END_NS and data in prefixes : <EOL> prefixes . pop ( data ) <EOL> else : <EOL> stream . append ( ( kind , data , pos ) ) <EOL> assert len ( streams ) == <NUM_LIT:1> <EOL> return streams [ <NUM_LIT:0> ] <EOL> def _interpolate_attrs ( self , stream ) : <EOL> for kind , data , pos in stream : <EOL> if kind is START : <EOL> tag , attrs = data <EOL> new_attrs = [ ] <EOL> for name , value in attrs : <EOL> if value : <EOL> value = list ( interpolate ( value , self . filepath , pos [ <NUM_LIT:1> ] , <EOL> pos [ <NUM_LIT:2> ] , lookup = self . lookup ) ) <EOL> if len ( value ) == <NUM_LIT:1> and value [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] is TEXT : <EOL> value = value [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> else : <EOL> value = [ ( TEXT , u'<STR_LIT>' , pos ) ] <EOL> new_attrs . append ( ( name , value ) ) <EOL> data = tag , Attrs ( new_attrs ) <EOL> yield kind , data , pos <EOL> def _prepare ( self , stream ) : <EOL> return Template . _prepare ( self , <EOL> self . _extract_includes ( self . _interpolate_attrs ( stream ) ) <EOL> ) <EOL> def add_directives ( self , namespace , factory ) : <EOL> """<STR_LIT>""" <EOL> assert not self . _prepared , '<STR_LIT>' '<STR_LIT>' <EOL> self . _stream = self . _extract_directives ( self . _stream , namespace , <EOL> factory ) <EOL> def _match ( self , stream , ctxt , start = <NUM_LIT:0> , end = None , ** vars ) : <EOL> """<STR_LIT>""" <EOL> match_templates = ctxt . _match_templates <EOL> tail = [ ] <EOL> def _strip ( stream ) : <EOL> depth = <NUM_LIT:1> <EOL> while <NUM_LIT:1> : <EOL> event = stream . next ( ) <EOL> if event [ <NUM_LIT:0> ] is START : <EOL> depth += <NUM_LIT:1> <EOL> elif event [ <NUM_LIT:0> ] is END : <EOL> depth -= <NUM_LIT:1> <EOL> if depth > <NUM_LIT:0> : <EOL> yield event <EOL> else : <EOL> tail [ : ] = [ event ] <EOL> break <EOL> for event in stream : <EOL> if not match_templates or event [ <NUM_LIT:0> ] is not START : <EOL> yield event <EOL> continue <EOL> for idx , ( test , path , template , hints , namespaces , directives ) in enumerate ( match_templates ) : <EOL> if idx < start or end is not None and idx >= end : <EOL> continue <EOL> if test ( event , namespaces , ctxt ) is True : <EOL> if '<STR_LIT>' in hints : <EOL> del match_templates [ idx ] <EOL> idx -= <NUM_LIT:1> <EOL> for test in [ mt [ <NUM_LIT:0> ] for mt in match_templates [ idx + <NUM_LIT:1> : ] ] : <EOL> test ( event , namespaces , ctxt , updateonly = True ) <EOL> pre_end = idx + <NUM_LIT:1> <EOL> if '<STR_LIT>' not in hints and '<STR_LIT>' in hints : <EOL> pre_end -= <NUM_LIT:1> <EOL> inner = _strip ( stream ) <EOL> if pre_end > <NUM_LIT:0> : <EOL> inner = self . _match ( inner , ctxt , end = pre_end ) <EOL> content = self . _include ( chain ( [ event ] , inner , tail ) , ctxt ) <EOL> if '<STR_LIT>' not in hints : <EOL> content = list ( content ) <EOL> selected = [ False ] <EOL> def select ( path ) : <EOL> selected [ <NUM_LIT:0> ] = True <EOL> return Stream ( content ) . select ( path , namespaces , ctxt ) <EOL> vars = dict ( select = select ) <EOL> template = _apply_directives ( template , directives , ctxt , <EOL> ** vars ) <EOL> for event in self . _match ( <EOL> self . _exec ( <EOL> self . _eval ( <EOL> self . _flatten ( template , ctxt , ** vars ) , <EOL> ctxt , ** vars ) , <EOL> ctxt , ** vars ) , <EOL> ctxt , start = idx + <NUM_LIT:1> , ** vars ) : <EOL> yield event <EOL> if not selected [ <NUM_LIT:0> ] : <EOL> for event in content : <EOL> pass <EOL> for test in [ mt [ <NUM_LIT:0> ] for mt in match_templates ] : <EOL> test ( tail [ <NUM_LIT:0> ] , namespaces , ctxt , updateonly = True ) <EOL> break <EOL> else : <EOL> yield event </s>
