""" SimpleHTMLGen.py 5 Oct 2002 Ian Bicking Kind of like htmlgen, only much simpler. The only important symbol that is exported is ``html``. You create tags with attribute access. I.e., the "A" anchor tag is html.a. The attributes of the HTML tag are done with keyword arguments. The contents of the tag are the non-keyword arguments (concatenated). You can also use the special "c" keyword, passing a list, tuple, or single tag, and it will make up the contents (this is useful because keywords have to come after all non-keyword arguments, which is non-intuitive). If the value of an attribute is Exclude, then no attribute will be inserted. I.e.:: >>> html.a(href="http://www.yahoo.com">, name=Exclude, c="Click Here") 'Click Here' If the value is None, then the empty string is used. Otherwise str() is called on the value. ``html`` can also be called, and it will concatenate the string representations of its arguments. ``html.input`` is special, in that you can use ``html.input.radio()`` to get an ```` tag. You can still use ``html.input(type="radio")`` though, just like normal. ``html.comment`` will generate an HTML comment, like ``html.comment('comment text', 'and some more text')`` -- note that it cannot take keyword arguments (because they wouldn't mean anything). """ from cgi import escape class Base: def __getattr__(self, attr): attr = attr.lower() if attr == "input": return UnfinishedInput('input') elif attr == "comment": return UnfinishedComment() else: return UnfinishedTag(attr) def __call__(self, *args): return ''.join(map(str, args)) class UnfinishedTag: def __init__(self, tag): self._tag = tag def __call__(self, *args, **kw): return Tag(self._tag, *args, **kw) class UnfinishedInput: def __init__(self, tag, type=None): self._tag = tag self._type = type def __call__(self, *args, **kw): if self._type: kw['type'] = self._type return Tag(self._tag, *args, **kw) def __getattr__(self, attr): return UnfinishedInput(self._tag, type=attr.lower()) class UnfinishedComment: def __call__(self, *args): return '' % ''.join(map(str, args)) def htmlEncode(v, str=str, escape=escape): if v is None: return "" else: return escape(str(v), 1) def attrEncode(v): if v.endswith('_'): return v[:-1] else: return v def Tag(tag, *args, **kw): if kw.has_key("c"): assert not args, "The special 'c' keyword argument cannot be used in conjunction with non-keyword arguments" args = kw["c"] del kw["c"] if type(args) not in (type(()), type([])): args = (args,) htmlArgs = [' %s="%s"' % (attrEncode(attr), htmlEncode(value)) for attr, value in kw.items() if value is not Exclude] if not args and emptyTags.has_key(tag): if blockTags.has_key(tag): return "<%s%s/>\n" % (tag, "".join(htmlArgs)) else: return "<%s%s/>" % (tag, "".join(htmlArgs)) else: if blockTags.has_key(tag): return "<%s%s>\n%s\n\n" % ( tag, "".join(htmlArgs), "".join(map(str, args)), tag) else: return "<%s%s>%s" % ( tag, "".join(htmlArgs), "".join(map(str, args)), tag) def d(*kw): return kw emptyTagString = """ area base basefont br col frame hr img input isindex link meta param """ emptyTags = {} for tag in emptyTagString.split(): emptyTags[tag] = 1 blockTagString = """ applet blockquote body br dd div dl dt fieldset form frameset head hr html iframe map menu noframes noscript object ol optgroup p param script select table tbody tfoot thead tr ul var """ blockTags = {} for tag in blockTagString.split(): blockTags[tag] = 1 html = Base() class Exclude: pass __all__ = [html, Exclude] if __name__ == "__main__": print html.html( html.head(html.title("Page Title")), html.body( bgcolor="#000066", text="#ffffff", c=[html.h1("Page Title"), html.p("Hello world!")], ))