Ruby goes 256-color in xterm

Posted by Daniel Butler Sat, 15 Apr 2006 14:17:00 GMT

Two-hundred and fifty six colors in your Unix terminal, you ask? Yes, it’s possible, but 256-color support isn’t very common among the terminal emulators out there (Konsole and Gnome-Terminal don’t support it yet). And elinks is the only program I know of that supports 256 colors natively. So, here’s a little Ruby program that generates 256-color color cubes in Ruby. I’ve translated it from a Perl script, so it’s not very ruby-like, but it makes pretty pictures.

The source code follows.

#!/usr/bin/env ruby

class ColorDemo

  ColorString = "##"
  ColorMode = {'fg' => '38', 'bg' => '48'}

  def show_welcome 
    puts <<-END
+----------------------------------------------------------------------------+
| This program shows 256-color support in xterm-compliant terminals. You may |
| notice some flickering while the color codes are mapped in your terminal.  |
| Please resize your terminal to at least the width of this box. Try this:   |
| xterm -fg beige -bg midnightblue -fa "antialias=true:rgba=0:pixelsize=18"  |
+-------------+--------------------------------------------------------------+
| Color Range | Description                                                  |
+-------------+--------------------------------------------------------------+
|  000 - 015  | Standard ANSI colors, but with more pleasing shades          |
|  016 - 231  | 6x6x6 color cube                                             |
|  232 - 255  | Greyscale ramp, with black and white intentionally omitted   |
+-------------+--------------------------------------------------------------|
| Translation: 256colors.rb by Daniel Butler <yup.com@gmail.com>  2005-10-30 |
| Original: 256colors2.pl by Todd Larason <jtl@molehill.org> v1.1 1999-07-11 |
+----------------------------------------------------------------------------+
  END
  end

  def clear_screen
    system("clear")
  end

  def loop_color_cube(mode = nil)
    (0...6).each do |red|
      (0...6).each do |green|
        (0...6).each do |blue|
          yield red, green, blue
        end
        print nocolor(" ") if mode == :cube
      end
      print "\n" if mode == :cube
    end  
  end

  def setup_color_cube_color
    # Colors 16-231 are a 6x6x6 color cube
    loop_color_cube do |red, green, blue|
      printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\",
        16 + (red * 36) + (green * 6) + blue,
        (red * 42.5).to_i,
        (green * 42.5).to_i,
        (blue * 42.5).to_i)
    end  
  end

  def setup_color_cube_gray
    # Colors 232-255 are a grayscale ramp, intentionally
    # leaving out black and white
    (0...24).each do |gray|
      level = (gray * 10) + 8
      printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\",
        232 + gray, level, level, level);
    end
  end

  def colorize(color, text, mode)
    "\x1b[#{ColorMode[mode]};5;#{color}m#{text}"
  end

  def nocolor(text)
    "\x1b[0m#{text}"
  end

  def display_system_colors(mode)
    puts "System colors (#{mode}):"
    (0...16).each do |color|
      print colorize(color, ColorString, mode)
      print nocolor("\n") if [7, 15].include? color
    end
  end

  def display_color_cube(mode)
    puts "Color cube, 6x6x6 (#{mode}):"
    loop_color_cube(:cube) do |red, green, blue| 
      print colorize(16 + (red * 36) + 
        (green * 6) + blue, ColorString, mode)
    end
  end

  def display_grayscale_ramp(mode)
    puts "Grayscale ramp (#{mode}):"
    (232...256).each do |color|
      print colorize(color, ColorString, mode)
    end
    print nocolor("\n")
  end

  def go
    clear_screen
    show_welcome
    setup_color_cube_color
    setup_color_cube_gray
    ['fg', 'bg'].each do |mode|
      display_system_colors(mode)
      display_color_cube(mode)
      display_grayscale_ramp(mode)
    end
  end
end

demo = ColorDemo.new
demo.go

I use KDE’s Konsole most of the time, but it sorely lacks 256 color support, so if you’re interested, register on the KDE bugs systems and vote for bug 107487. Neat-o command line wrappers which colorize program output like cwrapper could visually benefit from additional color support, as well as console-based text editors with syntax highlighting.

Incidently, the excellent Window-based terminal emulator, Putty supports 256-colors quite nicely.

Original Perl Source Code
The 256 Color Mode of xterm

Posted in ,  | 5 comments

Sponsored Links

Sponsored Links

Comments

  1. Avatar Sebastian said 9 days later:

    Putty is also available for unix and pterm (based on putty’s sources) is a rather nice terminal emulator with 256 colours support.

  2. Avatar PlasmaHH said 45 days later:

    Hi,

    not only elinks, but editors like vim and emacs support 256 colors too. And for syntax highlighting, it seems to be quite important for lots of people to have 256 colors to choose among. Unfortunately it looks like noone of the developers of e.g. konsole cares. I wonder if this is because of that demanding customers get tired of beeing ignored ;)

  3. Avatar Anon said 46 days later:

    gnome-terminal supports 256 colors, the support has been in CVS for a few months, it will be out whenever the next release is made.

  4. Avatar Michael Pyne said 79 days later:

    Konsole now supports 256 colors as well, and will be in KDE 3.5.4 and 4.0.

  5. Avatar Brian Pence said 492 days later:

    256-color terminal for Windows

    If you need a windows terminal client that supports the xterm 256 color mode, try AbsoluteTelnet from Celestial Software. You can download it here: AbsoluteTelnet In addition to the 256-color xterm, it supports ssh, telnet, dialup and direct serial terminal emulation. Lots of emulation types, character set translations, and the GUI is translated into 7 different languages you can choose from at install time.

(leave url/email »)

   Comment Markup Help Preview comment