Class: HighLine::Style

Inherits:
Object show all
Defined in:
lib/highline/style.rb

Overview

ANSI styles to be used by HighLine.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(defn = {}) ⇒ Style

Single color/styles have :name, :code, :rgb (possibly), :builtin Compound styles have :name, :list, :builtin

Parameters:

  • defn (Hash) (defaults to: {})

    options for the Style to be created.



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# 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

Instance Attribute Details

#builtinBoolean

Returns true if the Style is builtin or not.

Returns:

  • (Boolean)

    true if the Style is builtin or not.



198
199
200
# File 'lib/highline/style.rb', line 198

def builtin
  @builtin
end

#listArray<Symbol> (readonly)

When a compound Style, returns a list of its components.

Returns:

  • (Array<Symbol>)

    components of a Style list



192
193
194
# File 'lib/highline/style.rb', line 192

def list
  @list
end

#nameSymbol (readonly)

Style name

Returns:

  • (Symbol)

    the name of the Style



188
189
190
# File 'lib/highline/style.rb', line 188

def name
  @name
end

#rgbArray

Returns the three numerical rgb codes. Ex: [10, 12, 127].

Returns:

  • (Array)

    the three numerical rgb codes. Ex: [10, 12, 127]



195
196
197
# File 'lib/highline/style.rb', line 195

def rgb
  @rgb
end

Class Method Details

.ansi_rgb_to_hex(ansi_number) ⇒ String

From an ANSI number (color escape code), craft an ‘rgb_hex’ code of it

Parameters:

  • ansi_number (Integer)

    ANSI escape code

Returns:



157
158
159
160
161
162
163
164
165
166
167
# 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_indexvoid

This method returns an undefined value.

Clear all custom Styles, restoring the Style index to builtin styles only.



92
93
94
95
96
97
# 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

.code_indexHash

Returns list of all cached Style codes.

Returns:

  • (Hash)

    list of all cached Style codes



175
176
177
# File 'lib/highline/style.rb', line 175

def self.code_index
  @code_index ||= {}
end

.index(style) ⇒ Style

Index the given style. Uses @code_index (Hash) as repository.

Parameters:

Returns:

  • (Style)

    the given style



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 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

.listHash

Returns list of all cached Styles.

Returns:

  • (Hash)

    list of all cached Styles



170
171
172
# File 'lib/highline/style.rb', line 170

def self.list
  @styles ||= {}
end

.rgb(*colors) ⇒ Style

Search for or create a new Style from the colors provided.

Examples:

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]

Parameters:

  • colors (Array<Numeric, String>)

    color codes

Returns:

  • (Style)

    a Style with the rgb colors provided.



133
134
135
136
137
138
139
140
141
# 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

.rgb_hex(*colors) ⇒ String

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.

Examples:

HighLine::Style.rgb_hex(9, 10, "11") # => "090a11"

Parameters:

  • colors (Array<Numeric, String>)

    color codes

Returns:

  • (String)

    all color codes joined



107
108
109
110
111
# 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

.rgb_number(*parts) ⇒ Numeric

Returns the rgb number to be used as escape code on ANSI terminals.

Parameters:

  • parts (Array<Numeric>)

    three numerical codes for red, green and blue

Returns:

  • (Numeric)

    to be used as escape code on ANSI terminals



147
148
149
150
151
152
# 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

.rgb_parts(hex) ⇒ Array<Numeric>

Split an rgb code string into its 3 numerical compounds.

Examples:

HighLine::Style.rgb_parts("090A0B") # => [9, 10, 11]

Parameters:

  • hex (String)

    rgb code string like “010F0F”

Returns:

  • (Array<Numeric>)

    numerical compounds like [1, 15, 15]



119
120
121
# File 'lib/highline/style.rb', line 119

def self.rgb_parts(hex)
  hex.scan(/../).map { |part| part.to_i(16) }
end

.uncolor(string) ⇒ String

Remove any ANSI color escape sequence of the given String.

Parameters:

Returns:



182
183
184
# File 'lib/highline/style.rb', line 182

def self.uncolor(string)
  string.gsub(/\e\[\d+(;\d+)*m/, "")
end

Instance Method Details

#blueInteger

Returns the BLUE component of the rgb code.

Returns:

  • (Integer)

    the BLUE component of the rgb code



261
262
263
# File 'lib/highline/style.rb', line 261

def blue
  @rgb && @rgb[2]
end

#brightStyle

Returns a brighter version of this Style.

Returns:

  • (Style)

    a brighter version of this Style



296
297
298
# File 'lib/highline/style.rb', line 296

def bright
  create_bright_variant(:bright)
end

#codeString

Returns:

  • (String)

    all codes of the Style list joined together (if a Style list)

  • (String)

    the Style code



242
243
244
245
246
247
248
# File 'lib/highline/style.rb', line 242

def code
  if @list
    @list.map { |element| HighLine.Style(element).code }.join
  else
    @code
  end
end

#color(string) ⇒ String

Uses the Style definition to add ANSI color escape codes to a a given String

Parameters:

  • string (String)

    to be colored

Returns:

  • (String)

    an ANSI colored string



235
236
237
# File 'lib/highline/style.rb', line 235

def color(string)
  code + string + HighLine::CLEAR
end

#dupStyle

Duplicate current Style using the same definition used to create it.

Returns:

  • (Style)

    duplicated Style



222
223
224
# File 'lib/highline/style.rb', line 222

def dup
  self.class.new(@definition)
end

#greenInteger

Returns the GREEN component of the rgb code.

Returns:

  • (Integer)

    the GREEN component of the rgb code



256
257
258
# File 'lib/highline/style.rb', line 256

def green
  @rgb && @rgb[1]
end

#lightStyle

Returns a lighter version of this Style.

Returns:

  • (Style)

    a lighter version of this Style



301
302
303
# File 'lib/highline/style.rb', line 301

def light
  create_bright_variant(:light)
end

#onStyle

Uses the color as background and return a new style.

Returns:



290
291
292
293
# 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

#redInteger

Returns the RED component of the rgb code.

Returns:

  • (Integer)

    the RED component of the rgb code



251
252
253
# File 'lib/highline/style.rb', line 251

def red
  @rgb && @rgb[0]
end

#to_hashHash

Returns the definition used to create this Style.

Returns:

  • (Hash)

    the definition used to create this Style



227
228
229
# File 'lib/highline/style.rb', line 227

def to_hash
  @definition
end

#variant(new_name, options = {}) ⇒ Style

Duplicate Style with some minor changes

Parameters:

  • new_name (Symbol)
  • options (Hash) (defaults to: {})

    Style attributes to be changed

Returns:

  • (Style)

    new Style with changed attributes



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# 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