Text::Highlight

This module highlights text for display on terminals (using ANSI escape sequences) and for rendering in HTML.

Synopsis

require 'text/highlight'
hl = Text::HTMLHighlighter.new
String.highlighter = hl
puts "hello, world".blue                        => hello, world
puts hl.blue + hl.on_yellow + "hey!" + hl.reset => hey!
puts hl.bold { "To boldly go ... " }            => To boldly go ... 
puts "Ruby rocks!".bold.red                     => Ruby rocks!

Description

This module consists of:

Among other usages, it can spice up logging output, such as:

require 'log'

Log.verbose = true
Log.set_widths(-10, 5, -15)
Log.highlighter = Text::HTMLHighlighter.new
Log.set_color(Log::DEBUG, "blue")
Log.set_color(Log::INFO,  "bold")
Log.set_color(Log::WARN,  "magenta")
Log.set_color(Log::ERROR, "bold green")
Log.set_color(Log::FATAL, "underline bold white on red")

# later ...

class Core
  include Loggable

  def monitor
    (0 .. 2).each do 
      debug "things progressing nicely"
    end

    info  "hmm. odd occurrence in section 7G"

    warn  "surface temperature now at 200 degrees"

    error "core melting"
    
    fatal "no more doughnuts!"
  end

end

This produces:

% ~/tmp/gaudlog.rb
[gaudlog.rb:   22] {Core#monitor   } things progressing nicely
[gaudlog.rb:   22] {Core#monitor   } things progressing nicely
[gaudlog.rb:   22] {Core#monitor   } things progressing nicely
[gaudlog.rb:   25] {Core#monitor   } hmm. odd occurrence in section 7G
[gaudlog.rb:   27] {Core#monitor   } surface temperature now at 200 degrees
[gaudlog.rb:   29] {Core#monitor   } core melting
[gaudlog.rb:   31] {Core#monitor   } no more doughnuts!

This is using my not-yet-released log class, which is still in pre-alpha stage, mainly awaiting a not-yet-used name.

Usage

There are three modes: ANSI, HTML, and NONE.

ANSI highlights text appropriately for terminals that support ANSI escape sequences. I've tested this mainly with xterm. See perldoc Term::ANSIColor for a list of the terminals that are supported by ANSI color.

HTML highlights text for displaying in HTML.

NONE does no highlighting. So why does this exist? Because this is the default highlighter included by the extended String class.

Common Usage

As method invocations on a highlighter instance, with the reset method producing the code to end the highlighting:

hl = Text::HTMLHighlighter.new
puts hl.blue + "This is blue" + hl.reset

Blocks can be used, and reset is implicitly called for the end of the block. The following produces the same result as the previous example:

hl = Text::HTMLHighlighter.new
puts hl.blue { "This is blue" }

By loading the highlight module, the built-in String class is extended with the String#highlighter= method, which assigns a highlighter to be used for calls on strings:

String.highlighter = Text::HTMLHighlighter.new
puts "This is blue".blue

As with the block functionality, reset is implicitly invoked at end of the given string.

Formatting

It was recently mentioned that ANSI highlighted strings don't work well with the printf functions; since the nonprintable (control) characters are counted, the format breaks. For example, this doesn't work as expected, since "string".bold.red is actually 23 characters long:

s = "string".bold.red
printf "<<%-10s>>", s                            =>"<<string>>", not the expected "<<string    >>"

A simple solution was offered:

s = "string".ljust(10).bold.red
printf "<<%s>>", s                               => "<<string    >>"

This will work except for where spaces are effected, such as with reverse (negative):

s = "string".ljust(10).negative
printf "<<%s>>", s                               => "<<string    >>"

For this case, I suggest using the %* format, using the number of characters desired minus the length of the nonprintable characters, which is obtained easily by "highlighting" an empty string, for the purpose of counting its characters:

s = "string".negative    # no ljust
printf "<<%-*s>>", 10 + "".negative.length, s    => "<<string    >>"

Or, using ljust:

s  = "string".negative
s1 = s.ljust(10 + "".negative.length)
printf "<<%s>>", s1                              => "<<string    >>"

Download

The highlighting code is available here.

About

Written by Jeff Pace (jpace at incava dot org), based on the Perl Term::ANSIColor package, and inspired by Florian Frank's ansicolor.

Last modified: Tue Jan 6 23:19:52 EST 2004