iyi

Standard library, 0.18.0

std/colorize

Terminal colour and style: "text".colorize.red.on_blue.bold is the text wrapped in the ANSI SGR escape that paints it, and back to plain text with \e[0m. Sixteen named colours (ColorANSI), the 256-colour palette (Color256, fore(200_u8)), 24-bit RGB (ColorRGB, fore(r, g, b)), and one style slot (Mode: bold, dim, underline, blink, reverse, hidden — the last one asked for wins, and bright is bold).

import std/colorize to use it. Source: src/std/colorize.iyi at v0.18.0.

Colorize.enabled? decides whether escapes are written at all. Until set, it asks two things: whether standard output is a terminal, and whether the environment refuses colour the way the NO_COLOR convention asks — false when NO_COLOR is set to anything but the empty string, false when TERM is dumb, true otherwise. The terminal question is the prelude's __iyi_isatty, which is isatty on POSIX and GetConsoleMode answering at all on Windows; before it existed this module wrote escapes into pipes and files and said so here, and a program redirecting its own output had to set Colorize.enabled = false by hand. Colorize.reset(io) writes \e[0m; Colorize.with is an empty coloured object to build a prefix from.

.colorize is added to every value by reopening the prelude's Object at the end of this file: the method is the whole of the module's surface, and a wrapper call on every value is the one shape 42.colorize.yellow can take. That reopen is the only thing this module puts outside its own namespace.

Colorizestruct

std/colorizeiyi doc src/std/colorize.iyi
pub struct Colorize
  alias Color = ColorANSI | Color256 | ColorRGB
  struct Color256
    def initialize(value : UInt8)
    def to_u8 : UInt8
    def value : UInt8
  end
  enum ColorANSI : Int32
    Default = 39
    Black = 30
    Red = 31
    Green = 32
    Yellow = 33
    Blue = 34
    Magenta = 35
    Cyan = 36
    LightGray = 37
    DarkGray = 90
    LightRed = 91
    LightGreen = 92
    LightYellow = 93
    LightBlue = 94
    LightMagenta = 95
    LightCyan = 96
    White = 97
  end
  struct ColorRGB
    def blue : UInt8
    def green : UInt8
    def initialize(red : UInt8, green : UInt8, blue : UInt8)
    def red : UInt8
  end
  enum Mode : Int32
    Default = 0
    Bold = 1
    Dim = 2
    Underline = 4
    Blink = 5
    Reverse = 7
    Hidden = 8
  end
  struct Object(T)
    def back(r : UInt8, g : UInt8, b : UInt8) : self
    def back(color : Color) : self
    def back(color : Symbol) : self
    def back(val : UInt8) : self
    # Colors
    def black : self
    def blink : self
    def blue : self
    # Modes
    def bold : self
    def bright : self
    def cyan : self
    def dark_gray : self
    def default : self
    def dim : self
    def fore(r : UInt8, g : UInt8, b : UInt8) : self
    def fore(color : Color) : self
    def fore(color : Symbol) : self
    def fore(val : UInt8) : self
    def green : self
    def hidden : self
    def initialize(target : T, fore : Color | ::Nil = nil, back : Color | ::Nil = nil, mode : Mode = Mode::Default, enabled : Bool = true)
    def inspect(io) : Nil
    # The target written down, painted: `"hi".colorize.red.inspect` is the
    # escape around `"\"hi\""`, the way the other library has it. It was
    # `to_s`, so a coloured string inspected lost its quotes and read as a
    # name.
    def inspect : String
    def light_blue : self
    def light_cyan : self
    def light_gray : self
    def light_green : self
    def light_magenta : self
    def light_red : self
    def light_yellow : self
    def magenta : self
    def mode(mode : Mode) : self
    # `:bright` is `:bold`, as the `bright` method is; a name that is no mode
    # raises rather than answering `Default`, which cleared the mode already
    # set: `bold.mode(:italic)` printed the text plain.
    def mode(sym : Symbol) : self
    def on(color) : self
    # Backgrounds
    def on_black : self
    def on_blue : self
    def on_cyan : self
    def on_dark_gray : self
    def on_default : self
    def on_green : self
    def on_light_blue : self
    def on_light_cyan : self
    def on_light_gray : self
    def on_light_green : self
    def on_light_magenta : self
    def on_light_red : self
    def on_light_yellow : self
    def on_magenta : self
    def on_red : self
    def on_white : self
    def on_yellow : self
    def red : self
    def reverse : self
    def to_s(io) : Nil
    def to_s : String
    def toggle(enabled : Bool) : self
    def underline : self
    def white : self
    def yellow : self
  end
  module ObjectExtensions
    def colorize(r : UInt8, g : UInt8, b : UInt8) : Colorize::Object(self)
    def colorize(fore : Symbol) : Colorize::Object(self)
    def colorize(fore : Color) : Colorize::Object(self)
    def colorize(fore : UInt8) : Colorize::Object(self)
    def colorize : Colorize::Object(self)
  end
  def self.enabled : Bool
  def self.enabled=(value : Bool) : Bool
  def self.enabled? : Bool
  # The environment's answer, read once: standard output and standard
  # error must both be terminals, `NO_COLOR` set to anything but `""`
  # refuses, `TERM=dumb` refuses, and nothing else is asked. The terminal
  # test is first because it is the one a reader cannot set: escapes in a
  # file are a defect in every environment, and this module wrote them
  # there until the prelude could answer the question (`__iyi_isatty`).
  # Both, as Crystal's `on_tty_only!` asks, because the answer is one for
  # the program and text is painted before anyone knows which stream it
  # goes to: with only standard output asked, `prog 2> err.log` from a
  # terminal wrote escapes into err.log.
  def self.environment_allows? : Bool
  def initialize
  def self.reset(io : IO) : Nil
  def self.reset : Nil
  def self.with : Object(String)
end

Objectclass, reopened

std/colorizeiyi doc src/std/colorize.iyi
class ::Object
end