2 from wrw import dispatch
9 if isinstance(el, cons.element):
10 if el.ns not in names:
11 names[el.ns] = u"n" + unicode(nid[0])
13 for ch in el.children:
22 class formatter(object):
23 def __init__(self, out, root, nsnames=None, charset="utf-8", doctype=None):
26 nsnames = findnsnames(root)
27 self.nsnames = nsnames
29 self.charset = charset
30 self.doctype = doctype
32 def write(self, text):
33 self.out.write(text.encode(self.charset))
35 def quotewrite(self, buf):
49 def rawcode(self, el):
52 def attrval(self, buf):
53 qc, qt = (u"'", u"'") if u'"' in buf else (u'"', u""")
73 def shorttag(self, el, **extra):
74 self.write(u'<' + self.elname(el))
75 for k, v in el.attrs.iteritems():
78 for k, v in extra.iteritems():
84 ns = self.nsnames[el.ns]
88 return ns + u':' + el.name
90 def starttag(self, el, **extra):
91 self.write(u'<' + self.elname(el))
92 for k, v in el.attrs.iteritems():
95 for k, v in extra.iteritems():
100 def endtag(self, el):
101 self.write(u'</' + self.elname(el) + u'>')
103 def longtag(self, el, **extra):
104 self.starttag(el, **extra)
105 for ch in el.children:
109 def element(self, el, **extra):
110 if len(el.children) == 0:
111 self.shorttag(el, **extra)
113 self.longtag(el, **extra)
116 if isinstance(el, cons.element):
118 elif isinstance(el, cons.text):
120 elif isinstance(el, cons.raw):
123 raise Exception("Unknown object in element tree: " + el)
126 self.write(u'<?xml version="1.0" encoding="' + self.charset + u'" ?>\n')
128 self.write(u'<!DOCTYPE %s PUBLIC "%s" "%s">\n' % (self.root.name,
132 for uri, nm in self.nsnames.iteritems():
136 extra[u"xmlns"] = uri
138 extra[u"xmlns:" + nm] = uri
139 self.element(self.root, **extra)
142 def output(cls, out, el, *args, **kw):
143 cls(out=out, root=el, *args, **kw).start()
146 def fragment(cls, out, el, *args, **kw):
147 cls(out=out, root=el, *args, **kw).node(el)
150 def format(cls, el, *args, **kw):
151 buf = StringIO.StringIO()
152 cls.output(buf, el, *args, **kw)
153 return buf.getvalue()
155 def update(self, **ch):
156 ret = type(self).__new__(type(self))
157 ret.__dict__.update(self.__dict__)
158 ret.__dict__.update(ch)
161 class iwriter(object):
162 def __init__(self, out):
167 def write(self, buf):
176 def indent(self, indent):
184 class indenter(formatter):
185 def __init__(self, indent=u" ", *args, **kw):
186 super(indenter, self).__init__(*args, **kw)
187 self.out = iwriter(self.out)
191 def simple(self, el):
192 for ch in el.children:
193 if not isinstance(ch, cons.text):
197 def longtag(self, el, **extra):
198 self.starttag(el, **extra)
201 if not self.simple(el):
202 sub = self.update(curind=self.curind + self.indent)
205 for ch in el.children:
211 def element(self, el, **extra):
212 super(indenter, self).element(el, **extra)
213 if self.out.col > 80 and self.simple(el):
217 self.out.indent(self.curind.encode(self.charset))
220 super(indenter, self).start()
223 class response(dispatch.restart):
228 def __init__(self, root):
229 super(response, self).__init__()
234 raise Exception("a subclass of wrw.sp.util.response must override ctype")
236 def handle(self, req):
237 ret = self.formatter.format(self.root, doctype=self.doctype, charset=self.charset)
238 req.ohead["Content-Type"] = self.ctype
239 req.ohead["Content-Length"] = len(ret)