Josef 'Jupp' Schugt
10/28/2003 8:50:00 PM
* Gavin Sinclair; Tue, 28 Oct 2003 17:32:13 +0900
[Report on
> Using the 'text/highlight' package on RubyForge, you can emit
> coloured strings to the console like so:
>
> s = "string".bold.red.on_white
>
> Great. Now if I want to format that using:
>
> printf "%-10s goes here\n", s
>
> I'm not going to get (in B&W)
>
> string goes here
>
> Rather
>
> string goes here
>
> Because
>
> s.size > 10 # It contains escape sequences to enact colours.
>
> even though it only contains 6 printable characters.
> So, I don't think there's any way I can use printf to do this kind of
> formatting (modifying s.size doesn't change anything).
>
> Does anyone have any alternative, or a bright idea?
All the ECMA-48 Set Graphics Rendition control codes (that's their
official name) follow this scheme:
ESC [ parameters m
The parameters are semicolon separated numbers. They can be removed
by using
gsub(/\033\[[\d;]*m/, "")
More complex solution:
require 'my_highlight'
s = ANSI_string.new("string").black.on_cyan.blink
puts s
puts s.mono
puts s.text
printf "%-10s goes here\n", s.text
with 'my_highlight' containing the code given below. Wonder why I did
use delegate? If you *inherit* from String 'to_s' is not used for
implicit convertion so that the colors are absent.
'mono' only uses non-color codes.
require 'delegate'
class ANSI_string < DelegateClass(String)
def initialize(text)
@blink = false
@bold = false
@concealed = false
@half_bright = false
@italic = false
@rapid_blink = false
@reverse_video = false
@underline = false
@fg = ''
@bg = ''
@text = String.new(text)
super(@text)
end
def black; @fg = 'black'; self; end
def blue; @fg = 'blue'; self; end
def brown; @fg = 'brown'; self; end
def cyan; @fg = 'cyan'; self; end
def green; @fg = 'green'; self; end
def magenta; @fg = 'magenta'; self; end
def red; @fg = 'red'; self; end
def white; @fg = 'white'; self; end
def on_black; @bg = 'black'; self; end
def on_blue; @bg = 'blue'; self; end
def on_brown; @bg = 'brown'; self; end
def on_cyan; @bg = 'cyan'; self; end
def on_green; @bg = 'green'; self; end
def on_magenta; @bg = 'magenta'; self; end
def on_red; @bg = 'red'; self; end
def on_white; @bg = 'white'; self; end
def blink; @blink = true; self; end
def bold; @bold = true; self; end
def concealed; @concealed = true; self; end
def halb_bright; @half_bright = true; self; end
def italic; @italic = true; self; end
def rapid_blink; @blink = true; self; end
def reverse_video; @reverse_video = true; self; end
def strikethrough; @reverse_video = true; self; end
def underline; @underline = true; self; end
def no_blink; @blink = false; self; end
def no_bold; @bold = false; self; end
def no_concealed; @concealed = false; self; end
def no_halb_bright; @half_bright = false; self; end
def no_italic; @italic = false; self; end
def no_rapid_blink; @blink = false; self; end
def no_reverse_video; @reverse_video = false; self; end
def no_strikethrough; @reverse_video = false; self; end
def no_underline; @underline = false; self; end
def reset_all
reset_attributes
reset_colors
end
def reset_attributes
no_blink
no_bold
no_concealed
no_halb_bright
no_italic
no_rapid_blink
no_reverse_video
no_strikethrough
no_underline
end
def reset_colors
reset_fg
reset_bg
end
def reset_fg
@fg = ''
end
def reset_bg
@bg = ''
end
def to_s
s = mono
s = case @bg
when 'black' then "\033[40m#{s}\033[49m"
when 'blue' then "\033[44m#{s}\033[49m"
when 'brown' then "\033[43m#{s}\033[49m"
when 'cyan' then "\033[46m#{s}\033[49m"
when 'green' then "\033[42m#{s}\033[49m"
when 'magenta' then "\033[45m#{s}\033[49m"
when 'red' then "\033[41m#{s}\033[49m"
when 'white' then "\033[47m#{s}\033[49m"
else s
end
s = case @fg
when 'black' then "\033[30m#{s}\033[39m"
when 'blue' then "\033[34m#{s}\033[39m"
when 'brown' then "\033[33m#{s}\033[39m"
when 'cyan' then "\033[36m#{s}\033[39m"
when 'green' then "\033[32m#{s}\033[39m"
when 'magenta' then "\033[35m#{s}\033[39m"
when 'red' then "\033[31m#{s}\033[39m"
when 'white' then "\033[37m#{s}\033[39m"
else s
end
end
def mono
s = text
s = "\033[5m#{s}\033[25m" if @blink
s = "\033[1m#{s}\033[22m" if @bold
s = "\033[8m#{s}\033[28m" if @concealed
s = "\033[2m#{s}\033[22m" if @half_bright
s = "\033[3m#{s}\033[23m" if @italic
s = "\033[6m#{s}\033[26m" if @rapid_blink
s = "\033[7m#{s}\033[27m" if @reverse_video
s = "\033[9m#{s}\033[29m" if @strikethrough
s = "\033[4m#{s}\033[24m" if @underline
s
end
def text
@text
end
end
Josef 'Jupp' Schugt