Commit | Line | Data |
---|---|---|
ff79cdbf FT |
1 | import xml.dom.minidom, StringIO |
2 | import cons as _cons | |
3 | import util | |
4 | dom = xml.dom.minidom.getDOMImplementation() | |
5 | ||
6 | ns = u"http://www.w3.org/1999/xhtml" | |
7 | doctype = u"-//W3C//DTD XHTML 1.1//EN" | |
8 | dtd = u"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" | |
9 | ||
10 | class htmlelement(_cons.element): | |
11 | def __todoc__(self): | |
12 | doc = dom.createDocument(None, None, None) | |
13 | doc.appendChild(dom.createDocumentType("html", doctype, dtd)) | |
14 | doc.appendChild(self.__todom__(doc)) | |
15 | return doc | |
16 | ||
17 | def cons(ctx=None): | |
18 | return _cons.constructor(ns, htmlelement, ctx) | |
19 | ||
20 | def head(title=None, css=None): | |
21 | h = cons() | |
22 | head = h.head | |
23 | if title: | |
24 | head(h.title(title)) | |
25 | if isinstance(css, str) or isinstance(css, unicode): | |
26 | head(h.link(rel="stylesheet", type="text/css", href=css)) | |
27 | elif css: | |
28 | for ss in css: | |
29 | head(h.link(rel="stylesheet", type="text/css", href=ss)) | |
30 | return head | |
31 | ||
32 | class htmlformatter(util.formatter): | |
33 | allowshort = set([u"br", u"hr", u"img", u"input"]) | |
34 | def element(self, el, **extra): | |
35 | if el.name in self.allowshort: | |
36 | super(htmlformatter, self).element(el, **extra) | |
37 | else: | |
38 | self.longtag(el, **extra) | |
39 | ||
40 | class htmlindenter(util.indenter, htmlformatter): | |
41 | pass | |
42 | ||
43 | def forreq(req, tree): | |
44 | # XXX: Use proper Content-Type for clients accepting it. | |
45 | req.ohead["Content-Type"] = "text/html; charset=utf-8" | |
46 | buf = StringIO.StringIO() | |
47 | htmlindenter.output(buf, tree, doctype=(doctype, dtd), charset="utf-8") | |
48 | return [buf.getvalue()] | |
49 | ||
50 | def xhtmlresp(callable): | |
51 | def wrapper(req): | |
52 | return forreq(req, callable(req)) | |
53 | return wrapper |