def handle_tag(self, tag, attrs, start):
    if (attrs is None):
        attrs = {}
    else:
        attrs = dict(attrs)
    if self.google_doc:
        parent_style = {}
        if start:
            if self.tag_stack:
                parent_style = self.tag_stack[(- 1)][2]
            tag_style = element_style(attrs, self.style_def, parent_style)
            self.tag_stack.append((tag, attrs, tag_style))
        else:
            (dummy, attrs, tag_style) = self.tag_stack.pop()
            if self.tag_stack:
                parent_style = self.tag_stack[(- 1)][2]
    if hn(tag):
        self.p()
        if start:
            self.inheader = True
            self.o(((hn(tag) * '#') + ' '))
        else:
            self.inheader = False
            return
    if (tag in ['p', 'div']):
        if self.google_doc:
            if (start and google_has_height(tag_style)):
                self.p()
            else:
                self.soft_br()
        else:
            self.p()
    if ((tag == 'br') and start):
        self.o('  \n')
    if ((tag == 'hr') and start):
        self.p()
        self.o('* * *')
        self.p()
    if (tag in ['head', 'style', 'script']):
        if start:
            self.quiet += 1
        else:
            self.quiet -= 1
    if (tag == 'style'):
        if start:
            self.style += 1
        else:
            self.style -= 1
    if (tag in ['body']):
        self.quiet = 0
    if (tag == 'blockquote'):
        if start:
            self.p()
            self.o('> ', 0, 1)
            self.start = 1
            self.blockquote += 1
        else:
            self.blockquote -= 1
            self.p()
    if ((tag in ['em', 'i', 'u']) and (not self.ignore_emphasis)):
        self.o(self.emphasis_mark)
    if ((tag in ['strong', 'b']) and (not self.ignore_emphasis)):
        self.o(self.strong_mark)
    if (tag in ['del', 'strike', 's']):
        if start:
            self.o((('<' + tag) + '>'))
        else:
            self.o((('</' + tag) + '>'))
    if self.google_doc:
        if (not self.inheader):
            self.handle_emphasis(start, tag_style, parent_style)
    if ((tag in ['code', 'tt']) and (not self.pre)):
        self.o('`')
    if (tag == 'abbr'):
        if start:
            self.abbr_title = None
            self.abbr_data = ''
            if has_key(attrs, 'title'):
                self.abbr_title = attrs['title']
        else:
            if (self.abbr_title != None):
                self.abbr_list[self.abbr_data] = self.abbr_title
                self.abbr_title = None
            self.abbr_data = ''
    if ((tag == 'a') and (not self.ignore_links)):
        if start:
            if (has_key(attrs, 'href') and (not (self.skip_internal_links and attrs['href'].startswith('#')))):
                self.astack.append(attrs)
                self.maybe_automatic_link = attrs['href']
            else:
                self.astack.append(None)
        elif self.astack:
            a = self.astack.pop()
            if self.maybe_automatic_link:
                self.maybe_automatic_link = None
            elif a:
                if self.inline_links:
                    self.o((('](' + escape_md(a['href'])) + ')'))
                else:
                    i = self.previousIndex(a)
                    if (i is not None):
                        a = self.a[i]
                    else:
                        self.acount += 1
                        a['count'] = self.acount
                        a['outcount'] = self.outcount
                        self.a.append(a)
                    self.o((('][' + str(a['count'])) + ']'))
    if ((tag == 'img') and start and (not self.ignore_images)):
        if has_key(attrs, 'src'):
            attrs['href'] = attrs['src']
            alt = attrs.get('alt', '')
            self.o((('![' + escape_md(alt)) + ']'))
            if self.inline_links:
                self.o((('(' + escape_md(attrs['href'])) + ')'))
            else:
                i = self.previousIndex(attrs)
                if (i is not None):
                    attrs = self.a[i]
                else:
                    self.acount += 1
                    attrs['count'] = self.acount
                    attrs['outcount'] = self.outcount
                    self.a.append(attrs)
                self.o((('[' + str(attrs['count'])) + ']'))
    if ((tag == 'dl') and start):
        self.p()
    if ((tag == 'dt') and (not start)):
        self.pbr()
    if ((tag == 'dd') and start):
        self.o('    ')
    if ((tag == 'dd') and (not start)):
        self.pbr()
    if (tag in ['ol', 'ul']):
        if ((not self.list) and (not self.lastWasList)):
            self.p()
        if start:
            if self.google_doc:
                list_style = google_list_style(tag_style)
            else:
                list_style = tag
            numbering_start = list_numbering_start(attrs)
            self.list.append({'name': list_style, 'num': numbering_start})
        elif self.list:
            self.list.pop()
        self.lastWasList = True
    else:
        self.lastWasList = False
    if (tag == 'li'):
        self.pbr()
        if start:
            if self.list:
                li = self.list[(- 1)]
            else:
                li = {'name': 'ul', 'num': 0}
            if self.google_doc:
                nest_count = self.google_nest_count(tag_style)
            else:
                nest_count = len(self.list)
            self.o(('  ' * nest_count))
            if (li['name'] == 'ul'):
                self.o((self.ul_item_mark + ' '))
            elif (li['name'] == 'ol'):
                li['num'] += 1
                self.o((str(li['num']) + '. '))
            self.start = 1
    if ((tag in ['table', 'tr']) and start):
        self.p()
    if (tag == 'td'):
        self.pbr()
    if (tag == 'pre'):
        if start:
            self.startpre = 1
            self.pre = 1
        else:
            self.pre = 0
        self.p()
