degal/html.py
changeset 52 3071d0709c4a
child 53 14d73f544764
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/degal/html.py	Thu Jun 04 11:23:28 2009 +0300
@@ -0,0 +1,91 @@
+"""
+    Generating HTML tags
+"""
+
+from cgi import escape
+
+def tag_attr (name, value) :
+    return u'%s="%s"' % (name.rstrip('_'), escape(value, True))
+
+def tag_subcontent (subcontent) :
+    if not subcontent :
+        # skip
+        return
+
+    elif not isinstance(subcontent, basestring) and hasattr(subcontent, '__iter__') :
+        # render each sub-item recursively
+        for sc in subcontent :
+            for line in tag_subcontent(sc) :
+                yield line
+    
+    else :
+        yield subcontent
+
+def tag_content (content) :
+    if not content:
+        # no output
+        return
+    
+    elif isinstance(content, basestring) :
+        # escape raw vlues
+        yield escape(unicode(content))
+
+    else :
+        # treat it as subcontent
+        for line in tag_subcontent(content) :
+            yield line
+
+def tag (name, *content, **attrs) :
+    attr_stuff = " " + " ".join(tag_attr(n, v) for n, v in attrs.iteritems()) if attrs else ""
+    
+    if content and all(content) :
+        # tag with content
+        yield u"<%s%s>" % (name, attr_stuff)
+        
+        for c in content :
+            for line in tag_content(c) :
+                yield u"\t" + line
+
+        yield u"</%s>" % (name, )
+
+    else :
+        # singleton tag
+        yield u"<%s%s />" % (name, attr_stuff)
+
+def raw (data) :
+    yield data
+
+class TagFactory (object) :
+    def __getattr__ (self, name) :
+        def build_tag (*content, **attrs) :
+            return tag(name, *content, **attrs)
+
+        return build_tag
+
+tags = TagFactory()
+
+def render_lines (tags, charset=None) :
+    for line in tag_content(tags) :
+        if charset :
+            yield line.encode(charset)
+
+        else :
+            yield line
+
+def render (tags, charset=None) :
+    data = u'\n'.join(render_lines(tags))
+
+    if charset :
+        return data.encode(charset)
+
+    else :
+        return data
+
+def render_out (tags, out, charset='utf-8') :
+    """
+        Write the rendered tags into the given output stream using the given encoding
+    """
+
+    for line in render_lines(tags, charset) :
+        out.write(line + '\n')
+