Code

this oughta be better
[roundup.git] / roundup / template_parser.py
1 import htmllib, formatter
3 class Require:
4     ''' Encapsulates a parsed <require attributes>...[<else>...]</require>
5     '''
6     def __init__(self, attributes):
7         self.attributes = attributes
8         self.current = self.ok = []
9         self.fail = []
10     def __len__(self):
11         return len(self.current)
12     def __getitem__(self, n):
13         return self.current[n]
14     def __setitem__(self, n, data):
15         self.current[n] = data
16     def append(self, data):
17         self.current.append(data)
18     def elseMode(self):
19         self.current = self.fail
21 class Display:
22     ''' Encapsulates a parsed <display attributes>
23     '''
24     def __init__(self, attributes):
25         self.attributes = attributes
27 class Property:
28     ''' Encapsulates a parsed <property attributes>
29     '''
30     def __init__(self, attributes):
31         self.attributes = attributes
33 class RoundupTemplateParser(htmllib.HTMLParser):
34     ''' Parse Roundup's HTML template structure into a list of components:
36         'string': this is just plain data to be displayed
37         Display : instances indicate that display functions are to be called
38         Require : if/else style check using the conditions in the attributes,
39                   displaying the "ok" list of components or "fail" list
41     '''
42     def __init__(self):
43         htmllib.HTMLParser.__init__(self, formatter.NullFormatter())
44         self.current = self.structure = []
45         self.stack = []
47     def handle_data(self, data):
48         self.append_data(data)
50     def append_data(self, data):
51         if self.current and isinstance(self.current[-1], type('')):
52             self.current[-1] = self.current[-1] + data
53         else:
54             self.current.append(data)
56     def unknown_starttag(self, tag, attributes):
57         s = ''
58         s = s + '<%s' % tag
59         for name, value in attributes:
60             s = s + ' %s="%s"' % (name, value)
61         s = s + '>'
62         self.append_data(s)
64     def handle_starttag(self, tag, method, attributes):
65         if tag in ('require', 'else', 'display', 'property'):
66             method(attributes)
67         else:
68             self.unknown_starttag(tag, attributes)
70     def unknown_endtag(self, tag):
71         if tag == 'require':
72             self.current = self.stack.pop()
73         else:
74             self.append_data('</%s>'%tag)
76     def handle_endtag(self, tag, method):
77         self.unknown_endtag(tag)
79     def close(self):
80         htmllib.HTMLParser.close(self)
82     def do_display(self, attributes):
83         self.current.append(Display(attributes))
85     def do_property(self, attributes):
86         self.current.append(Property(attributes))
88     def do_require(self, attributes):
89         r = Require(attributes)
90         self.current.append(r)
91         self.stack.append(self.current)
92         self.current = r
94     def do_else(self, attributes):
95         self.current.elseMode()
97 def display(structure, indent=''):
98     ''' Pretty-print the parsed structure for debugging
99     '''
100     for entry in structure:
101         if isinstance(entry, type('')):
102             print "%s%r"%(indent, entry[:50])
103         elif isinstance(entry, Require):
104             print '%sTEST: %r'%(indent, entry.attributes)
105             print '%sOK...'%indent
106             display(entry.ok, indent+' ')
107             if entry.fail:
108                 print '%sFAIL...'%indent
109                 display(entry.fail, indent+' ')
110         elif isinstance(entry, Display):
111             print '%sDISPLAY: %r'%(indent, entry.attributes)
113 if __name__ == '__main__':
114     import sys
115     parser = RoundupTemplateParser()
116     parser.feed(open(sys.argv[1], 'r').read())
117     display(parser.structure)
120 # $Log: not supported by cvs2svn $
122 # vim: set filetype=python ts=4 sw=4 et si