Changeset 27

Show
Ignore:
Timestamp:
19/08/04 13:12:33 (4 years ago)
Author:
steve
Message:

#parse

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/airspeed.py

    r26 r27  
    2929        self.root_element.evaluate(namespace, fileobj, loader) 
    3030 
     31 
    3132class TemplateError(Exception): 
    3233    pass 
     34 
    3335 
    3436class TemplateSyntaxError(TemplateError): 
     
    5557 
    5658class NullLoader: 
    57     def merge_text(self, name, stream): 
    58         raise self.load_template(name) 
     59    def load_text(self, name): 
     60        raise TemplateError("no loader available for '%s'" % name) 
    5961 
    6062    def load_template(self, name): 
    61         raise TemplateError("no loader available for '%s'" % name) 
     63        raise self.load_text(name) 
    6264 
    6365 
    6466class FileLoader: 
    65     def merge_text(self, name, stream): 
     67    def load_text(self, name): 
    6668        f = open(name) 
    67         try: stream.write(f.read()
     69        try: return f.read(
    6870        finally: f.close() 
    6971 
    7072    def load_template(self, name): 
    71         f = open(name) 
    72         try: return Template(f.read()) 
    73         finally: f.close() 
     73        return Template(self.load_text(name)) 
    7474 
    7575 
     
    496496 
    497497    def evaluate(self, namespace, stream, loader): 
    498         template = loader.merge_text(self.name.calculate(namespace), stream) 
     498        stream.write(loader.load_text(self.name.calculate(namespace))) 
     499 
     500 
     501class ParseDirective(_Element): 
     502    START = re.compile(r'#parse\b(.*)', re.S + re.I) 
     503    OPEN_PAREN = re.compile(r'[ \t]*\(\s*(.*)$', re.S) 
     504    CLOSE_PAREN = re.compile(r'[ \t]*\)(.*)$', re.S) 
     505 
     506    def parse(self): 
     507        self.identity_match(self.START) 
     508        self.require_match(self.OPEN_PAREN, '(') 
     509        self.name = self.require_next_element((StringLiteral, SimpleReference), 'template name') 
     510        self.require_match(self.CLOSE_PAREN, ')') 
     511 
     512    def evaluate(self, namespace, stream, loader): 
     513        template = loader.load_template(self.name.calculate(namespace)) 
     514        ## TODO: local namespace? 
     515        template.merge_to(namespace, stream, loader=loader) 
    499516 
    500517 
     
    554571        self.children = [] 
    555572        while True: 
    556             try: self.children.append(self.next_element((Text, Placeholder, Comment, IfDirective, SetDirective, ForeachDirective, IncludeDirective, MacroDefinition, MacroCall))) 
     573            try: self.children.append(self.next_element((Text, Placeholder, Comment, IfDirective, SetDirective, ForeachDirective, IncludeDirective, ParseDirective, MacroDefinition, MacroCall))) 
    557574            except NoMatch: break 
    558575 
  • trunk/airspeed_test.py

    r25 r27  
    331331        self.assertRaises(airspeed.TemplateError, template.merge, {}) 
    332332 
    333     def test_include_directive_yield_loader_error_if_included_content_not_found(self): 
     333    def test_include_directive_yields_loader_error_if_included_content_not_found(self): 
    334334        class BrokenLoader: 
    335             def merge_text(self, name, stream): 
     335            def load_text(self, name): 
    336336                raise IOError(name) 
    337337        template = airspeed.Template('#include ("foo.tmpl")') 
    338338        self.assertRaises(IOError, template.merge, {}, loader=BrokenLoader()) 
     339 
     340    def test_valid_include_directive_include_content(self): 
     341        class WorkingLoader: 
     342            def load_text(self, name): 
     343                if name == 'foo.tmpl': 
     344                    return "howdy" 
     345        template = airspeed.Template('Message is: #include ("foo.tmpl")!') 
     346        self.assertEquals('Message is: howdy!', template.merge({}, loader=WorkingLoader())) 
     347 
     348    def test_parse_directive_gives_error_if_no_loader_provided(self): 
     349        template = airspeed.Template('#parse ("foo.tmpl")') 
     350        self.assertRaises(airspeed.TemplateError, template.merge, {}) 
     351 
     352    def test_parse_directive_yields_loader_error_if_parsed_content_not_found(self): 
     353        class BrokenLoader: 
     354            def load_template(self, name): 
     355                raise IOError(name) 
     356        template = airspeed.Template('#parse ("foo.tmpl")') 
     357        self.assertRaises(IOError, template.merge, {}, loader=BrokenLoader()) 
     358 
     359    def test_valid_parse_directive_outputs_parsed_content(self): 
     360        class WorkingLoader: 
     361            def load_template(self, name): 
     362                if name == 'foo.tmpl': 
     363                    return airspeed.Template("$message") 
     364        template = airspeed.Template('Message is: #parse ("foo.tmpl")!') 
     365        self.assertEquals('Message is: hola!', template.merge({'message': 'hola'}, loader=WorkingLoader())) 
    339366 
    340367# 
     
    345372#  range literals 
    346373#  list literals 
    347 #  #parse, #include 
     374#  #parse 
    348375#  Bind #macro calls at compile time? 
    349376#  Interpolated strings