'Construct and return a start tag given a node (id & class attributes
are extracted), tag name, and optional attributes.'

def starttag(self, node, tagname, suffix='\n', empty=0, **attributes):

    tagname = tagname.lower()
    prefix = []
    atts = {}
    ids = []
    for (name, value) in attributes.items():
        atts[name.lower()] = value
    classes = node.get('classes', [])
    if atts.has_key('class'):
        classes.append(atts['class'])
    if classes:
        atts['class'] = '    '.join(classes)
    assert (not atts.has_key('id'))
    ids.extend(node.get('ids', []))
    if atts.has_key('ids'):
        ids.extend(atts['ids'])
        del atts['ids']
    if ids:
        atts['id'] = ids[0]
        for id in ids[1:]:
            if empty:
                prefix.append(('<span    id="%s"></span>' % id))
            else:
                suffix += ('<span    id="%s"></span>' % id)
    attlist = atts.items()
    attlist.sort()
    parts = [tagname]
    for (name, value) in attlist:
        assert (value is not None)
        if isinstance(value, ListType):
            values = [unicode(v) for v in value]
            parts.append(('%s="%s"' % (name.lower(), self.attval('    '.join(values)))))
        else:
            parts.append(('%s="%s"' % (name.lower(), self.attval(unicode(value)))))
    if empty:
        infix = '    /'
    else:
        infix = ''
    return ((''.join(prefix) + ('<%s%s>' % ('    '.join(parts), infix))) + suffix)
