'format a traceback from sys.exc_info() into 7-item tuples,
containing the regular four traceback tuple items, plus the original
template filename, the line number adjusted relative to the template
source, and code line from that line number of the template.'

def _init(self, trcback):

    import mako.template
    mods = {}
    rawrecords = traceback.extract_tb(trcback)
    new_trcback = []
    for (filename, lineno, function, line) in rawrecords:
        if (not line):
            line = ''
        try:
            (line_map, template_lines) = mods[filename]
        except KeyError:
            try:
                info = mako.template._get_module_info(filename)
                module_source = info.code
                template_source = info.source
                template_filename = (info.template_filename or filename)
            except KeyError:
                if (not compat.py3k):
                    try:
                        fp = open(filename, 'rb')
                        encoding = util.parse_encoding(fp)
                        fp.close()
                    except IOError:
                        encoding = None
                    if encoding:
                        line = line.decode(encoding)
                    else:
                        line = line.decode('ascii', 'replace')
                new_trcback.append((filename, lineno, function, line, None, None, None, None))
                continue
            template_ln = 1
            source_map = mako.template.ModuleInfo.get_module_source_metadata(module_source, full_line_map=True)
            line_map = source_map['full_line_map']
            template_lines = [line for line in template_source.split('\n')]
            mods[filename] = (line_map, template_lines)
        template_ln = line_map[(lineno - 1)]
        if (template_ln <= len(template_lines)):
            template_line = template_lines[(template_ln - 1)]
        else:
            template_line = None
        new_trcback.append((filename, lineno, function, line, template_filename, template_ln, template_line, template_source))
    if (not self.source):
        for l in range((len(new_trcback) - 1), 0, (-1)):
            if new_trcback[l][5]:
                self.source = new_trcback[l][7]
                self.lineno = new_trcback[l][5]
                break
        else:
            if new_trcback:
                try:
                    fp = open(new_trcback[(-1)][0], 'rb')
                    encoding = util.parse_encoding(fp)
                    fp.seek(0)
                    self.source = fp.read()
                    fp.close()
                    if encoding:
                        self.source = self.source.decode(encoding)
                except IOError:
                    self.source = ''
                self.lineno = new_trcback[(-1)][1]
    return new_trcback
