Skip to content

Instantly share code, notes, and snippets.

@mikeharty
Last active October 13, 2023 21:13
Show Gist options
  • Save mikeharty/115619858469433e43f46feac6ad8264 to your computer and use it in GitHub Desktop.
Save mikeharty/115619858469433e43f46feac6ad8264 to your computer and use it in GitHub Desktop.
Clrzr.rb
# == Clrzr
# A static class for colorizing terminal output
# in Ruby scripts. I was learning Ruby ¯\_(ツ)_/¯
class Clrzr
private_class_method :new
class << self
CLR = {
:black => 30,
:bright_black => 90,
:red => 31,
:bright_red => 91,
:green => 32,
:bright_green => 92,
:yellow => 33,
:bright_yellow => 93,
:blue => 34,
:bright_blue => 94,
:magenta => 35,
:bright_magenta => 95,
:cyan => 36,
:bright_cyan => 96,
:white => 37,
:bright_white => 97
}.freeze
FMT = {
:reset => 0,
:bold => 1,
:italic => 3,
:underline => 4,
:strike => 9,
:blink => 5,
:invert => 7
}.freeze
def self.make_method(color)
# Colorizes the given string with the given color
# @example Clrzr.red('my string')
# @param [String] The string to colorize
# @param [Hash] The options to colorize with
# @return [String] A reusable Proc that will colorize a string
# @note This can be chained, but better to use Clrzr.custom
lambda { |string = nil, opts = {}|
return _colorize_string(string, { color: color }.merge(opts)) unless string.nil?
return custom({ color: color }.merge(opts))
}
end
define_method(:black, make_method(:black))
define_method(:blue, make_method(:blue))
define_method(:cyan, make_method(:cyan))
define_method(:green, make_method(:green))
define_method(:red, make_method(:red))
define_method(:yellow, make_method(:yellow))
define_method(:magenta, make_method(:magenta))
define_method(:white, make_method(:white))
define_method(:bright_black, make_method(:bright_black))
define_method(:bright_blue, make_method(:bright_blue))
define_method(:bright_cyan, make_method(:bright_cyan))
define_method(:bright_green, make_method(:bright_green))
define_method(:bright_red, make_method(:bright_red))
define_method(:bright_yellow, make_method(:bright_yellow))
define_method(:bright_magenta, make_method(:bright_magenta))
define_method(:bright_white, make_method(:bright_white))
def _colorize_string(input, opts = {})
cvt = ->(c, k) { (c.is_a?(::Integer) && "38;5;#{opts[k]}") || (c.is_a?(::Symbol) && CLR[opts[k]]) || nil }
codes = []
codes << cvt[opts[:color], :color] if opts[:color]
codes << cvt[opts[:bg], :bg] if opts[:bg]
codes << FMT[:bold] if opts[:bold]
codes << FMT[:italic] if opts[:italic]
codes << FMT[:underline] if opts[:underline]
codes << FMT[:strike] if opts[:strike]
codes << FMT[:invert] if opts[:invert]
codes = codes.length > 1 ? codes.join(';') : codes[0]
"\e[#{codes}m#{input}\e[0m"
end
# Generates a Proc that will colorize a string with the given options.
# @example myClr = Clrzr.custom({ color: 210, bg: 130, bold: true })
# @example myClr['my string']
# Colors are restored to defaults after every string
# @param opts [Hash] the options to create a message with
# @option opts [Symbol|Integer] :color Symbol or 8-bit Integer
# @option opts [Symbol|Integer] :bg Background color
# @option opts [Boolean] :bold Bold the string
# @option opts [Boolean] :italic Italicize the string
# @option opts [Boolean] :underline Underline the string
# @option opts [Boolean] :strike Strike the string
# @option opts [Boolean] :invert Invert the bg/fg
# @return [Proc<String>] A reusable Proc that will colorize a string
# @note with a Proc, square brackets are required!
def custom(opts = {}, **kwargs)
lambda { |string|
opts.merge(kwargs) unless kwargs.nil?
return _colorize_string(string, opts) unless string.nil?
}
end
def log_colors_table
puts four_bit_colors
puts eight_bit_colors
end
def four_bit_colors
puts "\n4 bit colors:\n"
CLR.each do |color, _|
r = ''
r += _colorize_string(CLR[color].to_s.center(4), { color: color, invert: true }).ljust(8)
r += ' '
r += _colorize_string(color.to_s.gsub('_', ' ').ljust(18), { color: color })
r += _colorize_string(' inverted '.center(12), { color: color, invert: true })
r += _colorize_string('bolded'.center(10), { color: color, bold: true })
r += _colorize_string('italicized'.ljust(12), { color: color, italic: true })
r += _colorize_string('underlined', { color: color, underline: true }).ljust(18)
r += _colorize_string('stricken'.ljust(10), { color: color, stike: true })
puts "#{r}\n"
end
puts "\nUse with Clrzr or directly use escape codes: \\e[\{code};7m\n"
end
def eight_bit_colors
c = 0
puts "8 bit colors:\n"
8.times.each do |r|
row = ''
cols = [0, 7].include?(r) ? 16 : 36
cols += 8 if r == 7
cols.times do
txt = c.to_s.rjust(4)
row += _colorize_string(txt, { color: c, invert: true })
row += ' ' if ((c - 15) % 6).zero? && r.between?(1, 6)
c += 1
end
puts "\n" if r == 7
puts row
puts "\n" if [0, 7].include? r
end
puts "Use with Clrzr or directly use escape codes: \\e[38;5;\#{code};7m\n\n"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment