Skip to content

Colorizing with true color #66

@globewalldesk

Description

@globewalldesk

Most modern terminals support true color with full RGB values ($COLORTERM == ‘truecolor’). I made an app that color-codes different programming languages, and when I started running out of Colorize's 16 colors, I looked around and discovered that there was a surprisingly simple way to colorize text and background--see below, String#color_text and String#color_bg.

Then I discovered that there are a few basic terminals that don't have $COLORTERM == ‘truecolor’, so I made my code (which had used Colorize) backwards-compatible with Colorize; I wrote my own String#colorize method. And then I decided to make that method work regardless of whether a console had $COLORTERM true or not. See below.

If Colorize incorporated this more advanced colorization, that would be awesome. Any interest?

module Colorize::InstanceMethods
  alias :old_colorize :colorize
end

class String
  def color_text(r, g, b)
    "\033[38;2;#{r};#{g};#{b}m#{self}\u001b[0m"
  end

  def color_bg(r, g, b)
    "\033[48;2;#{r};#{g};#{b}m#{self}\u001b[0m"
  end

  # Takes symbol with English color name, returns colored string.
  # Examples: "foo".colorize(:red) => returns red string.
  #           "foo".colorize(background: :blue) => returns blue background string.
  def colorize(color)
    if ENV["COLORTERM"]
      color.class == Symbol ?
        self.color_text(*RGB_CODES[color]) :
        self.color_bg(*RGB_CODES[color[:background]])
    else
      if color.class == Symbol
        color = COLOR_MAPPER.has_key?(color) ? COLOR_MAPPER[color] : color
        self.old_colorize(color)
      else
        color[:background] = COLOR_MAPPER.has_key?(color[:background]) ?
          COLOR_MAPPER[color[:background]] : color[:background]
        self.old_colorize(color)
      end
    end
  end

  RGB_CODES = {
    # Original "Colorize" gem colors, for backwards-compatibility.
    black:  [46, 52, 54],
    red:    [204, 0, 0],
    green:  [78, 154, 6],
    yellow: [205, 176, 48],
    blue:   [52, 101, 164],
    magenta:[117, 80, 123],
    cyan:   [6, 152, 154],
    white:  [211, 215, 207],
    light_black:  [85, 87, 83],
    light_red:    [239, 41, 41],
    light_green:  [158, 229, 90],
    light_yellow: [252, 233, 79],
    light_blue:   [114, 159, 207],
    light_magenta:[173, 127, 168],
    light_cyan:   [52, 226, 226],
    light_white:  [238, 238, 236],
    # New colors.
    free_speech_red:[169, 16, 0],     # Ruby
    festival:       [233, 212, 77],   # JavaScript
    denim:          [27, 132, 193],   # CSS
    tahiti_gold:    [233, 98, 40],    # HTML
    chateau_green:  [69, 181, 80],    # Bash
    malibu:         [93, 164, 221],   # SQL/PSQL
    echo_blue:      [163, 179, 198],  # C
    med_aquamarine: [98, 202, 175],   # C++
    carrot_orange:  [240, 148, 33],   # Java
    saffron:        [247, 191, 48],   # Python
    brown:          [165, 42, 42]     # Rust
  }

  # Mapping new color names to old names for use by Colorize gem.
  COLOR_MAPPER = {
    free_speech_red:  :red,           # Ruby
    festival:         :light_yellow,  # JavaScript
    denim:            :blue,          # CSS
    tahiti_gold:      :light_red,     # HTML
    chateau_green:    :white,         # Bash
    malibu:           :cyan,          # SQL/PSQL
    echo_blue:        :light_blue,    # C
    med_aquamarine:   :blue,          # C++
    carrot_orange:    :magenta,       # Java
    saffron:          :yellow,        # Python
    brown:            :red            # Rust
  }
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions