fedux-org/proxy_rb

View on GitHub
lib/proxy_rb/colorizer.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true
# ProxyRb
module ProxyRb
  # The ANSIColor module can be used for namespacing and mixed into your own
  # classes.
  module AnsiColor
    # :stopdoc:
    ATTRIBUTES = [
      [:clear,   0],
      [:reset,   0], # synonym for :clear
      [:bold,   1],
      [:dark,   2],
      [:italic, 3], # not widely implemented
      [:underline, 4],
      [:underscore, 4], # synonym for :underline
      [:blink, 5],
      [:rapid_blink, 6], # not widely implemented
      [:negative, 7], # no reverse because of String#reverse
      [:concealed, 8],
      [:strikethrough, 9], # not widely implemented
      [:black, 30],
      [:red, 31],
      [:green, 32],
      [:yellow, 33],
      [:blue, 34],
      [:magenta, 35],
      [:cyan, 36],
      [:white, 37],
      [:on_black, 40],
      [:on_red, 41],
      [:on_green, 42],
      [:on_yellow, 43],
      [:on_blue, 44],
      [:on_magenta, 45],
      [:on_cyan, 46],
      [:on_white, 47]
    ].freeze

    ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
    # :startdoc:

    # Returns true, if the coloring function of this module
    # is switched on, false otherwise.
    def self.coloring?
      @coloring
    end

    # Turns the coloring on or off globally, so you can easily do
    # this for example:
    #  ProxyRb::Colorizer.coloring = STDOUT.isatty
    def self.coloring=(val)
      @coloring = val
    end
    self.coloring = true

    ATTRIBUTES.each do |c, v|
      define_method(c) do |string|
        result = []
        result << "\e[#{v}m" if ProxyRb::AnsiColor.coloring?
        if block_given?
          result << yield
        elsif string
          result << string
        elsif respond_to?(:to_str)
          result << to_str
        else
          return result # only switch on
        end
        result << "\e[0m" if ProxyRb::AnsiColor.coloring?

        result.join
      end
    end

    # Regular expression that is used to scan for ANSI-sequences while
    # uncoloring strings.
    COLORED_REGEXP = /\e\[(?:[34][0-7]|[0-9])?m/

    def self.included(klass)
      return unless klass == String

      ATTRIBUTES.delete(:clear)
      ATTRIBUTE_NAMES.delete(:clear)
    end

    # Returns an uncolored version of the string, that is all
    # ANSI-sequences are stripped from the string.
    def uncolored(string = nil) # :yields:
      if block_given?
        yield.gsub(COLORED_REGEXP, '')
      elsif string
        string.gsub(COLORED_REGEXP, '')
      elsif respond_to?(:to_str)
        to_str.gsub(COLORED_REGEXP, '')
      else
        ''
      end
    end

    # Returns an array of all ProxyRb::Platforms::AnsiColor attributes as symbols.
    def attributes
      ATTRIBUTE_NAMES
    end
  end
end

# ProxyRb
module ProxyRb
  # Colorize output
  class Colorizer
    include ProxyRb::AnsiColor
  end
end