txt: ## dist_cpan-UZLUISF-Colorizable.md
  # 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](https://modules.raku.org/) 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`](https://docs.raku.org/language/pragmas#index-entry-MONKEY-TYPING__pragma).
  
  ## 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](https://github.com/fazibear)'s Ruby gem [colorize](https://github.com/fazibear/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.
  