def _parse(self, source, encoding):
        """Parse the template from text input."""
        stream = [] # list of events of the "compiled" template
        dirmap = {} # temporary mapping of directives to elements
        depth = 0

        source = source.read()
        if not isinstance(source, unicode):
            source = source.decode(encoding or 'utf-8', 'replace')
        offset = 0
        lineno = 1

        _escape_sub = self._escape_re.sub
        def _escape_repl(mo):
            groups = [g for g in mo.groups() if g]
            if not groups:
                return ''
            return groups[0]

        for idx, mo in enumerate(self._directive_re.finditer(source)):
            start, end = mo.span(1)
            if start > offset:
                text = _escape_sub(_escape_repl, source[offset:start])
                for kind, data, pos in interpolate(text, self.filepath, lineno,
                                                   lookup=self.lookup):
                    stream.append((kind, data, pos))
                lineno += len(text.splitlines())

            lineno += len(source[start:end].splitlines())
            command, value = mo.group(2, 3)

            if command == 'include':
                pos = (self.filename, lineno, 0)
                value = list(interpolate(value, self.filepath, lineno, 0,
                                         lookup=self.lookup))
                if len(value) == 1 and value[0][0] is TEXT:
                    value = value[0][1]
                stream.append((INCLUDE, (value, None, []), pos))

            elif command == 'python':
                if not self.allow_exec:
                    raise TemplateSyntaxError('Python code blocks not allowed',
                                              self.filepath, lineno)
                try:
                    suite = Suite(value, self.filepath, lineno,
                                  lookup=self.lookup)
                except SyntaxError, err:
                    raise TemplateSyntaxError(err, self.filepath,
                                              lineno + (err.lineno or 1) - 1)
                pos = (self.filename, lineno, 0)
                stream.append((EXEC, suite, pos))

            elif command == 'end':
                depth -= 1
                if depth in dirmap:
                    directive, start_offset = dirmap.pop(depth)
                    substream = stream[start_offset:]
                    stream[start_offset:] = [(SUB, ([directive], substream),
                                              (self.filepath, lineno, 0))]

            elif command:
                cls = self.get_directive(command)
                if cls is None:
                    raise BadDirectiveError(command)
                directive = 0, cls, value, None, (self.filepath, lineno, 0)
                dirmap[depth] = (directive, len(stream))
                depth += 1

            offset = end

        if offset < len(source):
            text = _escape_sub(_escape_repl, source[offset:])
            for kind, data, pos in interpolate(text, self.filepath, lineno,
                                               lookup=self.lookup):
                stream.append((kind, data, pos))

        return stream
dataset/ETHPy150Open timonwong/OmniMarkupPreviewer/OmniMarkupLib/Renderers/libs/python2/genshi/template/text.py/NewTextTemplate._parse/original