sai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +11 -0
- data/CHANGELOG.md +18 -0
- data/LICENSE +21 -0
- data/README.md +275 -0
- data/lib/sai/ansi.rb +94 -0
- data/lib/sai/conversion/color_sequence.rb +167 -0
- data/lib/sai/conversion/rgb.rb +322 -0
- data/lib/sai/decorator.rb +856 -0
- data/lib/sai/support.rb +115 -0
- data/lib/sai/terminal/capabilities.rb +121 -0
- data/lib/sai/terminal/color_mode.rb +63 -0
- data/lib/sai.rb +185 -0
- data/sig/sai/ansi.rbs +51 -0
- data/sig/sai/conversion/color_sequence.rbs +114 -0
- data/sig/sai/conversion/rgb.rbs +243 -0
- data/sig/sai/decorator.rbs +246 -0
- data/sig/sai/support.rbs +108 -0
- data/sig/sai/terminal/capabilities.rbs +81 -0
- data/sig/sai/terminal/color_mode.rbs +63 -0
- data/sig/sai.rbs +207 -0
- metadata +67 -0
data/lib/sai/support.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sai/terminal/color_mode'
|
4
|
+
|
5
|
+
module Sai
|
6
|
+
# Determine the color capabilities of the terminal
|
7
|
+
#
|
8
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
9
|
+
# @since unreleased
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
class Support
|
13
|
+
# Initialize a new instance of Support
|
14
|
+
#
|
15
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
16
|
+
# @since unreleased
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
#
|
20
|
+
# @param color_mode [Integer] the color mode
|
21
|
+
#
|
22
|
+
# @return [Support] the new instance of support
|
23
|
+
# @rbs (Integer color_mode) -> void
|
24
|
+
def initialize(color_mode)
|
25
|
+
@color_mode = color_mode
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check if the terminal supports ANSI colors (4-bit)
|
29
|
+
#
|
30
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
31
|
+
# @since unreleased
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
#
|
35
|
+
# @example Check if the terminal supports ANSI colors
|
36
|
+
# Sai.ansi? # => true
|
37
|
+
#
|
38
|
+
# @return [Boolean] `true` if the terminal supports ANSI colors (4-bit), otherwise `false`
|
39
|
+
# @rbs () -> bool
|
40
|
+
def ansi?
|
41
|
+
@color_mode >= Terminal::ColorMode::ANSI
|
42
|
+
end
|
43
|
+
alias bit4? ansi?
|
44
|
+
alias four_bit? ansi?
|
45
|
+
|
46
|
+
# Check if the terminal supports basic colors (3-bit)
|
47
|
+
#
|
48
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
49
|
+
# @since unreleased
|
50
|
+
#
|
51
|
+
# @api public
|
52
|
+
#
|
53
|
+
# @example Check if the terminal supports basic colors
|
54
|
+
# Sai.basic? # => true
|
55
|
+
#
|
56
|
+
# @return [Boolean] `true` if the terminal supports basic colors (3-bit), otherwise `false`
|
57
|
+
# @rbs () -> bool
|
58
|
+
def basic?
|
59
|
+
@color_mode >= Terminal::ColorMode::BASIC
|
60
|
+
end
|
61
|
+
alias bit3? basic?
|
62
|
+
alias three_bit? basic?
|
63
|
+
|
64
|
+
# Check if the terminal supports 256 colors (8-bit)
|
65
|
+
#
|
66
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
67
|
+
# @since unreleased
|
68
|
+
#
|
69
|
+
# @api public
|
70
|
+
#
|
71
|
+
# @example Check if the terminal supports 256 colors
|
72
|
+
# Sai.bit_8? # => true
|
73
|
+
#
|
74
|
+
# @return [Boolean] `true` if the terminal supports 256 colors (8-bit), otherwise `false`
|
75
|
+
# @rbs () -> bool
|
76
|
+
def bit8?
|
77
|
+
@color_mode >= Terminal::ColorMode::BIT8
|
78
|
+
end
|
79
|
+
alias eight_bit? bit8?
|
80
|
+
|
81
|
+
# Check if the terminal supports color output
|
82
|
+
#
|
83
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
84
|
+
# @since unreleased
|
85
|
+
#
|
86
|
+
# @api public
|
87
|
+
#
|
88
|
+
# @example Check if the terminal supports color
|
89
|
+
# Sai.color? # => true
|
90
|
+
#
|
91
|
+
# @return [Boolean] `true` if the terminal supports color output, otherwise `false`
|
92
|
+
# @rbs () -> bool
|
93
|
+
def color?
|
94
|
+
@color_mode > Terminal::ColorMode::NO_COLOR
|
95
|
+
end
|
96
|
+
|
97
|
+
# Check if the terminal supports true color (24-bit)
|
98
|
+
#
|
99
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
100
|
+
# @since unreleased
|
101
|
+
#
|
102
|
+
# @api public
|
103
|
+
#
|
104
|
+
# @example Check if the terminal supports true color
|
105
|
+
# Sai.true_color? # => true
|
106
|
+
#
|
107
|
+
# @return [Boolean] `true` if the terminal supports true color (24-bit), otherwise `false`
|
108
|
+
# @rbs () -> bool
|
109
|
+
def true_color?
|
110
|
+
@color_mode >= Terminal::ColorMode::TRUE_COLOR
|
111
|
+
end
|
112
|
+
alias bit24? true_color?
|
113
|
+
alias twenty_four_bit? true_color?
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sai/terminal/color_mode'
|
4
|
+
|
5
|
+
module Sai
|
6
|
+
module Terminal
|
7
|
+
# Detect the color capabilities of the terminal
|
8
|
+
#
|
9
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
10
|
+
# @since unreleased
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
module Capabilities
|
14
|
+
class << self
|
15
|
+
# Detect the color capabilities of the current terminal
|
16
|
+
#
|
17
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
18
|
+
# @since unreleased
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
#
|
22
|
+
# @return [Integer] the {ColorMode} of the terminal
|
23
|
+
# @rbs () -> Integer
|
24
|
+
def detect_color_support
|
25
|
+
return ColorMode::NO_COLOR if no_color?
|
26
|
+
return ColorMode::TRUE_COLOR if true_color?
|
27
|
+
return ColorMode::BIT8 if bit8?
|
28
|
+
return ColorMode::ANSI if ansi?
|
29
|
+
return ColorMode::BASIC if basic?
|
30
|
+
|
31
|
+
ColorMode::NO_COLOR
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Check for ANSI color support
|
37
|
+
#
|
38
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
39
|
+
# @since unreleased
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
#
|
43
|
+
# @return [Boolean] `true` if the terminal supports basic ANSI colors, otherwise `false`
|
44
|
+
# @rbs () -> bool
|
45
|
+
def ansi?
|
46
|
+
return true if ENV.fetch('TERM', '').match?(/^(xterm|screen|vt100|ansi)/)
|
47
|
+
|
48
|
+
!ENV.fetch('COLORTERM', '').empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Check for basic color support
|
52
|
+
#
|
53
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
54
|
+
# @since unreleased
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
#
|
58
|
+
# @return [Boolean] `true` if the terminal supports basic colors, otherwise `false`
|
59
|
+
# @rbs () -> bool
|
60
|
+
def basic?
|
61
|
+
!ENV.fetch('TERM', '').empty?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Check for 256 color (8-bit) support
|
65
|
+
#
|
66
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
67
|
+
# @since unreleased
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
#
|
71
|
+
# @return [Boolean] `true` if the terminal supports 256 colors, otherwise `false`
|
72
|
+
# @rbs () -> bool
|
73
|
+
def bit8?
|
74
|
+
return true if ENV.fetch('TERM', '').end_with?('-256color')
|
75
|
+
|
76
|
+
ENV.fetch('COLORTERM', '0').to_i >= 256
|
77
|
+
end
|
78
|
+
|
79
|
+
# Check for NO_COLOR environment variable
|
80
|
+
#
|
81
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
82
|
+
# @since unreleased
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
# @see https://no-color.org
|
87
|
+
#
|
88
|
+
# @return [Boolean] `true` if the NO_COLOR environment variable is set, otherwise `false`
|
89
|
+
# @rbs () -> bool
|
90
|
+
def no_color?
|
91
|
+
!ENV.fetch('NO_COLOR', '').empty? || !$stdout.tty?
|
92
|
+
end
|
93
|
+
|
94
|
+
# Check for true color (24-bit) support
|
95
|
+
#
|
96
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
97
|
+
# @since unreleased
|
98
|
+
#
|
99
|
+
# @api private
|
100
|
+
#
|
101
|
+
# @return [Boolean] `true` if the terminal supports true color, otherwise `false`
|
102
|
+
# @rbs () -> bool
|
103
|
+
def true_color?
|
104
|
+
return true if ENV.fetch('COLORTERM', '').match?(/^(truecolor|24bit)$/)
|
105
|
+
|
106
|
+
case ENV.fetch('TERM', nil)
|
107
|
+
when 'xterm-direct', 'xterm-truecolor'
|
108
|
+
return true
|
109
|
+
end
|
110
|
+
|
111
|
+
case ENV.fetch('TERM_PROGRAM', nil)
|
112
|
+
when 'iTerm.app', 'WezTerm', 'vscode'
|
113
|
+
return true
|
114
|
+
end
|
115
|
+
|
116
|
+
false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sai
|
4
|
+
module Terminal
|
5
|
+
# Represents different color support levels for terminal interfaces
|
6
|
+
#
|
7
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
8
|
+
# @since unreleased
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
module ColorMode
|
12
|
+
# The terminal does not support color output
|
13
|
+
#
|
14
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
15
|
+
# @since unreleased
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
# @return [Integer] the color mode
|
20
|
+
NO_COLOR = 0 #: Integer
|
21
|
+
|
22
|
+
# The terminal supports 8 colors (3-bit)
|
23
|
+
#
|
24
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
25
|
+
# @since unreleased
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
#
|
29
|
+
# @return [Integer] the color mode
|
30
|
+
BASIC = 1 #: Integer
|
31
|
+
|
32
|
+
# The terminal supports 16 colors (4-bit)
|
33
|
+
#
|
34
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
35
|
+
# @since unreleased
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
#
|
39
|
+
# @return [Integer] the color mode
|
40
|
+
ANSI = 2 #: Integer
|
41
|
+
|
42
|
+
# The terminal supports 256 colors (8-bit)
|
43
|
+
#
|
44
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
45
|
+
# @since unreleased
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
#
|
49
|
+
# @return [Integer] the color mode
|
50
|
+
BIT8 = 3 #: Integer
|
51
|
+
|
52
|
+
# The terminal supports 16 million colors (24-bit)
|
53
|
+
#
|
54
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
55
|
+
# @since unreleased
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
#
|
59
|
+
# @return [Integer] the color mode
|
60
|
+
TRUE_COLOR = 4 #: Integer
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/sai.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sai/decorator'
|
4
|
+
require 'sai/support'
|
5
|
+
require 'sai/terminal/capabilities'
|
6
|
+
require 'singleton'
|
7
|
+
|
8
|
+
# An elegant color management system for crafting sophisticated CLI applications
|
9
|
+
#
|
10
|
+
# Sai (彩) - meaning 'coloring' or 'paint' in Japanese - is a powerful and intuitive system for managing color output in
|
11
|
+
# command-line applications. Drawing inspiration from traditional Japanese artistic techniques, Sai brings vibrancy and
|
12
|
+
# harmony to terminal interfaces through its sophisticated color management
|
13
|
+
#
|
14
|
+
# Sai empowers developers to create beautiful, colorful CLI applications that maintain visual consistency across
|
15
|
+
# different terminal capabilities. Like its artistic namesake, it combines simplicity and sophistication to bring rich,
|
16
|
+
# adaptive color to your terminal interfaces
|
17
|
+
#
|
18
|
+
# When included in a class or module, Sai provides the following instance methods:
|
19
|
+
# * {#decorator} - Returns a new instance of {Decorator} for method chaining
|
20
|
+
# * {#terminal_color_support} - Returns the color support capabilities of the current terminal
|
21
|
+
#
|
22
|
+
# The Sai module itself responds to all the same methods as {Decorator}, excluding methods used for applying
|
23
|
+
# decorations (apply, call, decorate, encode). These methods are directly delegated to a new {Decorator} instance
|
24
|
+
#
|
25
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
26
|
+
# @since unreleased
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
#
|
30
|
+
# @example Using Sai as a module
|
31
|
+
# class MyClass
|
32
|
+
# include Sai
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# my_class = MyClass.new
|
36
|
+
# my_class.decorator.red.on_blue.bold.decorate('Hello, World!')
|
37
|
+
# #=> "\e[38;2;205;0;0m\e[48;2;0;0;238m\e[1mHello, World!\e[0m"
|
38
|
+
#
|
39
|
+
# my_class.terminal_color_support.true_color? # => true
|
40
|
+
#
|
41
|
+
# @example Using Sai directly
|
42
|
+
# Sai.red.on_blue.bold.decorate('Hello, World!')
|
43
|
+
# #=> "\e[38;2;205;0;0m\e[48;2;0;0;238m\e[1mHello, World!\e[0m"
|
44
|
+
#
|
45
|
+
# Sai.support.true_color? # => true
|
46
|
+
module Sai
|
47
|
+
class << self
|
48
|
+
ignored_decorator_methods = %i[apply call decorate encode]
|
49
|
+
Decorator.instance_methods(false).reject { |m| ignored_decorator_methods.include?(m) }.each do |method|
|
50
|
+
define_method(method) do |*arguments, **keyword_arguments|
|
51
|
+
Decorator.new(send(:color_mode)).public_send(method, *arguments, **keyword_arguments)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @rbs!
|
56
|
+
# def black: () -> self
|
57
|
+
# def blink: () -> self
|
58
|
+
# def blue: () -> self
|
59
|
+
# def bold: () -> self
|
60
|
+
# def bright_black: () -> self
|
61
|
+
# def bright_blue: () -> self
|
62
|
+
# def bright_cyan: () -> self
|
63
|
+
# def bright_green: () -> self
|
64
|
+
# def bright_magenta: () -> self
|
65
|
+
# def bright_red: () -> self
|
66
|
+
# def bright_white: () -> self
|
67
|
+
# def bright_yellow: () -> self
|
68
|
+
# def conceal: () -> self
|
69
|
+
# def cyan: () -> self
|
70
|
+
# def dim: () -> self
|
71
|
+
# def green: () -> self
|
72
|
+
# def italic: () -> self
|
73
|
+
# def magenta: () -> self
|
74
|
+
# def no_blink: () -> self
|
75
|
+
# def no_conceal: () -> self
|
76
|
+
# def no_italic: () -> self
|
77
|
+
# def no_reverse: () -> self
|
78
|
+
# def no_strike: () -> self
|
79
|
+
# def no_underline: () -> self
|
80
|
+
# def normal_intensity: () -> self
|
81
|
+
# def on_black: () -> self
|
82
|
+
# def on_blue: () -> self
|
83
|
+
# def on_bright_black: () -> self
|
84
|
+
# def on_bright_blue: () -> self
|
85
|
+
# def on_bright_cyan: () -> self
|
86
|
+
# def on_bright_green: () -> self
|
87
|
+
# def on_bright_magenta: () -> self
|
88
|
+
# def on_bright_red: () -> self
|
89
|
+
# def on_bright_white: () -> self
|
90
|
+
# def on_bright_yellow: () -> self
|
91
|
+
# def on_cyan: () -> self
|
92
|
+
# def on_green: () -> self
|
93
|
+
# def on_magenta: () -> self
|
94
|
+
# def on_red: () -> self
|
95
|
+
# def on_white: () -> self
|
96
|
+
# def on_yellow: () -> self
|
97
|
+
# def rapid_blink: () -> self
|
98
|
+
# def red: () -> self
|
99
|
+
# def reverse: () -> self
|
100
|
+
# def strike: () -> self
|
101
|
+
# def underline: () -> self
|
102
|
+
# def white: () -> self
|
103
|
+
# def yellow: () -> self
|
104
|
+
|
105
|
+
# The supported color modes for the terminal
|
106
|
+
#
|
107
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
108
|
+
# @since unreleased
|
109
|
+
#
|
110
|
+
# @api public
|
111
|
+
#
|
112
|
+
# @example Check the color support of the terminal
|
113
|
+
# Sai.support.ansi? # => true
|
114
|
+
# Sai.support.basic? # => true
|
115
|
+
# Sai.support.bit8? # => true
|
116
|
+
# Sai.support.no_color? # => false
|
117
|
+
# Sai.support.true_color? # => true
|
118
|
+
#
|
119
|
+
# @return [Support] the color support
|
120
|
+
# @rbs () -> Support
|
121
|
+
def support
|
122
|
+
@support ||= Support.new(color_mode).freeze
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
# Detect the color capabilities of the terminal
|
128
|
+
#
|
129
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
130
|
+
# @since unreleased
|
131
|
+
#
|
132
|
+
# @api private
|
133
|
+
#
|
134
|
+
# @return [Integer] the color mode
|
135
|
+
# @rbs () -> Integer
|
136
|
+
def color_mode
|
137
|
+
Thread.current[:sai_color_mode] ||= Terminal::Capabilities.detect_color_support
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# A helper method to initialize an instance of {Decorator}
|
142
|
+
#
|
143
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
144
|
+
# @since unreleased
|
145
|
+
#
|
146
|
+
# @api public
|
147
|
+
#
|
148
|
+
# @example Initialize a new instance of {Decorator}
|
149
|
+
# class MyClass
|
150
|
+
# include Sai
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# MyClass.new.decorator.blue.on_red.bold.decorate('Hello, world!')
|
154
|
+
# #=> "\e[38;5;21m\e[48;5;160m\e[1mHello, world!\e[0m"
|
155
|
+
#
|
156
|
+
# @return [Decorator] the Decorator instance
|
157
|
+
# @rbs () -> Decorator
|
158
|
+
def decorator
|
159
|
+
Decorator.new(Terminal::Capabilities.detect_color_support)
|
160
|
+
end
|
161
|
+
|
162
|
+
# The supported color modes for the terminal
|
163
|
+
#
|
164
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
165
|
+
# @since unreleased
|
166
|
+
#
|
167
|
+
# @api public
|
168
|
+
#
|
169
|
+
# @example Check the color support of the terminal
|
170
|
+
# class MyClass
|
171
|
+
# include Sai
|
172
|
+
# end
|
173
|
+
#
|
174
|
+
# MyClass.new.terminal_color_support.ansi? # => true
|
175
|
+
# MyClass.new.terminal_color_support.basic? # => true
|
176
|
+
# MyClass.new.terminal_color_support.bit8? # => true
|
177
|
+
# MyClass.new.terminal_color_support.no_color? # => false
|
178
|
+
# MyClass.new.terminal_color_support.true_color? # => true
|
179
|
+
#
|
180
|
+
# @return [Support] the color support
|
181
|
+
# @rbs () -> Support
|
182
|
+
def terminal_color_support
|
183
|
+
Sai.support
|
184
|
+
end
|
185
|
+
end
|
data/sig/sai/ansi.rbs
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Generated from lib/sai/ansi.rb with RBS::Inline
|
2
|
+
|
3
|
+
module Sai
|
4
|
+
# ANSI constants for encoding text styles and colors
|
5
|
+
#
|
6
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
7
|
+
# @since unreleased
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
module ANSI
|
11
|
+
# ANSI color code mappings
|
12
|
+
#
|
13
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
14
|
+
# @since unreleased
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
# @return [Hash{Symbol => Integer}] the color codes
|
19
|
+
COLOR_CODES: untyped
|
20
|
+
|
21
|
+
# Standard ANSI color names and their RGB values
|
22
|
+
#
|
23
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
24
|
+
# @since unreleased
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
#
|
28
|
+
# @return [Hash{Symbol => Array<Integer>}] the color names and RGB values
|
29
|
+
COLOR_NAMES: untyped
|
30
|
+
|
31
|
+
# ANSI escape sequence for resetting text formatting
|
32
|
+
#
|
33
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
34
|
+
# @since unreleased
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
#
|
38
|
+
# @return [String] the ANSI escape sequence
|
39
|
+
RESET: ::String
|
40
|
+
|
41
|
+
# Standard ANSI style codes
|
42
|
+
#
|
43
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
44
|
+
# @since unreleased
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
#
|
48
|
+
# @return [Hash{Symbol => Integer}] the style codes
|
49
|
+
STYLES: untyped
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# Generated from lib/sai/conversion/color_sequence.rb with RBS::Inline
|
2
|
+
|
3
|
+
module Sai
|
4
|
+
module Conversion
|
5
|
+
# ANSI escape sequence utilities
|
6
|
+
#
|
7
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
8
|
+
# @since unreleased
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
module ColorSequence
|
12
|
+
type style_type = :foreground | :background
|
13
|
+
|
14
|
+
# Convert a color to the appropriate ANSI escape sequence
|
15
|
+
#
|
16
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
17
|
+
# @since unreleased
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
#
|
21
|
+
# @param color [String, Array<Integer>] the color to convert
|
22
|
+
# @param mode [Integer] the terminal color mode
|
23
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
24
|
+
#
|
25
|
+
# @return [String] the ANSI escape sequence
|
26
|
+
# @rbs (Array[Integer] | String | Symbol color, Integer mode, ?style_type style_type) -> String
|
27
|
+
def self.resolve: (Array[Integer] | String | Symbol color, Integer mode, ?style_type style_type) -> String
|
28
|
+
|
29
|
+
# Convert RGB values to a 4-bit ANSI color sequence
|
30
|
+
#
|
31
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
32
|
+
# @since unreleased
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
#
|
36
|
+
# @param rgb [Array<Integer>] the RGB components
|
37
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
38
|
+
#
|
39
|
+
# @return [String] the ANSI escape sequence
|
40
|
+
# @rbs (Array[Integer] rgb, style_type style_type) -> String
|
41
|
+
private def self.ansi: (Array[Integer] rgb, style_type style_type) -> String
|
42
|
+
|
43
|
+
# Convert a base color to a foreground or background sequence
|
44
|
+
#
|
45
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
46
|
+
# @since unreleased
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
#
|
50
|
+
# @param base_code [Integer] the base color code
|
51
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
52
|
+
#
|
53
|
+
# @return [Integer] the code for the color sequence
|
54
|
+
# @rbs (Integer base_code, style_type style_type) -> Integer
|
55
|
+
private def self.base_color_for_style_type: (Integer base_code, style_type style_type) -> Integer
|
56
|
+
|
57
|
+
# Convert RGB values to a 3-bit basic color sequence
|
58
|
+
#
|
59
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
60
|
+
# @since unreleased
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
#
|
64
|
+
# @param rgb [Array<Integer>] the RGB components
|
65
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
66
|
+
#
|
67
|
+
# @return [String] the ANSI escape sequence
|
68
|
+
# @rbs (Array[Integer] rgb, style_type style_type) -> String
|
69
|
+
private def self.basic: (Array[Integer] rgb, style_type style_type) -> String
|
70
|
+
|
71
|
+
# Convert RGB values to an 8-bit color sequence
|
72
|
+
#
|
73
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
74
|
+
# @since unreleased
|
75
|
+
#
|
76
|
+
# @api private
|
77
|
+
#
|
78
|
+
# @param rgb [Array<Integer>] the RGB components
|
79
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
80
|
+
#
|
81
|
+
# @return [String] the ANSI escape sequence
|
82
|
+
# @rbs (Array[Integer] rgb, style_type type) -> String
|
83
|
+
private def self.bit8: (Array[Integer] rgb, style_type type) -> String
|
84
|
+
|
85
|
+
# Convert RGB values to a true color (24-bit) sequence
|
86
|
+
#
|
87
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
88
|
+
# @since unreleased
|
89
|
+
#
|
90
|
+
# @api private
|
91
|
+
#
|
92
|
+
# @param rgb [Array<Integer>] the RGB components
|
93
|
+
# @param style_type [Symbol] the type of color (foreground or background)
|
94
|
+
#
|
95
|
+
# @return [String] the ANSI escape sequence
|
96
|
+
# @rbs (Array[Integer] rgb, style_type type) -> String
|
97
|
+
private def self.true_color: (Array[Integer] rgb, style_type type) -> String
|
98
|
+
|
99
|
+
# Validate a color style type
|
100
|
+
#
|
101
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
102
|
+
# @since unreleased
|
103
|
+
#
|
104
|
+
# @api private
|
105
|
+
#
|
106
|
+
# @param style_type [Symbol] the style type to validate
|
107
|
+
#
|
108
|
+
# @raise [ArgumentError] if the style type is invalid
|
109
|
+
# @return [Symbol] the validated style type
|
110
|
+
# @rbs (Symbol style_type) -> Symbol
|
111
|
+
private def self.validate_style_type: (Symbol style_type) -> Symbol
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|