def parse_text(self, formatted_text):
        """
        Retursn a list of operations (draw, cup, ed,...).

        Each operation consist of a command and its associated data.

        :param formatted_text: text to parse with the default char format to apply.
        :return: list of Operation
        """
        assert isinstance(formatted_text, FormattedText)
        ret_val = []
        fmt = formatted_text.fmt if self._prev_fmt_closed else self._prev_fmt
        fmt = QtGui.QTextCharFormat(fmt)
        if not self._pending_text:
            stripped_text = formatted_text.txt
        else:
            stripped_text = self._pending_text + formatted_text.txt
            self._pending_text = ''
        while stripped_text:
            try:
                escape_pos = stripped_text.index(self._escape[0])
            except ValueError:
                ret_val.append(Operation('draw', FormattedText(stripped_text, fmt)))
                break
            else:
                if escape_pos != 0:
                    ret_val.append(Operation('draw', FormattedText(stripped_text[:escape_pos], fmt)))
                    stripped_text = stripped_text[escape_pos:]
                    fmt = QtGui.QTextCharFormat(fmt)
            assert stripped_text[0] == self._escape[0]
            while stripped_text and stripped_text[0] == self._escape[0]:
                if self._escape.startswith(stripped_text):
                    # control sequence not complete
                    self._pending_text += stripped_text
                    stripped_text = ''
                    break
                if not stripped_text.startswith(self._escape):
                    # check vt100 escape sequences
                    ctrl_seq = False
                    for alt_seq in self._escape_alts:
                        if stripped_text.startswith(alt_seq):
                            ctrl_seq = True
                            break
                    if not ctrl_seq:
                        # not a control sequence
                        self._pending_text = ''
                        ret_val.append(Operation('draw', FormattedText(stripped_text[:1], fmt)))
                        fmt = QtGui.QTextCharFormat(fmt)
                        stripped_text = stripped_text[1:]
                        continue
                self._pending_text += _mid(stripped_text, 0, self._escape_len)
                stripped_text = stripped_text[self._escape_len:]

                # Non draw related command (cursor/erase)
                if self._pending_text in [self._escape] + self._escape_alts:
                    m = self._supported_commands.match(stripped_text)
                    if m and self._pending_text == self._escape:
                        _, e = m.span()
                        n = m.group('n')
                        cmd = m.group('cmd')
                        if not n:
                            n = 0
                        ret_val.append(Operation(self._commands[cmd], n))
                        self._pending_text = ''
                        stripped_text = stripped_text[e:]
                        continue
                    else:
                        m = self._unsupported_command.match(stripped_text)
                        if m:
                            self._pending_text = ''
                            stripped_text = stripped_text[m.span()[1]:]
                            continue
                        elif self._pending_text in ['\x1b=', '\x1b>']:
                            self._pending_text = ''
                            continue

                # Handle Select Graphic Rendition commands
                # get the number
                str_nbr = ''
                numbers = []
                while stripped_text:
                    if stripped_text[0].isdigit():
                        str_nbr += stripped_text[0]
                    else:
                        if str_nbr:
                            numbers.append(str_nbr)
                        if not str_nbr or stripped_text[0] != self._semicolon:
                            break
                        str_nbr = ''
                    self._pending_text += _mid(stripped_text, 0, 1)
                    stripped_text = stripped_text[1:]

                if not stripped_text:
                    break

                # remove terminating char
                if not stripped_text.startswith(self._color_terminator):
                    # _logger().warn('removing %s', repr(self._pending_text + stripped_text[0]))
                    self._pending_text = ''
                    stripped_text = stripped_text[1:]
                    break

                # got consistent control sequence, ok to clear pending text
                self._pending_text = ''
                stripped_text = stripped_text[1:]

                if not numbers:
                    fmt = QtGui.QTextCharFormat(formatted_text.fmt)
                    self.end_format_scope()

                i_offset = 0
                n = len(numbers)
                for i in range(n):
                    i += i_offset
                    code = int(numbers[i])

                    if self._TextColorStart <= code <= self._TextColorEnd:
                        fmt.setForeground(_ansi_color(code - self._TextColorStart, self.color_scheme))
                        self._set_format_scope(fmt)
                    elif self._BackgroundColorStart <= code <= self._BackgroundColorEnd:
                        fmt.setBackground(_ansi_color(code - self._BackgroundColorStart, self.color_scheme))
                        self._set_format_scope(fmt)
                    else:
                        if code == self._ResetFormat:
                            fmt = QtGui.QTextCharFormat(formatted_text.fmt)
                            self.end_format_scope()
                        elif code == self._BoldText:
                            fmt.setFontWeight(QtGui.QFont.Bold)
                            self._set_format_scope(fmt)
                        elif code == self._NotBold:
                            fmt.setFontWeight(QtGui.QFont.Normal)
                            self._set_format_scope(fmt)
                        elif code == self._ItalicText:
                            fmt.setFontItalic(True)
                            self._set_format_scope(fmt)
                        elif code == self._NotItalicNotFraktur:
                            fmt.setFontItalic(False)
                            self._set_format_scope(fmt)
                        elif code == self._UnderlinedText:
                            fmt.setUnderlineStyle(fmt.SingleUnderline)
                            fmt.setUnderlineColor(fmt.foreground().color())
                            self._set_format_scope(fmt)
                        elif code == self._NotUnderlined:
                            fmt.setUnderlineStyle(fmt.NoUnderline)
                            self._set_format_scope(fmt)
                        elif code == self._DefaultTextColor:
                            fmt.setForeground(formatted_text.fmt.foreground())
                            self._set_format_scope(fmt)
                        elif code == self._DefaultBackgroundColor:
                            fmt.setBackground(formatted_text.fmt.background())
                            self._set_format_scope(fmt)
                        elif code == self._Dim:
                            fmt = QtGui.QTextCharFormat(fmt)
                            fmt.setForeground(fmt.foreground().color().darker(self.DIM_FACTOR))
                        elif code == self._Negative:
                            normal_fmt = fmt
                            fmt = QtGui.QTextCharFormat(fmt)
                            fmt.setForeground(normal_fmt.background())
                            fmt.setBackground(normal_fmt.foreground())
                        elif code == self._Positive:
                            fmt = QtGui.QTextCharFormat(formatted_text.fmt)
                        elif code in [self._RgbBackgroundColor, self._RgbTextColor]:
                            # See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
                            i += 1
                            if i == n:
                                break
                            next_code = int(numbers[i])
                            if next_code == 2:
                                # RGB set with format: 38;2;<r>;<g>;<b>
                                if i + 3 < n:
                                    method = fmt.setForeground if code == self._RgbTextColor else fmt.setBackground
                                    method(QtGui.QColor(int(numbers[i + 1]), int(numbers[i + 2]), int(numbers[i + 3])))
                                    self._set_format_scope(fmt)
                                i_offset = 3
                            elif next_code == 5:
                                # 256 color mode with format: 38;5;<i>
                                index = int(numbers[i + 1])
                                if index < 8:
                                    # The first 8 colors are standard low-intensity ANSI colors.
                                    color = _ansi_color(index, self.color_scheme)
                                elif index < 16:
                                    # The next 8 colors are standard high-intensity ANSI colors.
                                    color = _ansi_color(index - 8, self.color_scheme).lighter(150)
                                elif index < 232:
                                    # The next 216 colors are a 6x6x6 RGB cube.
                                    o = index - 16
                                    color = QtGui.QColor((o / 36) * 51, ((o / 6) % 6) * 51, (o % 6) * 51)
                                else:
                                    # The last 24 colors are a greyscale gradient.
                                    grey = (index - 232) * 11
                                    color = QtGui.QColor(grey, grey, grey)

                                if code == self._RgbTextColor:
                                    fmt.setForeground(color)
                                else:
                                    fmt.setBackground(color)

                                self._set_format_scope(fmt)
                        else:
                            _logger().warn('unsupported SGR code: %r', code)
        return ret_val