def starttag(self, node, tagname, suffix='\n', empty=False, **attributes):
        tagname = tagname.lower()
        prefix = []
        atts = {}
        ids = []
        for (name, value) in list(attributes.items()):
            atts[name.lower()] = value
        classes = []
        languages = []
        # unify class arguments and move language specification
        for cls in node.get('classes', []) + atts.pop('class', '').split() :
            if cls.startswith('language-'):
                languages.append(cls[9:])
            elif cls.strip() and cls not in classes:
                classes.append(cls)
        if languages:
            atts['lang'] = languages[0]
        if classes:
            atts['class'] = ' '.join(classes)
        assert 'id' not in atts
        ids.extend(node.get('ids', []))
        if 'ids' in atts:
            ids.extend(atts['ids'])
            del atts['ids']
        if ids:
            atts['id'] = ids[0]
            for id in ids[1:]:
                # Add empty "span" elements for additional IDs.
                # (I'm not sure what the status of nested "a" elements
                # is in HTML5, but in any case <a> to create a link *target*
                # appears to be deprecated.)
                if empty:
                    # Empty tag.  Insert target right in front of element.
                    prefix.append('<span id="%s"></span>' % id)
                else:
                    # Non-empty tag.  Place the auxiliary <span> tag
                    # *inside* the element, as the first child.
                    suffix += '<span id="%s"></span>' % id
        attlist = list(atts.items())
        attlist.sort()
        parts = [tagname]
        for name, value in attlist:
            # value=None was used for boolean attributes without
            # value, but this wasn't supported by XHTML and so was
            # deprecated on the input side; we retain this
            # strictness. Generating compact attributes when possible
            # is too much work.
            assert value is not None
            if isinstance(value, list):
                values = [str(v) for v in value]
                parts.append('%s="%s"' % (name.lower(),
                                          self.attval(' '.join(values))))
            else:
                parts.append('%s="%s"' % (name.lower(),
                                          self.attval(str(value))))
        return ''.join(prefix) + '<%s>' % (' '.join(parts)) + suffix
Called when a TLS ClientHello is detected in the stream.
dataset/ETHPy150Open zackw/header-survey/sphinx/ext/html5_output.py/BaseTranslator.starttag--crossover with--dataset/ETHPy150Open google/nogotofail/nogotofail/mitm/connection/handlers/base.py/BaseConnectionHandler.on_ssl