def print_string(s)
      s = s.to_s.dup
      until s.empty?
        if s.sub!(/([^\e]*)?\e([\[\(])([0-9\;\=]*)([a-zA-Z@])(.*)/, '\5')
          @out.write(concealed(Regexp.last_match(1)))
          if Regexp.last_match(2) == '[' && Regexp.last_match(4) == 'm'
            attrs = Regexp.last_match(3).split(';')
            attrs.push(nil) unless attrs
            attrs.each do |attr|
              atv = attr.to_i
              case atv
              when 0
                reset_colors
              when 1
                @bold = true
              when 21
                @bold = false
              when 4
                @underline = true
              when 24
                @underline = false
              when 7
                @revideo = true
              when 27
                @revideo = false
              when 8
                @concealed = true
              when 28
                @concealed = false
              when 30..37
                @foreground = ANSI2WIN[atv - 30]
              when 39
                @foreground = @default_foreground
              when 40..47
                @background = ANSI2WIN[atv - 40]
              when 49
                @background = @default_background
              end
            end

            attrib = @revideo ? (@background | (@foreground << 4)) : (@foreground | (@background << 4))
            attrib |= 0x08 if @bold
            attrib |= 0x400 if @underline

            WinColors.SetConsoleTextAttribute(@handle, attrib)
          end
        else
          @out.write(concealed(s))
          s = ''
        end
      end
    end
def print_string(s)
      s = s.to_s.dup
      until s.empty?
        if s.sub!(/([^\e]*)?\e([\[\(])([0-9\;\=]*)([a-zA-Z@])(.*)/, '\5')
          @out.write(concealed(Regexp.last_match(1)))
          if Regexp.last_match(2) == '[' && Regexp.last_match(4) == 'm'
            attrs = Regexp.last_match(3).split(';')
            attrs.push(nil) unless attrs
            attrs.each do |attr|
              atv = attr.to_i
              case atv
              when 0
                reset_colors
              when 1
                @bold = true
              when 21
                @bold = false
              when 4
                @underline = true
              when 24
                @underline = false
              when 7
                @revideo = true
              when 27
                @revideo = false
              when 8
                @concealed = true
              when 28
                @concealed = false
              when 30..37
                @foreground = ANSI2WIN[atv - 30]
              when 39
                @foreground = @default_foreground
              when 40..47
                @background = ANSI2WIN[atv - 40]
              when 49
                @background = @default_background
              end
            end

            attrib = @revideo ? (@background | (@foreground << 4)) : (@foreground | (@background << 4))
            attrib |= 0x08 if @bold
            attrib |= 0x400 if @underline

            WinColors.SetConsoleTextAttribute(@handle, attrib)
          end
        else
          @out.write(concealed(s))
          s = ''
        end
      end
    end
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
 rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
 rubocop:disable Metrics/BlockNesting, Metrics/BlockLength