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)
119 #
120 # $Log: not supported by cvs2svn $
121 #
122 # vim: set filetype=python ts=4 sw=4 et si