# class Reline::Face::Config

### Constants

ESSENTIAL_DEFINE_NAMES
RESET_SGR

### Attributes

definition[R]

### Public Class Methods

new(name, &block) click to toggle source

    # File lib/reline/face.rb, line 62
    def initialize(name, &block)
      @definition = {}
      block.call(self)
      ESSENTIAL_DEFINE_NAMES.each do |name|
        @definition[name] ||= { style: :reset, escape_sequence: RESET_SGR }
      end
    end

### Public Instance Methods

[](name) click to toggle source

    # File lib/reline/face.rb, line 84
    def [](name)
      @definition.dig(name, :escape_sequence) or raise ArgumentError, "unknown face: #{name}"
    end

define(name, **values) click to toggle source

    # File lib/reline/face.rb, line 72
    def define(name, **values)
      values[:escape_sequence] = format_to_sgr(values.to_a).freeze
      @definition[name] = values
    end

reconfigure() click to toggle source

    # File lib/reline/face.rb, line 77
    def reconfigure
      @definition.each_value do |values|
        values.delete(:escape_sequence)
        values[:escape_sequence] = format_to_sgr(values.to_a).freeze
      end
    end

### Private Instance Methods

format_to_sgr(ordered_values) click to toggle source

    # File lib/reline/face.rb, line 126
    def format_to_sgr(ordered_values)
      sgr = "\e[" + ordered_values.map do |key_value|
        key, value = key_value
        case key
        when :foreground, :background
          case value
          when Symbol
            SGR_PARAMETERS[key][value]
          when String
            sgr_rgb(key, value)
          end
        when :style
          [ value ].flatten.map do |style_name|
            SGR_PARAMETERS[:style][style_name]
          end.then do |sgr_parameters|
            sgr_parameters.include?(nil) ? nil : sgr_parameters
          end
        end.then do |rendition_expression|
          unless rendition_expression
            raise ArgumentError, "invalid SGR parameter: #{value.inspect}"
          end
          rendition_expression
        end
      end.join(';') + "m"
      sgr == RESET_SGR ? RESET_SGR : RESET_SGR + sgr
    end

rgb_expression?(color) click to toggle source

    # File lib/reline/face.rb, line 153
    def rgb_expression?(color)
      color.respond_to?(:match?) and color.match?(/\A#[0-9a-fA-F]{6}\z/)
    end

sgr_rgb(key, value) click to toggle source

    # File lib/reline/face.rb, line 90
    def sgr_rgb(key, value)
      return nil unless rgb_expression?(value)
      if Reline::Face.truecolor?
        sgr_rgb_truecolor(key, value)
      else
        sgr_rgb_256color(key, value)
      end
    end

sgr_rgb_256color(key, value) click to toggle source

    # File lib/reline/face.rb, line 108
    def sgr_rgb_256color(key, value)
      # 256 colors are
      # 0..15: standard colors, high intensity colors
      # 16..232: 216 colors (R, G, B each 6 steps)
      # 233..255: grayscale colors (24 steps)
      # This methods converts rgb_expression to 216 colors
      rgb = value[1, 6].scan(/../).map(&:hex)
      # Color steps are [0, 95, 135, 175, 215, 255]
      r, g, b = rgb.map { |v| v <= 95 ? v / 48 : (v - 35) / 40 }
      color = (16 + 36 * r + 6 * g + b)
      case key
      when :foreground
        "38;5;#{color}"
      when :background
        "48;5;#{color}"
      end
    end

sgr_rgb_truecolor(key, value) click to toggle source

    # File lib/reline/face.rb, line 99
    def sgr_rgb_truecolor(key, value)
      case key
      when :foreground
        "38;2;"
      when :background
        "48;2;"
      end + value[1, 6].scan(/../).map(&:hex).join(";")
    end