Formatting (ANSI) highlighted strings

G

Gavin Sinclair

Hi folks,

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?

Thanks,
Gavin
 
J

Josef 'Jupp' Schugt

* 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
 
A

Andrew Walrond

Hi Gavin,

Using the 'text/highlight' package on RubyForge, you can emit coloured

I would like to use this package in my rubyx linux distro to replace my own
clunky text colorisation in the init system. I wondered however if you would
accept a small change to your install script which implements the standard
DESTDIR functionality. Something like this...

dest = (ENV['DESTDIR'] ? ENV['DESTDIR']+'/' : '')+"#{sitedir}/#{version}/

Andrew Walrond
 
J

Jeff Pace

[...] I wondered however if you would
accept a small change to your install script which implements the
standard DESTDIR functionality. Something like this...
dest = (ENV['DESTDIR'] ? ENV['DESTDIR']+'/' :
'')+"#{sitedir}/#{version}/

Thanks for the suggestion. This has been released as version 1.0.2.


--Jeff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top