degal/html.py
changeset 52 3071d0709c4a
child 53 14d73f544764
equal deleted inserted replaced
51:0f39cb5e4b11 52:3071d0709c4a
       
     1 """
       
     2     Generating HTML tags
       
     3 """
       
     4 
       
     5 from cgi import escape
       
     6 
       
     7 def tag_attr (name, value) :
       
     8     return u'%s="%s"' % (name.rstrip('_'), escape(value, True))
       
     9 
       
    10 def tag_subcontent (subcontent) :
       
    11     if not subcontent :
       
    12         # skip
       
    13         return
       
    14 
       
    15     elif not isinstance(subcontent, basestring) and hasattr(subcontent, '__iter__') :
       
    16         # render each sub-item recursively
       
    17         for sc in subcontent :
       
    18             for line in tag_subcontent(sc) :
       
    19                 yield line
       
    20     
       
    21     else :
       
    22         yield subcontent
       
    23 
       
    24 def tag_content (content) :
       
    25     if not content:
       
    26         # no output
       
    27         return
       
    28     
       
    29     elif isinstance(content, basestring) :
       
    30         # escape raw vlues
       
    31         yield escape(unicode(content))
       
    32 
       
    33     else :
       
    34         # treat it as subcontent
       
    35         for line in tag_subcontent(content) :
       
    36             yield line
       
    37 
       
    38 def tag (name, *content, **attrs) :
       
    39     attr_stuff = " " + " ".join(tag_attr(n, v) for n, v in attrs.iteritems()) if attrs else ""
       
    40     
       
    41     if content and all(content) :
       
    42         # tag with content
       
    43         yield u"<%s%s>" % (name, attr_stuff)
       
    44         
       
    45         for c in content :
       
    46             for line in tag_content(c) :
       
    47                 yield u"\t" + line
       
    48 
       
    49         yield u"</%s>" % (name, )
       
    50 
       
    51     else :
       
    52         # singleton tag
       
    53         yield u"<%s%s />" % (name, attr_stuff)
       
    54 
       
    55 def raw (data) :
       
    56     yield data
       
    57 
       
    58 class TagFactory (object) :
       
    59     def __getattr__ (self, name) :
       
    60         def build_tag (*content, **attrs) :
       
    61             return tag(name, *content, **attrs)
       
    62 
       
    63         return build_tag
       
    64 
       
    65 tags = TagFactory()
       
    66 
       
    67 def render_lines (tags, charset=None) :
       
    68     for line in tag_content(tags) :
       
    69         if charset :
       
    70             yield line.encode(charset)
       
    71 
       
    72         else :
       
    73             yield line
       
    74 
       
    75 def render (tags, charset=None) :
       
    76     data = u'\n'.join(render_lines(tags))
       
    77 
       
    78     if charset :
       
    79         return data.encode(charset)
       
    80 
       
    81     else :
       
    82         return data
       
    83 
       
    84 def render_out (tags, out, charset='utf-8') :
       
    85     """
       
    86         Write the rendered tags into the given output stream using the given encoding
       
    87     """
       
    88 
       
    89     for line in render_lines(tags, charset) :
       
    90         out.write(line + '\n')
       
    91