Colorizable
A Raku module for colorizing text using ANSI escape codes.
Synopsis
use Colorizable;
my $string = "Hello" but Colorizable;
given $string {
say .colorize: red; # red text
say .colorize: :fg(red); # same as previous
say .red; # same as previous
say .colorize: red, blue; # red text on blue background
say .colorize: :fg(red), :bg(blue); # same as previous
say .red.on-blue; # same as previous
say .colorize: red, blue, bold; # bold red text on blue background
say .colorize: :fg(red), :bg(blue), :mo(bold); # same as previous
say .red.on-blue.bold; # same as previous
}
Installation
From Raku module ecosystem using zef
:
$ zef install Colorizable
From source code:
$ git clone https://gitlab.com/uzluisf/raku-colorizable.git
$ cd raku-colorizable/
$ zef install .
Description
The module allows to colorize text using ANSI escape code by composing the Colorizable
role into a string. After doing this, the method colorize
can be used to set the text color, background color and text effects (e.g., bold, italic, etc.):
use Colorizable;
my $planet = "Arrakis" but Colorizable;
say $planet.colorize(:fg(blue), :bg(red), :mo(bold));
If composed into a class, Colorizable
assumes the class implements the appropriate Str
method:
use Colorizable;
class A does Colorizable {
}
say A.new.colorize(blue); #=> A<94065101711120>, in blue
class B does Colorizable {
method Str { 'Class B' }
}
say B.new.colorize(blue); #=> class B, in blue
Invocations to the colorize
method are chainable:
use Colorizable;
my $text = "Bold red text on yellow background" but Colorizable;
say $text
.colorize(:fg(red))
.colorize(:bg(yellow))
.colorize(:mo(bold));
Colors and modes can be invoked as methods: .color
for foreground, .on-color
for background, and .mode
for mode given color
and mode
respectively:
use Colorizable;
my $text = "Bold red text on yellow background" but Colorizable;
say $text.red.on-yellow.bold;
To get a list of available colors and modes, use the colors
and modes
methods respectively
Although this might not be advisable, you can make regular strings colorizable by augmenting the Str
class:
use Colorizable;
use MONKEY-TYPING;
# making strings colorizable
augment class Str {
also does Colorizable;
}
say "Bold red text on yellow background"
.colorize(:fg(red))
.colorize(:bg(yellow))
.colorize(:mo(bold));
Note the use of the pragma MONKEY-TYPING
.
Methods
colorize
method colorize($fg, $bg, $mo)
Change color of string.
Examples:
my $str = "Hello" does Colorizable;
say $str.colorize(yellow); # yellow text
say $str.colorize('yellow'); # yellow text
say $str.colorize(blue, red, bold); # bold blue text in red background
Parameters:
$fg
the string's foreground color$bg
the string's background color$mo
the string's mode
colorize
method colorize(:fg(:$foreground), :bg(:$background), :mo(:$mode))
Change color of string.
Examples:
my $str = "Hello" does Colorizable;
say $str.colorize(:fg(yellow)); # yellow text
say $str.colorize(:foreground('yellow')); # yellow text
say $str.colorize(:fg(blue), :bg(red)); # blue text in red background
Parameters:
$fg
the string's foreground color$bg
the string's background color$mo
the string's mode
colors
method colors(--> List)
Return list of available colors as allomorphs. By default, the IntSt
values for the foreground are returned. To return the values for the background, pass the Boolean named argument bg
(or background
).
Examples:
my $str = "Hello" does Colorizable;
say $str.colors.head(3).join(' '); #=> «black red green»
say $str.colors.head(3)».Int.join(' '); #=> «30 31 32»
say $str.colors(:bg).head(3).join(' '); #=> «black red green»
say $str.colors(:bg).head(3)».Int.join(' '); #=> «40 41 42»
modes
method modes( --> List )
Return list of available modes as allomorphs.
Examples:
my $str = "Hello" does Colorizable;
say $str.modes.head(3).join(' '); #=> «default-mode bold italic»
say $str.modes.head(3)».Int.join(' '); #=> «0 1 3»
is-colorized
method is-colorized( --> Bool )
Return true if the string is colorized. Otherwise, false. A string is considered colorized if it has at least one element (foreground, background, or mode) set.
Examples:
my $str = "Hello" does Colorizable;
say $str.is-colorized;
uncolorize
method uncolorize( --> Str )
Return uncolorized string.
Examples:
my $str = "Hello" does Colorizable;
say $str.uncolorize;
color-samples
method color-samples()
Display color samples.
Examples:
my $str = "Hello" does Colorizable;
$str.color-samples; # display color samples
More examples
How to make rainbow-y strings?
An option is to create a subroutine that colorizes a string character by character:
sub rainbow( $str, :@only ) {
sub rainbowize( @colors ) {
$str.comb
.batch(@colors.elems)
.map({($_ Z @colors).map(-> ($ch, $fg) { ($ch does Colorizable).colorize($fg) }).join })
.join
}
return rainbowize(@only) if @only;
return rainbowize Color.enums.keys.list;
}
say rainbow "Hello, World!";
say rainbow "Hello, World!", :only[blue, red, yellow];
Another "I know what I'm doing" alternative is to implement a somewhat similar routine right into the Str
class after composing Colorizable
into it:
use MONKEY-TYPING;
augment class Str {
also does Colorizable;
method rainbow( $str : :@only ) {
sub rainbowize( @colors ) {
$str.comb
.batch(@colors.elems)
.map({($_ Z @colors).map(-> ($ch, $fg) { $ch.colorize($fg) }).join })
.join
}
return rainbowize(@only) if @only;
return rainbowize Color.enums.keys.list;
}
}
say "Hello, World!".rainbow;
say "Hello, World!".rainbow: :only[blue, red, yellow];
Acknowledgement
This module is inspired by Michał Kalbarczyk's Ruby gem colorize.
Authors
Luis F. Uceta
License
You can use and distribute this module under the terms of the The Artistic License 2.0. See the LICENSE file included in this distribution for complete details.
The META6.json file of this distribution may be distributed and modified without restrictions or attribution.