class HighLine::Style
ANSI styles to be used by HighLine
.
Attributes
@return [Boolean] true if the Style
is builtin or not.
@return [Array] the three numerical rgb codes. Ex: [10, 12, 127]
Public Class Methods
From an ANSI number (color escape code), craft an 'rgb_hex' code of it @param ansi_number [Integer] ANSI escape code @return [String] all color codes joined as {.rgb_hex}
# File lib/highline/style.rb, line 157 def self.ansi_rgb_to_hex(ansi_number) raise "Invalid ANSI rgb code #{ansi_number}" unless (16..231).cover?(ansi_number) parts = (ansi_number - 16). to_s(6). rjust(3, "0"). scan(/./). map { |d| (d.to_i * 255.0 / 6.0).ceil } rgb_hex(*parts) end
Clear all custom Styles, restoring the Style
index to builtin styles only. @return [void]
# File lib/highline/style.rb, line 92 def self.clear_index # reset to builtin only styles @styles = list.select { |_name, style| style.builtin } @code_index = {} @styles.each_value { |style| index(style) } end
@return [Hash] list of all cached Style
codes
# File lib/highline/style.rb, line 175 def self.code_index @code_index ||= {} end
Index the given style. Uses @code_index (Hash) as repository. @param style [Style] @return [Style] the given style
# File lib/highline/style.rb, line 73 def self.index(style) if style.name @styles ||= {} @styles[style.name] = style end unless style.list @code_index ||= {} @code_index[style.code] ||= [] @code_index[style.code].reject! do |indexed_style| indexed_style.name == style.name end @code_index[style.code] << style end style end
@return [Hash] list of all cached Styles
# File lib/highline/style.rb, line 170 def self.list @styles ||= {} end
Single color/styles have :name, :code, :rgb (possibly), :builtin Compound styles have :name, :list, :builtin
@param defn [Hash] options for the Style
to be created.
# File lib/highline/style.rb, line 204 def initialize(defn = {}) @definition = defn @name = defn[:name] @code = defn[:code] @rgb = defn[:rgb] @list = defn[:list] @builtin = defn[:builtin] if @rgb hex = self.class.rgb_hex(@rgb) @name ||= "rgb_" + hex elsif @list @name ||= @list end self.class.index self unless defn[:no_index] end
Search for or create a new Style
from the colors provided. @param colors (see .rgb_hex) @return [Style] a Style
with the rgb colors provided. @example Creating a new Style
based on rgb code
rgb_style = HighLine::Style.rgb(9, 10, 11) rgb_style.name # => :rgb_090a0b rgb_style.code # => "\e[38;5;16m" rgb_style.rgb # => [9, 10, 11]
# File lib/highline/style.rb, line 133 def self.rgb(*colors) hex = rgb_hex(*colors) name = ("rgb_" + hex).to_sym style = list[name] return style if style parts = rgb_parts(hex) new(name: name, code: "\e[38;5;#{rgb_number(parts)}m", rgb: parts) end
Converts all given color codes to hexadecimal and join them in a single string. If any given color code is already a String
, doesn't perform any convertion.
@param colors [Array<Numeric, String>] color codes @return [String] all color codes joined @example
HighLine::Style.rgb_hex(9, 10, "11") # => "090a11"
# File lib/highline/style.rb, line 107 def self.rgb_hex(*colors) colors.map do |color| color.is_a?(Numeric) ? format("%02x", color) : color.to_s end.join end
Returns the rgb number to be used as escape code on ANSI terminals. @param parts [Array<Numeric>] three numerical codes for red, green
and blue
@return [Numeric] to be used as escape code on ANSI terminals
# File lib/highline/style.rb, line 147 def self.rgb_number(*parts) parts = parts.flatten 16 + parts.reduce(0) do |kode, part| kode * 6 + (part / 256.0 * 6.0).floor end end
Split an rgb code string into its 3 numerical compounds. @param hex [String] rgb code string like â010F0Fâ @return [Array<Numeric>] numerical compounds like [1, 15, 15] @example
HighLine::Style.rgb_parts("090A0B") # => [9, 10, 11]
# File lib/highline/style.rb, line 119 def self.rgb_parts(hex) hex.scan(/../).map { |part| part.to_i(16) } end
Remove any ANSI color escape sequence of the given String
. @param string [String] @return [String]
# File lib/highline/style.rb, line 182 def self.uncolor(string) string.gsub(/\e\[\d+(;\d+)*m/, "") end
Public Instance Methods
@return [Integer] the BLUE component of the rgb code
# File lib/highline/style.rb, line 261 def blue @rgb && @rgb[2] end
@return [Style] a brighter version of this Style
# File lib/highline/style.rb, line 296 def bright create_bright_variant(:bright) end
@return [Integer] the GREEN component of the rgb code
# File lib/highline/style.rb, line 256 def green @rgb && @rgb[1] end
@return [Style] a lighter version of this Style
# File lib/highline/style.rb, line 301 def light create_bright_variant(:light) end
Uses the color as background and return a new style. @return [Style]
# File lib/highline/style.rb, line 290 def on new_name = ("on_" + @name.to_s).to_sym self.class.list[new_name] ||= variant(new_name, increment: 10) end
@return [Integer] the RED component of the rgb code
# File lib/highline/style.rb, line 251 def red @rgb && @rgb[0] end
@return [Hash] the definition used to create this Style
# File lib/highline/style.rb, line 227 def to_hash @definition end
Duplicate Style
with some minor changes @param new_name [Symbol] @param options [Hash] Style
attributes to be changed @return [Style] new Style
with changed attributes
# File lib/highline/style.rb, line 269 def variant(new_name, options = {}) raise "Cannot create a variant of a style list (#{inspect})" if @list new_code = options[:code] || code if options[:increment] raise "Unexpected code in #{inspect}" unless new_code =~ /^(.*?)(\d+)(.*)/ new_code = Regexp.last_match(1) + (Regexp.last_match(2).to_i + options[:increment]).to_s + Regexp.last_match(3) end new_rgb = options[:rgb] || @rgb self.class.new(to_hash.merge(name: new_name, code: new_code, rgb: new_rgb)) end
Private Instance Methods
# File lib/highline/style.rb, line 307 def create_bright_variant(variant_name) raise "Cannot create a #{name} variant of a style list (#{inspect})" if @list new_name = ("#{variant_name}_" + @name.to_s).to_sym new_rgb = if @rgb == [0, 0, 0] [128, 128, 128] else @rgb.map { |color| color.zero? ? 0 : [color + 128, 255].min } end find_style(new_name) || variant(new_name, increment: 60, rgb: new_rgb) end
# File lib/highline/style.rb, line 321 def find_style(name) self.class.list[name] end