def handle_tag(self, tag, attrs, start):
    if (attrs is None):
        attrs = {}
    else:
        attrs = dict(attrs)
    if self.google_doc:
        parent_style = {}
        if start:
            if self.tag_stack:
                parent_style = self.tag_stack[(- 1)][2]
            tag_style = element_style(attrs, self.style_def, parent_style)
            self.tag_stack.append((tag, attrs, tag_style))
        else:
            (dummy, attrs, tag_style) = self.tag_stack.pop()
            if self.tag_stack:
                parent_style = self.tag_stack[(- 1)][2]
    if hn(tag):
        self.p()
        if start:
            self.inheader = True
            self.o(((hn(tag) * '#') + ' '))
        else:
            self.inheader = False
            return
    if (tag in ['p', 'div']):
        if self.google_doc:
            if (start and google_has_height(tag_style)):
                self.p()
            else:
                self.soft_br()
        else:
            self.p()
    if ((tag == 'br') and start):
        self.o('  \n')
    if ((tag == 'hr') and start):
        self.p()
        self.o('* * *')
        self.p()
    if (tag in ['head', 'style', 'script']):
        if start:
            self.quiet += 1
        else:
            self.quiet -= 1
    if (tag == 'style'):
        if start:
            self.style += 1
        else:
            self.style -= 1
    if (tag in ['body']):
        self.quiet = 0
    if (tag == 'blockquote'):
        if start:
            self.p()
            self.o('> ', 0, 1)
            self.start = 1
            self.blockquote += 1
        else:
            self.blockquote -= 1
            self.p()
    if ((tag in ['em', 'i', 'u']) and (not self.ignore_emphasis)):
        self.o(self.emphasis_mark)
    if ((tag in ['strong', 'b']) and (not self.ignore_emphasis)):
        self.o(self.strong_mark)
    if (tag in ['del', 'strike', 's']):
        if start:
            self.o((('<' + tag) + '>'))
        else:
            self.o((('</' + tag) + '>'))
    if self.google_doc:
        if (not self.inheader):
            self.handle_emphasis(start, tag_style, parent_style)
    if ((tag in ['code', 'tt']) and (not self.pre)):
        self.o('`')
    if (tag == 'abbr'):
        if start:
            self.abbr_title = None
            self.abbr_data = 
            if has_key(attrs, 'title'):
                self.abbr_title = attrs['title']
        else:
            if (self.abbr_title != None):
                self.abbr_list[self.abbr_data] = self.abbr_title
                self.abbr_title = None
            self.abbr_data = 
    if ((tag == 'a') and (not self.ignore_links)):
        if start:
            if (has_key(attrs, 'href') and (not (self.skip_internal_links and attrs['href'].startswith('#')))):
                self.astack.append(attrs)
                self.maybe_automatic_link = attrs['href']
            else:
                self.astack.append(None)
        elif self.astack:
            a = self.astack.pop()
            if self.maybe_automatic_link:
                self.maybe_automatic_link = None
            elif a:
                if self.inline_links:
                    self.o((('](' + escape_md(a['href'])) + ')'))
                else:
                    i = self.previousIndex(a)
                    if (i is not None):
                        a = self.a[i]
                    else:
                        self.acount += 1
                        a['count'] = self.acount
                        a['outcount'] = self.outcount
                        self.a.append(a)
                    self.o((('][' + str(a['count'])) + ']'))
    if ((tag == 'img') and start and (not self.ignore_images)):
        if has_key(attrs, 'src'):
            attrs['href'] = attrs['src']
            alt = attrs.get('alt', )
            self.o((('![' + escape_md(alt)) + ']'))
            if self.inline_links:
                self.o((('(' + escape_md(attrs['href'])) + ')'))
            else:
                i = self.previousIndex(attrs)
                if (i is not None):
                    attrs = self.a[i]
                else:
                    self.acount += 1
                    attrs['count'] = self.acount
                    attrs['outcount'] = self.outcount
                    self.a.append(attrs)
                self.o((('[' + str(attrs['count'])) + ']'))
    if ((tag == 'dl') and start):
        self.p()
    if ((tag == 'dt') and (not start)):
        self.pbr()
    if ((tag == 'dd') and start):
        self.o('    ')
    if ((tag == 'dd') and (not start)):
        self.pbr()
    if (tag in ['ol', 'ul']):
        if ((not self.list) and (not self.lastWasList)):
            self.p()
        if start:
            if self.google_doc:
                list_style = google_list_style(tag_style)
            else:
                list_style = tag
            numbering_start = list_numbering_start(attrs)
            self.list.append({'name': list_style, 'num': numbering_start})
        elif self.list:
            self.list.pop()
        self.lastWasList = True
    else:
        self.lastWasList = False
    if (tag == 'li'):
        self.pbr()
        if start:
            if self.list:
                li = self.list[(- 1)]
            else:
                li = {'name': 'ul', 'num': 0}
            if self.google_doc:
                nest_count = self.google_nest_count(tag_style)
            else:
                nest_count = len(self.list)
            self.o(('  ' * nest_count))
            if (li['name'] == 'ul'):
                self.o((self.ul_item_mark + ' '))
            elif (li['name'] == 'ol'):
                li['num'] += 1
                self.o((str(li['num']) + '. '))
            self.start = 1
    if ((tag in ['table', 'tr']) and start):
        self.p()
    if (tag == 'td'):
        self.pbr()
    if (tag == 'pre'):
        if start:
            self.startpre = 1
            self.pre = 1
        else:
            self.pre = 0
        self.p()