Changing Text Color

Problem

You want to display multicolored text on the console.

Solution

The simplest solution is to use HighLine. It lets you enclose color commands in an ERb template that gets interpreted within HighLine and printed to standard output. Try this colorful bit of code to test the capabilities of your terminal:

	require 
ubygems
	require highline/import

	say(%{Heres some <%= color(dark red text, RED) %>.})
	say(%{Heres some <%= color(right red text on a blue background,
	 RED+BOLD+ON_BLUE) %>.})
	say(%{Heres some <%= 
color(linking bright cyan 
text, CYAN+BOLD+BLINK) %>.})
	say(%{Heres some <%= GREEN+UNDERLINE %>underlined dark green text<%=CLEAR%>.})

Some of these features (particularly the blinking and underlining) aren supported on all terminals.

Discussion

The HighLine#color method encloses a display string in special command strings, which start with an escape character and a left square bracket:

	HighLine.new.color(Hello, HighLine::GREEN)
	# => "e[32mHelloe[0m"

These are ANSI escape sequences. Instead of displaying the string "e[32m", an ANSI-compatible terminal treats it as a command: in this case, a command to start printing characters in green-on-black. The string "e[0m" tells the terminal to go back to white-on-black.

Most modern Unix terminals support ANSI escape sequences, including the Mac OS X terminal. You should be able to get green text in your irb session just by calling puts "e[32mHelloe[0m" (try it!), but HighLine makes it easy to get color without having to remember the ANSI sequences.

Windows terminals don support ANSI by default, but you can get it to work by loading ANSI.SYS (see below for a relevant Microsoft support article).

An alternative to HighLine is the Ncurses library.[4] It supports color terminals that use a means other than ANSI, but these days, most color terminals get their color support through ANSI. Since Ncurses is much more complex than HighLine, and not available as a gem, you should only use Ncurses for color if you e already using it for its other features.

[4] Standard Curses doesn support color because it was written in the 1980s, when monochrome ruled the world.

Heres a rough equivalent of the HighLine program given above. This program uses the Ncurses::program wrapper described in Recipe 21.5. The wrapper sets up Ncurses and initializes some default color pairs:

	Ncurses.program do |s|
	 # Define the red-on-blue color pair used in the second string.
	 # All the default color pairs use a black background.
	 Ncurses.init_pair(8, Ncurses::COLOR_RED, Ncurses::COLOR_BLUE)

	 Ncurses::attrset(Ncurses::COLOR_PAIR(1))
	 s.mvaddstr(0,0, "Heres some dark red text.")

	 Ncurses::attrset(Ncurses::COLOR_PAIR(8) | Ncurses::A_BOLD)
	 s.mvaddstr(1,0, "Heres some bright red text on a blue background.")
	 Ncurses::attrset(Ncurses:: 
COLOR_PAIR(6) | Ncurses::A_BOLD |
	 Ncurses::A_BLINK)
	 s.mvaddstr(2,0, "Heres some blinking bright cyan 
text.")

	 Ncurses::attrset(Ncurses::COLOR_PAIR(2) | Ncurses::A_UNDERLINE)
	 s.mvaddstr(3,0, "Heres some underlined dark green text.")

	 s.getch
	end

An Ncurses program can draw from a palette of color pairscombinations of foreground and background colors. Ncurses::program sets up a default palette of the seven basic ncurses colors (red, green, yellow, blue, magenta, cyan, and white), each on a black background. You can change this around if you like, or define additional color pairs (like the red-on-blue defined in the example). The following Ncurses program prints out a color chart of all foreground-background pairs. It makes the text of the chart bold, so that the text doesn become invisible when the background is the same color.

	Ncurses.program do |s|
	 pair = 0
	 Ncurses::COLORS.each_with_index do |background, i|
	 Ncurses::COLORS.each_with_index do |foreground, j|
	 Ncurses::init_pair(pair, foreground, background) unless pair == 0
	 Ncurses::attrset(Ncurses::COLOR_PAIR(pair) | Ncurses::A_BOLD)
	 s.mvaddstr(i, j*4, "#{foreground},#{background}")
	 pair += 1
	 end
	 end
	 s.getch
	end

You can modify a color pair by combining it with an Ncurses constant. The most useful constants are Ncurses::A_BOLD, Ncurses::A_BLINK, and Ncurses::A_UNDERLINE. This works the same way (and, on an ANSI system, uses the same ANSI codes) as HighLines BOLD, BLINK, and UNDERLINE constants. The only difference is that you modify an Ncurses color with the OR operator (|), and you modify a HighLine color with the addition operator.

See Also

  • Recipe 1.3, "Substituting Variables into an Existing String," has more on ERb
  • http://en.wikipedia.org/wiki/ANSI_escape_code has technical details on ANSI color codes
  • The examples/ansi_colors.rb file in the HighLine gem
  • You can get a set of Ncurses bindings for Ruby at http://ncurses-ruby.berlios.de/; its also available as the Debian package libncurses-ruby
  • If you want something more lightweight than the highline gem, try the termansicolor gem instead: it defines methods for generating the escape sequences for ANSI colors, and nothing else
  • "How to Enable ANSI.SYS in a Command Window" (http://support.microsoft.com/?id=101875)


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net