Skip to content

Commit 3ae3c51

Browse files
author
Richard Jones
committed
this oughta be better
1 parent 0eb89fe commit 3ae3c51

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

roundup/template_parser.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import htmllib, formatter
2+
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
20+
21+
class Display:
22+
''' Encapsulates a parsed <display attributes>
23+
'''
24+
def __init__(self, attributes):
25+
self.attributes = attributes
26+
27+
class Property:
28+
''' Encapsulates a parsed <property attributes>
29+
'''
30+
def __init__(self, attributes):
31+
self.attributes = attributes
32+
33+
class RoundupTemplateParser(htmllib.HTMLParser):
34+
''' Parse Roundup's HTML template structure into a list of components:
35+
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
40+
41+
'''
42+
def __init__(self):
43+
htmllib.HTMLParser.__init__(self, formatter.NullFormatter())
44+
self.current = self.structure = []
45+
self.stack = []
46+
47+
def handle_data(self, data):
48+
self.append_data(data)
49+
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)
55+
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)
63+
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)
69+
70+
def unknown_endtag(self, tag):
71+
if tag == 'require':
72+
self.current = self.stack.pop()
73+
else:
74+
self.append_data('</%s>'%tag)
75+
76+
def handle_endtag(self, tag, method):
77+
self.unknown_endtag(tag)
78+
79+
def close(self):
80+
htmllib.HTMLParser.close(self)
81+
82+
def do_display(self, attributes):
83+
self.current.append(Display(attributes))
84+
85+
def do_property(self, attributes):
86+
self.current.append(Property(attributes))
87+
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
93+
94+
def do_else(self, attributes):
95+
self.current.elseMode()
96+
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)
112+
113+
if __name__ == '__main__':
114+
import sys
115+
parser = RoundupTemplateParser()
116+
parser.feed(open(sys.argv[1], 'r').read())
117+
display(parser.structure)
118+
119+
#
120+
# $Log: not supported by cvs2svn $
121+
#
122+
# vim: set filetype=python ts=4 sw=4 et si
123+

0 commit comments

Comments
 (0)