Edgewall Software

Ticket #396: select.patch

File select.patch, 9.5 KB (added by Carsten Klein <carsten.klein@…>, 4 years ago)

Still some issues here, moved addition of the select function outside of the loop, as it was added to the variables for each test in a given match template

  • markup.py

     
    1818from genshi.core import Attrs, Markup, Namespace, Stream, StreamEventKind 
    1919from genshi.core import START, END, START_NS, END_NS, TEXT, PI, COMMENT 
    2020from genshi.input import XMLParser 
    21 from genshi.template.base import BadDirectiveError, Template, \ 
    22                                  TemplateSyntaxError, _apply_directives, \ 
    23                                  EXEC, INCLUDE, SUB 
     21from genshi.template.base import Template, TemplateSyntaxError, \ 
     22                                 _apply_directives, EXEC, INCLUDE, SUB 
    2423from genshi.template.eval import Suite 
     24from genshi.template.directives import DirectivesLibraryManager, \ 
     25                                       UnknownDirectiveError 
    2526from genshi.template.interpolation import interpolate 
    26 from genshi.template.directives import * 
    2727from genshi.template.text import NewTextTemplate 
    2828 
    2929__all__ = ['MarkupTemplate'] 
     
    4242    </ul> 
    4343    """ 
    4444 
    45     DIRECTIVE_NAMESPACE = 'http://genshi.edgewall.org/' 
    4645    XINCLUDE_NAMESPACE = 'http://www.w3.org/2001/XInclude' 
    4746 
    48     directives = [('def', DefDirective), 
    49                   ('match', MatchDirective), 
    50                   ('when', WhenDirective), 
    51                   ('otherwise', OtherwiseDirective), 
    52                   ('for', ForDirective), 
    53                   ('if', IfDirective), 
    54                   ('choose', ChooseDirective), 
    55                   ('with', WithDirective), 
    56                   ('replace', ReplaceDirective), 
    57                   ('content', ContentDirective), 
    58                   ('attrs', AttrsDirective), 
    59                   ('strip', StripDirective)] 
    6047    serializer = 'xml' 
    6148    _number_conv = Markup 
    6249 
    6350    def __init__(self, source, filepath=None, filename=None, loader=None, 
    64                  encoding=None, lookup='strict', allow_exec=True): 
     51                 encoding=None, lookup='strict', allow_exec=True, 
     52                 directives_library_manager=None): 
    6553        Template.__init__(self, source, filepath=filepath, filename=filename, 
    6654                          loader=loader, encoding=encoding, lookup=lookup, 
    67                           allow_exec=allow_exec) 
    68         self.add_directives(self.DIRECTIVE_NAMESPACE, self) 
     55                          allow_exec=allow_exec, directives_library_manager= \ 
     56                          directives_library_manager) 
     57        self._stream = self._extract_directives(self._stream) 
    6958 
    7059    def _init_filters(self): 
    7160        Template._init_filters(self) 
     
    111100 
    112101        return stream 
    113102 
    114     def _extract_directives(self, stream, namespace, factory): 
     103    def _extract_directives(self, stream): 
    115104        depth = 0 
    116105        dirmap = {} # temporary mapping of directives to elements 
    117106        new_stream = [] 
    118107        ns_prefix = {} # namespace prefixes in use 
    119108 
     109        library = self.directives_library 
     110 
    120111        for kind, data, pos in stream: 
    121112 
    122113            if kind is START: 
     
    124115                directives = [] 
    125116                strip = False 
    126117 
    127                 if tag.namespace == namespace: 
    128                     cls = factory.get_directive(tag.localname) 
     118                if library.defines_namespace(tag.namespace): 
     119                    cls = library.get_directive(tag.localname,  
     120                                                namespace=tag.namespace) 
    129121                    if cls is None: 
    130                         raise BadDirectiveError(tag.localname, 
    131                                                 self.filepath, pos[1]) 
     122                        raise UnknownDirectiveError(tag.localname, 
     123                                                    self.filepath, pos[1]) 
     124# FIXME:axn arguments to directives should be in the namespace of 
     125# the directive, alternatively one may use no namespace at all 
     126# for when using namespaces, must make sure that no directive of that 
     127# namespace is being defined in the library  
    132128                    args = dict([(name.localname, value) for name, value 
    133129                                 in attrs if not name.namespace]) 
    134                     directives.append((factory.get_directive_index(cls), cls, 
    135                                        args, ns_prefix.copy(), pos)) 
     130 
     131                    directives.append(( 
     132                        library.get_directive_priority(tag.localname,  
     133                                                       namespace= 
     134                                                       tag.namespace), 
     135                                                       cls, args,  
     136                                                       ns_prefix.copy(), 
     137                                                       pos)) 
    136138                    strip = True 
    137139 
    138140                new_attrs = [] 
    139141                for name, value in attrs: 
    140                     if name.namespace == namespace: 
    141                         cls = factory.get_directive(name.localname) 
     142                    if library.defines_namespace(name.namespace): 
     143                        cls = library.get_directive(name.localname,  
     144                                                    namespace=name.namespace) 
    142145                        if cls is None: 
    143                             raise BadDirectiveError(name.localname, 
    144                                                     self.filepath, pos[1]) 
     146                            raise UnknownDirectiveError(name.localname, 
     147                                                        self.filepath, pos[1]) 
    145148                        if type(value) is list and len(value) == 1: 
    146149                            value = value[0][1] 
    147                         directives.append((factory.get_directive_index(cls), 
    148                                            cls, value, ns_prefix.copy(), pos)) 
     150                        directives.append(( 
     151                            library.get_directive_priority(name.localname,  
     152                                                           namespace= 
     153                                                           name.namespace), 
     154                                                           cls, value,  
     155                                                           ns_prefix.copy(), 
     156                                                           pos)) 
    149157                    else: 
    150158                        new_attrs.append((name, value)) 
    151159                new_attrs = Attrs(new_attrs) 
    152160 
    153161                if directives: 
    154                     directives.sort() 
     162                    #directives.sort() 
    155163                    dirmap[(depth, tag)] = (directives, len(new_stream), 
    156164                                            strip) 
    157165 
     
    176184 
    177185            elif kind is SUB: 
    178186                directives, substream = data 
    179                 substream = self._extract_directives(substream, namespace, 
    180                                                      factory) 
     187                substream = self._extract_directives(substream) 
    181188 
    182189                if len(substream) == 1 and substream[0][0] is SUB: 
    183190                    added_directives, substream = substream[0][1] 
     
    190197                # directives 
    191198                prefix, uri = data 
    192199                ns_prefix[prefix] = uri 
    193                 if uri != namespace: 
     200                if not library.defines_namespace(uri): 
    194201                    new_stream.append((kind, data, pos)) 
    195202 
    196203            elif kind is END_NS: 
    197204                uri = ns_prefix.pop(data, None) 
    198                 if uri and uri != namespace: 
     205                if uri and not library.defines_namespace(uri): 
    199206                    new_stream.append((kind, data, pos)) 
    200207 
    201208            else: 
     
    291298            self._extract_includes(self._interpolate_attrs(stream)) 
    292299        ) 
    293300 
    294     def add_directives(self, namespace, factory): 
    295         """Register a custom `DirectiveFactory` for a given namespace. 
    296          
    297         :param namespace: the namespace URI 
    298         :type namespace: `basestring` 
    299         :param factory: the directive factory to register 
    300         :type factory: `DirectiveFactory` 
    301         :since: version 0.6 
    302         """ 
    303         assert not self._prepared, 'Too late for adding directives, ' \ 
    304                                    'template already prepared' 
    305         self._stream = self._extract_directives(self._stream, namespace, 
    306                                                 factory) 
    307  
    308301    def _match(self, stream, ctxt, start=0, end=None, **vars): 
    309302        """Internal stream filter that applies any defined match templates 
    310303        to the stream. 
     
    327320                    append(event) 
    328321                    break 
    329322 
     323        # Make the select() function available in the body of the 
     324        # match template 
     325        selected = [False] 
     326        def select(path): 
     327            selected[0] = True 
     328            return content.select(path, namespaces, ctxt) 
     329        vars['select'] = select 
     330 
    330331        for event in stream: 
    331332 
    332333            # We (currently) only care about start and end events for matching 
     
    365366                        content = list(content) 
    366367                    content = Stream(content) 
    367368 
    368                     # Make the select() function available in the body of the 
    369                     # match template 
    370                     selected = [False] 
    371                     def select(path): 
    372                         selected[0] = True 
    373                         return content.select(path, namespaces, ctxt) 
    374                     vars = dict(select=select) 
    375  
    376369                    # Recursively process the output 
    377370                    template = _apply_directives(template, directives, ctxt, 
    378371                                                 vars)