""" 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). Examples:: >>> print html.html( ... html.head(html.title("Page Title")), ... html.body( ... bgcolor='#000066', ... text='#ffffff', ... c=[html.h1('Page Title'), ... html.p('Hello world!')], ... )) Page Title

Page Title

Hello world!

. . >>> html.a(href='#top', c='return to top') 'return to top' >>> 1.4 1.4 """ from cgi import escape class Base: #input = UnfinishedInput('input') #comment = UnfinishedComment() def __getattr__(self, attr): if attr.startswith('__'): raise AttributeError attr = attr.lower() #return UnfinishedTag(attr) if attr == "input": return UnfinishedInput('input') elif attr == "comment": return UnfinishedComment() else: return UnfinishedTag(attr) def __call__(self, *args): return ''.join(map(str, args)) def quote(self, *args): return ''.join(map(htmlEncode, args)) class UnfinishedTag: def __init__(self, tag): self._tag = tag def __call__(self, *args, **kw): return Tag(self._tag, *args, **kw) def __str__(self): return '<%s/>' % self._tag 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): if attr.startswith('__'): raise AttributeError 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] htmlArgs = [] for attr, value in kw.items(): if value is Exclude: continue if value is NoValue: htmlArgs.append(' %s' % attrEncode(attr)) else: htmlArgs.append(' %s="%s"' % (attrEncode(attr), htmlEncode(value))) 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 class NoValue: pass __all__ = [html, Exclude]