natty-ui 0.7.0 → 0.9.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 +4 -4
- data/.yardopts +7 -3
- data/README.md +25 -47
- data/examples/24bit-colors.rb +27 -0
- data/examples/3bit-colors.rb +14 -0
- data/examples/8bit-colors.rb +31 -0
- data/examples/animate.rb +24 -0
- data/examples/attributes.rb +25 -159
- data/examples/demo.rb +53 -0
- data/examples/illustration.png +0 -0
- data/examples/illustration.rb +29 -0
- data/examples/{list_in_columns.rb → ls.rb} +13 -20
- data/examples/message.rb +30 -0
- data/examples/progress.rb +25 -30
- data/examples/query.rb +26 -28
- data/examples/read_key.rb +13 -0
- data/examples/table.rb +36 -0
- data/lib/natty-ui/ansi.rb +351 -305
- data/lib/natty-ui/ansi_constants.rb +73 -0
- data/lib/natty-ui/ansi_wrapper.rb +136 -162
- data/lib/natty-ui/features.rb +11 -18
- data/lib/natty-ui/key_map.rb +119 -0
- data/lib/natty-ui/line_animation/default.rb +35 -0
- data/lib/natty-ui/line_animation/matrix.rb +28 -0
- data/lib/natty-ui/line_animation/rainbow.rb +30 -0
- data/lib/natty-ui/line_animation/test.rb +29 -0
- data/lib/natty-ui/line_animation/type_writer.rb +64 -0
- data/lib/natty-ui/line_animation.rb +54 -0
- data/lib/natty-ui/version.rb +2 -2
- data/lib/natty-ui/wrapper/animate.rb +17 -0
- data/lib/natty-ui/wrapper/ask.rb +21 -21
- data/lib/natty-ui/wrapper/element.rb +19 -23
- data/lib/natty-ui/wrapper/framed.rb +29 -19
- data/lib/natty-ui/wrapper/heading.rb +26 -53
- data/lib/natty-ui/wrapper/horizontal_rule.rb +37 -0
- data/lib/natty-ui/wrapper/list_in_columns.rb +71 -12
- data/lib/natty-ui/wrapper/message.rb +20 -27
- data/lib/natty-ui/wrapper/progress.rb +40 -13
- data/lib/natty-ui/wrapper/query.rb +34 -31
- data/lib/natty-ui/wrapper/quote.rb +25 -0
- data/lib/natty-ui/wrapper/request.rb +21 -10
- data/lib/natty-ui/wrapper/section.rb +55 -39
- data/lib/natty-ui/wrapper/table.rb +298 -0
- data/lib/natty-ui/wrapper/task.rb +6 -7
- data/lib/natty-ui/wrapper.rb +123 -41
- data/lib/natty-ui.rb +65 -40
- metadata +28 -9
- data/examples/basic.rb +0 -62
data/lib/natty-ui/ansi.rb
CHANGED
@@ -6,141 +6,147 @@ module NattyUI
|
|
6
6
|
#
|
7
7
|
module Ansi
|
8
8
|
class << self
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
# @
|
13
|
-
|
14
|
-
|
15
|
-
# @return [String] ANSI code to restore screen state
|
16
|
-
def screen_restore = "\e[?47l"
|
17
|
-
|
18
|
-
# @return [String] ANSI code to alternate screen
|
19
|
-
def screen_alternative = "\e[?1049h"
|
20
|
-
|
21
|
-
# @return [String] ANSI code to set alternate screen off
|
22
|
-
def screen_alternative_off = "\e[?1049l"
|
23
|
-
|
24
|
-
# @return [String] ANSI code to erase screen
|
25
|
-
def screen_erase = "\e[2J"
|
26
|
-
|
27
|
-
# @return [String] ANSI code to erase screen below current cursor position
|
28
|
-
def screen_erase_below = "\e[0J"
|
29
|
-
|
30
|
-
# @return [String] ANSI code to erase screen above current cursor position
|
31
|
-
def screen_erase_above = "\e[1J"
|
32
|
-
|
33
|
-
# @return [String] ANSI code to erase current line
|
34
|
-
def line_erase = "\e[2K"
|
35
|
-
|
36
|
-
# @return [String] ANSI code to erase to end of current line
|
37
|
-
def line_erase_to_end = "\e[0K"
|
38
|
-
|
39
|
-
# @return [String] ANSI code to erase to begin of current line
|
40
|
-
def line_erase_to_begin = "\e[1K"
|
41
|
-
|
42
|
-
# @return [String] ANSI code to erase current line and position to first
|
43
|
-
# column
|
44
|
-
def line_clear = "\e[1K\e[0G"
|
45
|
-
|
46
|
-
# @param lines [Integer] number of lines
|
47
|
-
# @return [String] ANSI code to move the cursor up
|
48
|
-
def cursor_up(lines = nil) = "\e[#{lines}A"
|
49
|
-
|
50
|
-
# @param lines [Integer] number of lines
|
51
|
-
# @return [String] ANSI code to move the cursor down
|
52
|
-
def cursor_down(lines = nil) = "\e[#{lines}B"
|
53
|
-
|
54
|
-
# @param columns [Integer] number of columns
|
55
|
-
# @return [String] ANSI code to move the cursor right
|
56
|
-
def cursor_right(columns = nil) = "\e[#{columns}C"
|
57
|
-
|
58
|
-
# @param columns [Integer] number of columns
|
59
|
-
# @return [String] ANSI code to move the cursor left
|
60
|
-
def cursor_left(columns = nil) = "\e[#{columns}D"
|
9
|
+
# Supported attribute names.
|
10
|
+
# @see []
|
11
|
+
#
|
12
|
+
# @attribute [r] attribute_names
|
13
|
+
# @return [Array<Symbol>] supported attribute names
|
14
|
+
def attribute_names = SATTR.keys.sort!
|
61
15
|
|
62
|
-
#
|
63
|
-
# @
|
64
|
-
#
|
65
|
-
|
16
|
+
# Supported color names.
|
17
|
+
# @see []
|
18
|
+
#
|
19
|
+
# @attribute [r] color_names
|
20
|
+
# @return [Array<Symbol>] supported color names
|
21
|
+
def color_names = SCLR.keys
|
66
22
|
|
67
|
-
#
|
68
|
-
# @return [String] ANSI code to move the cursor to beginning of the line
|
69
|
-
# some lines up
|
70
|
-
def cursor_line_up(lines = nil) = "\e[#{lines}F"
|
23
|
+
# @!group Control functions
|
71
24
|
|
72
|
-
#
|
73
|
-
#
|
74
|
-
|
25
|
+
# Move cursor given lines up.
|
26
|
+
#
|
27
|
+
# @param lines [Integer] number of lines to move
|
28
|
+
# @return [String] ANSI control code
|
29
|
+
def cursor_up(lines = 1) = "\e[#{lines}A"
|
75
30
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
31
|
+
# Move cursor given lines down.
|
32
|
+
#
|
33
|
+
# @param (see cursor_up)
|
34
|
+
# @return (see cursor_up)
|
35
|
+
def cursor_down(lines = 1) = "\e[#{lines}B"
|
79
36
|
|
80
|
-
#
|
81
|
-
|
37
|
+
# Move cursor given colums forward.
|
38
|
+
#
|
39
|
+
# @param columns [Integer] number of columns to move
|
40
|
+
# @return (see cursor_up)
|
41
|
+
def cursor_forward(columns = 1) = "\e[#{columns}C"
|
82
42
|
|
83
|
-
#
|
84
|
-
|
43
|
+
# Move cursor given colums back.
|
44
|
+
#
|
45
|
+
# @param (see cursor_forward)
|
46
|
+
# @return (see cursor_up)
|
47
|
+
def cursor_back(columns = 1) = "\e[#{columns}D"
|
85
48
|
|
86
|
-
#
|
87
|
-
|
49
|
+
# Move cursor of beginning of the given next line.
|
50
|
+
#
|
51
|
+
# @param (see cursor_up)
|
52
|
+
# @return (see cursor_up)
|
53
|
+
def cursor_next_line(lines = 1) = "\e[#{lines}E"
|
88
54
|
|
89
|
-
#
|
90
|
-
|
55
|
+
# Move cursor of beginning of the given previous line.
|
56
|
+
#
|
57
|
+
# @param (see cursor_up)
|
58
|
+
# @return (see cursor_up)
|
59
|
+
def cursor_previous_line(lines = 1) = "\e[#{lines}F"
|
60
|
+
alias cursor_prev_line cursor_previous_line
|
91
61
|
|
92
|
-
#
|
93
|
-
|
62
|
+
# Move cursor to given column in the current row.
|
63
|
+
#
|
64
|
+
# @param column [Integer] column index
|
65
|
+
# @return (see cursor_up)
|
66
|
+
def cursor_column(column = 1) = "\e[#{column}G"
|
94
67
|
|
95
|
-
#
|
96
|
-
#
|
97
|
-
# @
|
68
|
+
# Move cursor to given row and column counting from the top left corner.
|
69
|
+
#
|
70
|
+
# @param row [Integer] row index
|
71
|
+
# @param column [Integer] column index
|
72
|
+
# @return (see cursor_up)
|
98
73
|
def cursor_pos(row, column = nil)
|
99
74
|
return column ? "\e[#{row};#{column}H" : "\e[#{row}H" if row
|
100
75
|
column ? "\e[;#{column}H" : "\e[H"
|
101
76
|
end
|
102
77
|
|
103
|
-
#
|
104
|
-
|
105
|
-
#
|
78
|
+
# @comment ??? def cursor_tab(count = 1) = "\e[#{column}I"
|
79
|
+
|
80
|
+
# Erase screen.
|
106
81
|
#
|
107
|
-
# @param
|
108
|
-
# @
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
82
|
+
# @param part [:below, :above, :scrollback, :entire] part to erase
|
83
|
+
# @return (see cursor_up)
|
84
|
+
def screen_erase(part = :entire)
|
85
|
+
return "\e[0J" if part == :below
|
86
|
+
return "\e[1J" if part == :above
|
87
|
+
return "\e[3J" if part == :scrollback
|
88
|
+
"\e[2J"
|
114
89
|
end
|
115
90
|
|
116
|
-
#
|
91
|
+
# Clear part of current line.
|
117
92
|
#
|
118
|
-
# @
|
93
|
+
# @param part [:to_end, :to_start, :entire] part to delete
|
94
|
+
# @return (see cursor_up)
|
95
|
+
def line_erase(part = :entire)
|
96
|
+
return "\e[0K" if part == :to_end
|
97
|
+
return "\e[1K" if part == :to_start
|
98
|
+
"\e[2K"
|
99
|
+
end
|
100
|
+
|
101
|
+
# @comment ??? def line_insert(lines = 1) = "\e[#{lines}L"
|
102
|
+
# @comment ??? def line_delete(lines = 1) = "\e[#{lines}M"
|
103
|
+
# @comment ??? def chars_delete(count = 1) = "\e[#{count}P"
|
104
|
+
|
105
|
+
# Scroll window given lines up.
|
119
106
|
#
|
120
|
-
# @param
|
121
|
-
# @return
|
122
|
-
def
|
107
|
+
# @param lines [Integer] number of lines to scroll
|
108
|
+
# @return (see cursor_up)
|
109
|
+
def scroll_up(lines = 1) = "\e[;#{lines}S"
|
123
110
|
|
124
|
-
#
|
111
|
+
# Scroll window given lines down.
|
125
112
|
#
|
126
|
-
#
|
113
|
+
# @param (see scroll_up)
|
114
|
+
# @return (see cursor_up)
|
115
|
+
def scroll_down(lines = 1) = "\e[;#{lines}T"
|
116
|
+
|
117
|
+
# @comment ??? def chars_erase(count = 1) = "\e[#{count}X"
|
118
|
+
# @comment ??? def cursor_reverse_tab(count = 1) = "\e[#{count}Z"
|
119
|
+
|
120
|
+
# set absolute col
|
121
|
+
# @comment ??? doubled! def cursor_column(column = 1) = "\e[#{column}`"
|
122
|
+
# set relative column
|
123
|
+
# @comment ??? def cursor_column_rel(column = 1) = "\e[#{column}a"
|
124
|
+
# set absolute row
|
125
|
+
# @comment ??? def cursor_row(row = 1) = "\e[#{row}d"
|
126
|
+
# set relative row
|
127
|
+
# @comment ??? def cursor_row_rel(row = 1) = "\e[#{row}e"
|
128
|
+
|
129
|
+
# Change window title.
|
130
|
+
# This is not widely supported but by XTerm and iTerm.
|
127
131
|
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
|
131
|
-
|
132
|
-
#
|
133
|
-
#
|
134
|
-
# `invert_off`, `reverse_off`, `reveal`, `strike_off`, `proportional_off`,
|
135
|
-
# `spacing_off`, `framed`, `encircled`, `overlined`, `framed_off`,
|
136
|
-
# `encircled_off`, `overlined_off`.
|
132
|
+
# @param [String] title text
|
133
|
+
# @return (see cursor_up)
|
134
|
+
def window_title(title) = "\e]2;#{title}\e\\"
|
135
|
+
|
136
|
+
# Change tab title.
|
137
|
+
# This is not widely supported but by iTerm.
|
137
138
|
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
|
141
|
-
|
142
|
-
#
|
139
|
+
# @param [String] title text
|
140
|
+
# @return (see cursor_up)
|
141
|
+
def tab_title(title) = "\e]0;#{title}\a"
|
142
|
+
|
143
|
+
# @!endgroup
|
144
|
+
|
145
|
+
# @!group Tool functions
|
146
|
+
|
147
|
+
# Combine given ANSI {.attribute_names}, {.color_names} and color codes.
|
143
148
|
#
|
149
|
+
# Colors can specified by their name for ANSI 3-bit and 4-bit colors.
|
144
150
|
# For 8-bit ANSI colors use 2-digit hexadecimal values `00`...`ff`.
|
145
151
|
#
|
146
152
|
# To use RGB ANSI colors (24-bit colors) specify 3-digit or 6-digit
|
@@ -150,11 +156,9 @@ module NattyUI
|
|
150
156
|
#
|
151
157
|
# To use a color as background color prefix the color attribute with `bg_`
|
152
158
|
# or `on_`.
|
153
|
-
#
|
154
159
|
# To use a color as underline color prefix the color attribute with `ul_`.
|
155
|
-
#
|
156
|
-
#
|
157
|
-
# color the color value can be prefixed with `fg_`.
|
160
|
+
# To clarify that a color attribute have to be used as foreground
|
161
|
+
# color use the prefix `fg_`.
|
158
162
|
#
|
159
163
|
# @example Valid Foreground Color Attributes
|
160
164
|
# Ansi[:yellow]
|
@@ -197,12 +201,17 @@ module NattyUI
|
|
197
201
|
attributes
|
198
202
|
.map do |arg|
|
199
203
|
case arg
|
200
|
-
when Symbol
|
201
|
-
|
204
|
+
when Symbol
|
205
|
+
SATTR[arg] || SCLR[arg] || color(arg.to_s) ||
|
206
|
+
invalid_argument(arg)
|
207
|
+
when String
|
208
|
+
ATTR[arg] || CLR[arg] || color(arg) || invalid_argument(arg)
|
202
209
|
when (0..255)
|
203
210
|
"38;5;#{arg}"
|
204
|
-
when (256..
|
211
|
+
when (256..511)
|
205
212
|
"48;5;#{arg}"
|
213
|
+
when (512..767)
|
214
|
+
"58;5;#{arg}"
|
206
215
|
else
|
207
216
|
invalid_argument(arg)
|
208
217
|
end
|
@@ -211,8 +220,29 @@ module NattyUI
|
|
211
220
|
}m"
|
212
221
|
end
|
213
222
|
|
214
|
-
#
|
215
|
-
#
|
223
|
+
# Decorate given `str` with ANSI attributes and colors.
|
224
|
+
#
|
225
|
+
# @see []
|
226
|
+
#
|
227
|
+
# @param str [#to_s] object to be decorated
|
228
|
+
# @param attributes [Symbol, String] attribute names to be used
|
229
|
+
# @param reset [Boolean] whether to include reset code for ANSI attributes
|
230
|
+
# @return [String] `str` converted and decorated with the ANSI `attributes`
|
231
|
+
def embellish(str, *attributes, reset: true)
|
232
|
+
attributes = self[*attributes]
|
233
|
+
attributes.empty? ? str.to_s : "#{attributes}#{str}#{"\e[0m" if reset}"
|
234
|
+
end
|
235
|
+
|
236
|
+
# Remove ANSI functions, attributes and colors from given string.
|
237
|
+
#
|
238
|
+
# @see embellish
|
239
|
+
#
|
240
|
+
# @param str [#to_s] string to be modified
|
241
|
+
# @return [String] string without ANSI attributes
|
242
|
+
def blemish(str) = str.to_s.gsub(/(\e\[(?~[a-zA-Z])[a-zA-Z])/, '')
|
243
|
+
|
244
|
+
# Try to combine given ANSI attributes and colors.
|
245
|
+
# The attributes and colors have to be seperated by space char (" ").
|
216
246
|
#
|
217
247
|
# @example Valid Attribute String
|
218
248
|
# Ansi.try_convert('bold italic blink red on#00ff00')
|
@@ -230,11 +260,40 @@ module NattyUI
|
|
230
260
|
return if (attributes = attributes.to_s.split).empty?
|
231
261
|
"\e[#{
|
232
262
|
attributes
|
233
|
-
.map { |
|
263
|
+
.map! { |a| ATTR[a] || CLR[a] || color(a) || return }
|
234
264
|
.join(';')
|
235
265
|
}m"
|
236
266
|
end
|
237
267
|
|
268
|
+
# @param str [#to_s] plain text string to enrich with color
|
269
|
+
# @param type [:foreground, :background, :underline] type of coloring
|
270
|
+
# @param frequence [Float] color change frequency
|
271
|
+
# @param spread [Float] number of chars with same color
|
272
|
+
# @param seed [Float] start index on sinus curve
|
273
|
+
# @return [String] fancy text
|
274
|
+
def rainbow(
|
275
|
+
str,
|
276
|
+
type: :foreground,
|
277
|
+
frequence: 0.3,
|
278
|
+
spread: 0.8,
|
279
|
+
seed: 1.1
|
280
|
+
)
|
281
|
+
type = color_type(type)
|
282
|
+
pos = -1
|
283
|
+
str
|
284
|
+
.to_s
|
285
|
+
.chars
|
286
|
+
.map! do |char|
|
287
|
+
i = (seed + ((pos += 1) / spread)) * frequence
|
288
|
+
"\e[#{type};2;#{(Math.sin(i) * 255).abs.to_i};" \
|
289
|
+
"#{(Math.sin(i + PI2_THIRD) * 255).abs.to_i};" \
|
290
|
+
"#{(Math.sin(i + PI4_THIRD) * 255).abs.to_i}m#{char}"
|
291
|
+
end
|
292
|
+
.join
|
293
|
+
end
|
294
|
+
|
295
|
+
# @!endgroup
|
296
|
+
|
238
297
|
private
|
239
298
|
|
240
299
|
def invalid_argument(name)
|
@@ -245,195 +304,182 @@ module NattyUI
|
|
245
304
|
)
|
246
305
|
end
|
247
306
|
|
307
|
+
def color_type(type)
|
308
|
+
case type
|
309
|
+
when :background, :bg, 'background', 'bg'
|
310
|
+
48
|
311
|
+
when :underline, :ul, 'underline', 'ul'
|
312
|
+
58
|
313
|
+
else
|
314
|
+
38
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
248
318
|
def color(val)
|
249
|
-
|
250
|
-
base
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
val.delete_prefix!(':') || val.delete_prefix!('_')
|
259
|
-
'48;'
|
260
|
-
else
|
261
|
-
'38;'
|
262
|
-
end
|
263
|
-
val.delete_prefix!('#')
|
264
|
-
case val.size
|
265
|
-
when 2
|
266
|
-
"#{base}5;#{val.hex}" if /\A[[:xdigit:]]+\z/.match?(val)
|
267
|
-
when 3
|
268
|
-
if /\A[[:xdigit:]]+\z/.match?(val)
|
269
|
-
"#{base}2;#{(val[0] * 2).hex};#{(val[1] * 2).hex};#{
|
270
|
-
(val[2] * 2).hex
|
271
|
-
}"
|
272
|
-
end
|
273
|
-
when 6
|
274
|
-
if /\A[[:xdigit:]]+\z/.match?(val)
|
275
|
-
"#{base}2;#{val[0, 2].hex};#{val[2, 2].hex};#{val[4, 2].hex}"
|
276
|
-
end
|
319
|
+
base = CLR_PREFIX[val[0, 2]]
|
320
|
+
idx = base ? 2 : 0
|
321
|
+
base ||= '38'
|
322
|
+
idx += 1 if val[idx] == '_' || val[idx] == ':'
|
323
|
+
idx += 1 if val[idx] == '#'
|
324
|
+
val = val[idx..]
|
325
|
+
return "#{base};5;#{val.hex}" if /\A[[:xdigit:]]{1,2}\z/.match?(val)
|
326
|
+
if /\A[[:xdigit:]]{6}\z/.match?(val)
|
327
|
+
return "#{base};2;#{val[0, 2].hex};#{val[2, 2].hex};#{val[4, 2].hex}"
|
277
328
|
end
|
329
|
+
return unless /\A[[:xdigit:]]{3}\z/.match?(val)
|
330
|
+
"#{base};2;#{(val[0] * 2).hex};#{(val[1] * 2).hex};#{(val[2] * 2).hex}"
|
278
331
|
end
|
279
332
|
end
|
280
333
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
ul_bright_red: '58;2;255;0;0',
|
430
|
-
ul_bright_green: '58;2;0;255;0',
|
431
|
-
ul_bright_yellow: '58;2;255;255;0',
|
432
|
-
ul_bright_blue: '58;2;0;0;255',
|
433
|
-
ul_bright_magenta: '58;2;255;0;255',
|
434
|
-
ul_bright_cyan: '58;2;0;255;255',
|
435
|
-
ul_bright_white: '58;2;255;255;255'
|
436
|
-
}.tap { |ret| ret.merge!(ret.transform_keys(&:to_s)).freeze }
|
437
|
-
private_constant :ATTRIBUTES
|
334
|
+
CLR_PREFIX = {
|
335
|
+
'fg' => '38',
|
336
|
+
'bg' => '48',
|
337
|
+
'ul' => '58',
|
338
|
+
'on' => '48'
|
339
|
+
}.freeze
|
340
|
+
|
341
|
+
PI2_THIRD = 2 * Math::PI / 3.0
|
342
|
+
PI4_THIRD = 4 * Math::PI / 3.0
|
343
|
+
|
344
|
+
SATTR =
|
345
|
+
Module
|
346
|
+
.new do
|
347
|
+
def self.to_hash
|
348
|
+
map = {
|
349
|
+
# alternative names
|
350
|
+
slow_blink: 5,
|
351
|
+
conceal: 8,
|
352
|
+
default_font: 10,
|
353
|
+
doubly: 21,
|
354
|
+
faint_off: 22,
|
355
|
+
fraktur_off: 23,
|
356
|
+
spacing: 26,
|
357
|
+
conceal_off: 28,
|
358
|
+
spacing_off: 50,
|
359
|
+
encircled_off: 54,
|
360
|
+
subscript_off: 75,
|
361
|
+
# special
|
362
|
+
curly_underline_off: '4:0',
|
363
|
+
dotted_underline_off: '4:0',
|
364
|
+
dashed_underline_off: '4:0',
|
365
|
+
curly_underline: '4:3',
|
366
|
+
dotted_underline: '4:4',
|
367
|
+
dashed_underline: '4:5'
|
368
|
+
}
|
369
|
+
add = ->(s, n) { n.each_with_index { |a, idx| map[a] = s + idx } }
|
370
|
+
add[
|
371
|
+
0,
|
372
|
+
%i[
|
373
|
+
reset
|
374
|
+
bold
|
375
|
+
faint
|
376
|
+
italic
|
377
|
+
underline
|
378
|
+
blink
|
379
|
+
rapid_blink
|
380
|
+
invert
|
381
|
+
hide
|
382
|
+
strike
|
383
|
+
primary_font
|
384
|
+
font1
|
385
|
+
font2
|
386
|
+
font3
|
387
|
+
font4
|
388
|
+
font5
|
389
|
+
font6
|
390
|
+
font7
|
391
|
+
font8
|
392
|
+
font9
|
393
|
+
fraktur
|
394
|
+
double_underline
|
395
|
+
bold_off
|
396
|
+
italic_off
|
397
|
+
underline_off
|
398
|
+
blink_off
|
399
|
+
proportional
|
400
|
+
invert_off
|
401
|
+
reveal
|
402
|
+
strike_off
|
403
|
+
]
|
404
|
+
]
|
405
|
+
add[
|
406
|
+
50,
|
407
|
+
%i[
|
408
|
+
proportional_off
|
409
|
+
framed
|
410
|
+
encircled
|
411
|
+
overlined
|
412
|
+
framed_off
|
413
|
+
overlined_off
|
414
|
+
]
|
415
|
+
]
|
416
|
+
add[73, %i[superscript subscript superscript_off]]
|
417
|
+
map
|
418
|
+
end
|
419
|
+
end
|
420
|
+
.to_hash
|
421
|
+
.compare_by_identity
|
422
|
+
.freeze
|
423
|
+
|
424
|
+
CLR =
|
425
|
+
Module
|
426
|
+
.new do
|
427
|
+
def self.to_hash
|
428
|
+
clr = {
|
429
|
+
0 => 'black',
|
430
|
+
1 => 'red',
|
431
|
+
2 => 'green',
|
432
|
+
3 => 'yellow',
|
433
|
+
4 => 'blue',
|
434
|
+
5 => 'magenta',
|
435
|
+
6 => 'cyan',
|
436
|
+
7 => 'white'
|
437
|
+
}
|
438
|
+
map = {}
|
439
|
+
add = ->(s, p) { clr.each_pair { |i, n| map["#{p}#{n}"] = s + i } }
|
440
|
+
ul = ->(r, g, b) { "58;2;#{r};#{g};#{b}" }
|
441
|
+
add[30, nil]
|
442
|
+
map['default'] = 39
|
443
|
+
add[90, 'bright_']
|
444
|
+
add[30, 'fg_']
|
445
|
+
map['fg_default'] = 39
|
446
|
+
add[90, 'fg_bright_']
|
447
|
+
add[40, 'bg_']
|
448
|
+
map['bg_default'] = 49
|
449
|
+
add[100, 'bg_bright_']
|
450
|
+
add[40, 'on_']
|
451
|
+
map['on_default'] = 49
|
452
|
+
add[100, 'on_bright_']
|
453
|
+
map.merge!(
|
454
|
+
'ul_black' => ul[0, 0, 0],
|
455
|
+
'ul_red' => ul[128, 0, 0],
|
456
|
+
'ul_green' => ul[0, 128, 0],
|
457
|
+
'ul_yellow' => ul[128, 128, 0],
|
458
|
+
'ul_blue' => ul[0, 0, 128],
|
459
|
+
'ul_magenta' => ul[128, 0, 128],
|
460
|
+
'ul_cyan' => ul[0, 128, 128],
|
461
|
+
'ul_white' => ul[128, 128, 128],
|
462
|
+
'ul_default' => '59',
|
463
|
+
'ul_bright_black' => ul[64, 64, 64],
|
464
|
+
'ul_bright_red' => ul[255, 0, 0],
|
465
|
+
'ul_bright_green' => ul[0, 255, 0],
|
466
|
+
'ul_bright_yellow' => ul[255, 255, 0],
|
467
|
+
'ul_bright_blue' => ul[0, 0, 255],
|
468
|
+
'ul_bright_magenta' => ul[255, 0, 255],
|
469
|
+
'ul_bright_cyan' => ul[0, 255, 255],
|
470
|
+
'ul_bright_white' => ul[255, 255, 255]
|
471
|
+
)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
.to_hash
|
475
|
+
.freeze
|
476
|
+
|
477
|
+
ATTR = SATTR.transform_keys(&:to_s).freeze
|
478
|
+
SCLR = CLR.transform_keys(&:to_sym).compare_by_identity.freeze
|
479
|
+
|
480
|
+
private_constant :CLR_PREFIX, :PI2_THIRD, :PI4_THIRD
|
481
|
+
private_constant :SATTR, :SCLR, :ATTR, :CLR
|
438
482
|
end
|
439
483
|
end
|
484
|
+
|
485
|
+
require_relative 'ansi_constants'
|