[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Formatting (ANSI) highlighted strings

Gavin Sinclair

10/28/2003 8:32:00 AM

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


4 Answers

Josef 'Jupp' Schugt

10/28/2003 8:50:00 PM

0

* 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

Andrew Walrond

11/3/2003 4:02:00 PM

0

Hi Gavin,

On Tuesday 28 Oct 2003 8:32 am, Gavin Sinclair wrote:
>
> 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


Jeff Pace

11/3/2003 4:25:00 PM

0

On Tue, 4 Nov 2003 01:01:46 +0900
Andrew Walrond <andrew@walrond.org> wrote:

> [...] 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

--
Jeff Pace / jpace@incava.org

Andrew Walrond

11/3/2003 6:31:00 PM

0

On Monday 03 Nov 2003 4:24 pm, Jeff Pace wrote:
>
> Thanks for the suggestion. This has been released as version 1.0.2.
>

Excellent! I'll add the package to rubyx now.