Skip to content

Commit

Permalink
Add docs to Colorize (#11664)
Browse files Browse the repository at this point in the history
Co-authored-by: r00ster91 <[email protected]>
Co-authored-by: Oleh Prypin <[email protected]>
  • Loading branch information
3 people authored Jan 3, 2022
1 parent 9c2d38e commit 6bbf05f
Showing 1 changed file with 59 additions and 8 deletions.
67 changes: 59 additions & 8 deletions src/colorize.cr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# With Colorize you can change the fore- and background colors and text decorations when rendering text
# With `Colorize` you can change the fore- and background colors and text decorations when rendering text
# on terminals supporting ANSI escape codes. It adds the `colorize` method to `Object` and thus all classes
# as its main interface, which calls `to_s` and surrounds it with the necessary escape codes
# when it comes to obtaining a string representation of the object.
#
# Its first argument changes the foreground color:
#
# ```
# require "colorize"
#
Expand All @@ -13,6 +14,7 @@
# ```
#
# There are alternative ways to change the foreground color:
#
# ```
# require "colorize"
#
Expand All @@ -21,6 +23,7 @@
# ```
#
# To change the background color, the following methods are available:
#
# ```
# require "colorize"
#
Expand All @@ -30,20 +33,27 @@
# ```
#
# You can also pass an RGB color to `colorize`:
#
# ```
# require "colorize"
#
# "foo".colorize(0, 255, 255) # => "foo" in aqua
#
# # This is the same as:
#
# "foo".colorize(Colorize::ColorRGB.new(0, 255, 255)) # => "foo" in aqua
# ```
#
# Or an 8-bit color:
#
# ```
# require "colorize"
#
# "foo".colorize(Colorize::Color256.new(208)) # => "foo" in orange
# ```
#
# It's also possible to change the text decoration:
#
# ```
# require "colorize"
#
Expand All @@ -53,6 +63,7 @@
#
# The `colorize` method returns a `Colorize::Object` instance,
# which allows chaining methods together:
#
# ```
# require "colorize"
#
Expand All @@ -61,19 +72,21 @@
#
# With the `toggle` method you can temporarily disable adding the escape codes.
# Settings of the instance are preserved however and can be turned back on later:
#
# ```
# require "colorize"
#
# "foo".colorize(:red).toggle(false) # => "foo" without color
# "foo".colorize(:red).toggle(false).toggle(true) # => "foo" in red
# ```
#
# The color `:default` will just leave the object as it is (but it's an `Colorize::Object(String)` then).
# That's handy in for example conditions:
# The color `:default` leaves the object's representation as it is but the object is a `Colorize::Object` then
# which is handy in conditions such as:
#
# ```
# require "colorize"
#
# "foo".colorize(some_bool ? :green : :default)
# "foo".colorize(Random::DEFAULT.next_bool ? :green : :default)
# ```
#
# Available colors are:
Expand Down Expand Up @@ -108,10 +121,7 @@
# :hidden
# ```
module Colorize
# If this value is `true`, `Colorize::Object` is enabled by default.
# But if this value is `false`, `Colorize::Object` is disabled.
#
# The default value is `true`.
# Objects will only be colored if this is `true`.
#
# ```
# require "colorize"
Expand All @@ -122,6 +132,9 @@ module Colorize
# Colorize.enabled = false
# "hello".colorize.red.to_s # => "hello"
# ```
#
# NOTE: This is by default disabled on non-TTY devices because they likely don't support ANSI escape codes.
# This will also be disabled if the environment variable `TERM` is "dumb".
class_property? enabled : Bool = true

# Makes `Colorize.enabled` `true` if and only if both of `STDOUT.tty?`
Expand All @@ -132,6 +145,15 @@ module Colorize
self.enabled = STDOUT.tty? && STDERR.tty? && ENV["TERM"]? != "dumb"
end

# Resets the color and text decoration of the *io*.
#
# ```
# with_color.green.surround(io) do
# io << "green"
# Colorize.reset
# io << " default"
# end
# ```
def self.reset(io = STDOUT)
io << "\e[0m" if enabled?
end
Expand All @@ -151,10 +173,12 @@ module Colorize
end

module Colorize::ObjectExtensions
# Turns `self` into a `Colorize::Object`.
def colorize : Colorize::Object
Colorize::Object.new(self)
end

# Turns `self` into a `Colorize::Object` and colors it with a color.
def colorize(fore)
Colorize::Object.new(self).fore(fore)
end
Expand All @@ -167,6 +191,7 @@ end
module Colorize
alias Color = ColorANSI | Color256 | ColorRGB

# One color of a fixed set of colors.
enum ColorANSI
Default = 39
Black = 30
Expand Down Expand Up @@ -195,6 +220,7 @@ module Colorize
end
end

# An 8-bit color.
record Color256,
value : UInt8 do
def fore(io : IO) : Nil
Expand All @@ -208,6 +234,7 @@ module Colorize
end
end

# An RGB color.
record ColorRGB,
red : UInt8,
green : UInt8,
Expand All @@ -228,6 +255,7 @@ module Colorize
end
end

# A colorized object. Colors and text decorations can be modified.
struct Colorize::Object(T)
private MODE_DEFAULT = '0'
private MODE_BOLD = '1'
Expand Down Expand Up @@ -323,23 +351,46 @@ struct Colorize::Object(T)
back color
end

# Enables or disables colors and text decoration on this object.
def toggle(flag)
@enabled = !!flag
self
end

# Appends this object colored and with text decoration to *io*.
def to_s(io : IO) : Nil
surround(io) do
io << @object
end
end

# Inspects this object and makes the ANSI escape codes visible.
def inspect(io : IO) : Nil
surround(io) do
@object.inspect(io)
end
end

# Surrounds *io* by the ANSI escape codes and lets you build colored strings:
#
# ```
# require "colorize"
#
# io = IO::Memory.new
#
# with_color.red.surround(io) do
# io << "colorful"
# with_color.green.bold.surround(io) do
# io << " hello "
# end
# with_color.blue.surround(io) do
# io << "world"
# end
# io << " string"
# end
#
# io.to_s # returns a colorful string where "colorful" is red, "hello" green, "world" blue and " string" red again
# ```
def surround(io = STDOUT)
return yield io unless @enabled

Expand Down

0 comments on commit 6bbf05f

Please sign in to comment.