# File lib/pastel/color_parser.rb, line 30
    def self.parse(text)
      scanner = StringScanner.new(text)
      state = {}
      result = []
      ansi_stack = []
      text_chunk = ''

      until scanner.eos?
        char = scanner.getch
        # match control
        if char == ESC && (delim = scanner.getch) == CSI
          if scanner.scan(/^0m/)
            unpack_ansi(ansi_stack) { |attr, name| state[attr] = name }
            ansi_stack = []
          elsif scanner.scan(/^([1-9;:]+)m/)
            # ansi codes separated by text
            if !text_chunk.empty? && !ansi_stack.empty?
              unpack_ansi(ansi_stack) { |attr, name| state[attr] = name }
              ansi_stack = []
            end
            scanner[1].split(/:|;/).each do |code|
              ansi_stack << code
            end
          end

          if !text_chunk.empty?
            state[:text] = text_chunk
            result.push(state)
            state = {}
            text_chunk = ''
          end
        elsif char == ESC # broken escape
          text_chunk << char + delim.to_s
        else
          text_chunk << char
        end
      end

      if !text_chunk.empty?
        state[:text] = text_chunk
      end
      if !ansi_stack.empty?
        unpack_ansi(ansi_stack) { |attr, name| state[attr] = name}
      end
      if state.values.any? { |val| !val.empty? }
        result.push(state)
      end
      result
    end