just-ansi 0.1.1
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/LICENSE +21 -0
- data/README.md +29 -0
- data/lib/just-ansi/attributes.rb +206 -0
- data/lib/just-ansi/named_colors.rb +664 -0
- data/lib/just-ansi/string.rb +31 -0
- data/lib/just-ansi/version.rb +6 -0
- data/lib/just-ansi.rb +470 -0
- data/lib/just_ansi.rb +3 -0
- metadata +58 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../just-ansi'
|
4
|
+
|
5
|
+
# Ruby String class ANSI extension.
|
6
|
+
class String
|
7
|
+
# Test if String contains ANSI codes.
|
8
|
+
#
|
9
|
+
# @see JustAnsi.ansi?
|
10
|
+
#
|
11
|
+
# @return [true, false] whether if attributes are found
|
12
|
+
def ansi? = JustAnsi.ansi?(self)
|
13
|
+
|
14
|
+
# Decorate self with ANSI attributes and colors.
|
15
|
+
#
|
16
|
+
# @see JustAnsi.decorate
|
17
|
+
#
|
18
|
+
# @param attributes [Array<Symbol, String>] attribute names to be used
|
19
|
+
# @param reset [true, false] whether to include reset code for ANSI attributes
|
20
|
+
# @return [String] `str` converted and decorated with the ANSI `attributes`
|
21
|
+
def ansi(*attributes, reset: true)
|
22
|
+
JustAnsi.decorate(self, *attributes, reset: reset)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Remove ANSI functions, attributes and colors from self.
|
26
|
+
#
|
27
|
+
# @see JustAnsi.undecorate
|
28
|
+
#
|
29
|
+
# @return [String] string without ANSI attributes
|
30
|
+
def unansi = JustAnsi.undecorate(self)
|
31
|
+
end
|
data/lib/just-ansi.rb
ADDED
@@ -0,0 +1,470 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# shareable_constant_value: literal
|
3
|
+
|
4
|
+
#
|
5
|
+
# Simple and fast ANSI control code processing.
|
6
|
+
#
|
7
|
+
module JustAnsi
|
8
|
+
class << self
|
9
|
+
# Supported attribute names.
|
10
|
+
#
|
11
|
+
# @see []
|
12
|
+
#
|
13
|
+
# @attribute [r] attributes
|
14
|
+
# @return [Array<Symbol>] all attribute names
|
15
|
+
def attributes = ATTRIBUTES_S.keys
|
16
|
+
|
17
|
+
# Supported 3/4-bit color names.
|
18
|
+
#
|
19
|
+
# @see []
|
20
|
+
#
|
21
|
+
# @attribute [r] colors
|
22
|
+
# @return [Array<Symbol>] all color names
|
23
|
+
def colors = COLORS_S.keys
|
24
|
+
|
25
|
+
# Supported basic 24-bit color names.
|
26
|
+
#
|
27
|
+
# @see []
|
28
|
+
#
|
29
|
+
# @attribute [r] named_colors
|
30
|
+
# @return [Array<Symbol>] all basic named_colors names
|
31
|
+
def named_colors = NAMED_COLORS.keys.map!(&:to_sym)
|
32
|
+
|
33
|
+
# Combine given ANSI {.attributes}, {.colors}, {.named_colors} and color
|
34
|
+
# codes.
|
35
|
+
#
|
36
|
+
# Colors can specified by their name for ANSI 3-bit and 4-bit colors.
|
37
|
+
# For 8-bit ANSI colors use 2-digit hexadecimal values `00`...`ff`.
|
38
|
+
#
|
39
|
+
# To use RGB ANSI colors (24-bit colors) specify 3-digit or 6-digit
|
40
|
+
# hexadecimal values `000`...`fff` or `000000`...`ffffff`.
|
41
|
+
# This represent the `RRGGBB` values (or `RGB` for short version) like you
|
42
|
+
# may known from CSS color notation.
|
43
|
+
#
|
44
|
+
# To use a color as background color prefix the color attribute with `bg_`
|
45
|
+
# or `on_`.
|
46
|
+
# To use a color as underline color prefix the color attribute with `ul_`.
|
47
|
+
# To clarify that a color attribute have to be used as foreground
|
48
|
+
# color use the prefix `fg_`.
|
49
|
+
#
|
50
|
+
# @example Valid Foreground Color Attributes
|
51
|
+
# JustAnsi[:yellow]
|
52
|
+
# JustAnsi[:fg_fab]
|
53
|
+
# JustAnsi[:fg_00aa00]
|
54
|
+
# JustAnsi[:af]
|
55
|
+
# JustAnsi[:fg_af]
|
56
|
+
# JustAnsi['#fab']
|
57
|
+
# JustAnsi['#00aa00']
|
58
|
+
# JustAnsi['lightblue']
|
59
|
+
#
|
60
|
+
# @example Valid Background Color Attributes
|
61
|
+
# JustAnsi[:bg_yellow]
|
62
|
+
# JustAnsi[:bg_fab]
|
63
|
+
# JustAnsi[:bg_00aa00]
|
64
|
+
# JustAnsi[:bg_af]
|
65
|
+
# JustAnsi['bg#00aa00']
|
66
|
+
# JustAnsi['bg_lightblue']
|
67
|
+
#
|
68
|
+
# JustAnsi[:on_yellow]
|
69
|
+
# JustAnsi[:on_fab]
|
70
|
+
# JustAnsi[:on_00aa00]
|
71
|
+
# JustAnsi[:on_af]
|
72
|
+
# JustAnsi['on#00aa00']
|
73
|
+
# JustAnsi['on_lightblue']
|
74
|
+
#
|
75
|
+
# @example Valid Underline Color Attributes
|
76
|
+
# JustAnsi[:underline, :ul_yellow]
|
77
|
+
# JustAnsi[:underline, :ul_fab]
|
78
|
+
# JustAnsi[:underline, :ul_00aa00]
|
79
|
+
# JustAnsi[:underline, :ul_fa]
|
80
|
+
# JustAnsi[:underline, :ul_bright_yellow]
|
81
|
+
# JustAnsi[:underline, 'ul#00aa00']
|
82
|
+
# JustAnsi['underline', 'ul_lightblue']
|
83
|
+
#
|
84
|
+
# @example Combined attributes:
|
85
|
+
# JustAnsi[:bold, :italic, :bright_white, :on_0000cc]
|
86
|
+
#
|
87
|
+
# @param attributes [Array<Symbol, String>] attribute names to be used
|
88
|
+
# @return [String] combined ANSI attributes
|
89
|
+
def [](*attributes)
|
90
|
+
return +'' if attributes.empty?
|
91
|
+
"\e[#{
|
92
|
+
attributes
|
93
|
+
.map do |arg|
|
94
|
+
case arg
|
95
|
+
when Symbol
|
96
|
+
ATTRIBUTES_S[arg] || COLORS_S[arg] || _color(arg) || _invalid(arg)
|
97
|
+
when String
|
98
|
+
ATTRIBUTES[arg] || COLORS[arg] || _color(arg) || _invalid(arg)
|
99
|
+
when (0..255)
|
100
|
+
"38;5;#{arg}"
|
101
|
+
when (256..511)
|
102
|
+
"48;5;#{arg - 256}"
|
103
|
+
when (512..767)
|
104
|
+
"58;5;#{arg - 512}"
|
105
|
+
else
|
106
|
+
_invalid(arg)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
.join(';')
|
110
|
+
}m"
|
111
|
+
end
|
112
|
+
|
113
|
+
# Test if all given attributes are valid.
|
114
|
+
#
|
115
|
+
# @see []
|
116
|
+
#
|
117
|
+
# @param attributes [Array<Symbol, String>] attribute names to be used
|
118
|
+
# @return [true, false] whether if all given attributes are valid
|
119
|
+
def valid?(*attributes)
|
120
|
+
attributes.all? do |arg|
|
121
|
+
case arg
|
122
|
+
when Symbol
|
123
|
+
ATTRIBUTES_S[arg] || COLORS_S[arg] || _color(arg) || false
|
124
|
+
when String
|
125
|
+
ATTRIBUTES[arg] || COLORS[arg] || _color(arg) || false
|
126
|
+
when (0..767)
|
127
|
+
true
|
128
|
+
else
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Test if given String contains ANSI codes.
|
135
|
+
#
|
136
|
+
# @param str [#to_s] object to be tested
|
137
|
+
# @return [true, false] whether if attributes are found
|
138
|
+
def ansi?(str) = TEST.match?(str.to_s)
|
139
|
+
|
140
|
+
# Decorate given `str` with ANSI attributes and colors.
|
141
|
+
#
|
142
|
+
# @see []
|
143
|
+
# @see undecorate
|
144
|
+
#
|
145
|
+
# @param str [#to_s] object to be decorated
|
146
|
+
# @param attributes [Array<Symbol, String>] attribute names to be used
|
147
|
+
# @param reset [true, false] whether to include reset code for ANSI attributes
|
148
|
+
# @return [String] `str` converted and decorated with the ANSI `attributes`
|
149
|
+
def decorate(str, *attributes, reset: true)
|
150
|
+
attributes = self[*attributes]
|
151
|
+
attributes.empty? ? "#{str}" : "#{attributes}#{str}#{"\e[m" if reset}"
|
152
|
+
end
|
153
|
+
|
154
|
+
# Remove ANSI functions, attributes and colors from given string.
|
155
|
+
#
|
156
|
+
# @see decorate
|
157
|
+
#
|
158
|
+
# @param str [#to_s] string to be modified
|
159
|
+
# @return [String] string without ANSI attributes
|
160
|
+
def undecorate(str) = str.to_s.gsub(TEST, '')
|
161
|
+
|
162
|
+
# Try to combine given ANSI attributes and colors.
|
163
|
+
# The attributes and colors have to be seperated by given `seperator``.
|
164
|
+
#
|
165
|
+
# @example Valid Attribute String
|
166
|
+
# JustAnsi.try_convert('bold italic blink red on#00ff00')
|
167
|
+
# # => ANSI attribute string for bold, italic text which blinks red on
|
168
|
+
# # green background
|
169
|
+
#
|
170
|
+
# @example Invalid Attribute String
|
171
|
+
# JustAnsi.try_convert('cool bold on green')
|
172
|
+
# # => nil
|
173
|
+
#
|
174
|
+
# @see []
|
175
|
+
#
|
176
|
+
# @param attributes [#to_s] attributes separated by given `seperator`
|
177
|
+
# @param seperator [String] attribute seperator char
|
178
|
+
# @return [String] combined ANSI attributes
|
179
|
+
# @return [nil] when string does not contain valid attributes
|
180
|
+
def try_convert(attributes, seperator: ' ')
|
181
|
+
return unless attributes
|
182
|
+
return if (attributes = attributes.to_s.split(seperator)).empty?
|
183
|
+
"\e[#{
|
184
|
+
attributes
|
185
|
+
.map! { ATTRIBUTES[_1] || COLORS[_1] || _color(_1) || return }
|
186
|
+
.join(';')
|
187
|
+
}m"
|
188
|
+
end
|
189
|
+
|
190
|
+
# @!group Control functions
|
191
|
+
|
192
|
+
# Move cursor given lines up.
|
193
|
+
#
|
194
|
+
# @param lines [Integer] number of lines to move
|
195
|
+
# @return [String] ANSI control code
|
196
|
+
def cursor_up(lines = 1) = "\e[#{lines}A"
|
197
|
+
|
198
|
+
# Move cursor given lines down.
|
199
|
+
#
|
200
|
+
# @param (see cursor_up)
|
201
|
+
# @return (see cursor_up)
|
202
|
+
def cursor_down(lines = 1) = "\e[#{lines}B"
|
203
|
+
|
204
|
+
# Move cursor given colums forward.
|
205
|
+
#
|
206
|
+
# @param columns [Integer] number of columns to move
|
207
|
+
# @return (see cursor_up)
|
208
|
+
def cursor_forward(columns = 1) = "\e[#{columns}C"
|
209
|
+
|
210
|
+
# Move cursor given colums back.
|
211
|
+
#
|
212
|
+
# @param (see cursor_forward)
|
213
|
+
# @return (see cursor_up)
|
214
|
+
def cursor_back(columns = 1) = "\e[#{columns}D"
|
215
|
+
|
216
|
+
# Move cursor of beginning of the given next line.
|
217
|
+
#
|
218
|
+
# @param (see cursor_up)
|
219
|
+
# @return (see cursor_up)
|
220
|
+
def cursor_next_line(lines = 1) = "\e[#{lines}E"
|
221
|
+
|
222
|
+
# Move cursor of beginning of the given previous line.
|
223
|
+
#
|
224
|
+
# @param (see cursor_up)
|
225
|
+
# @return (see cursor_up)
|
226
|
+
def cursor_previous_line(lines = 1) = "\e[#{lines}F"
|
227
|
+
alias cursor_prev_line cursor_previous_line
|
228
|
+
|
229
|
+
# Move cursor to given column in the current row.
|
230
|
+
#
|
231
|
+
# @param column [Integer] column index
|
232
|
+
# @return (see cursor_up)
|
233
|
+
def cursor_column(column = 1) = "\e[#{column}G"
|
234
|
+
|
235
|
+
# Move cursor to given row and column counting from the top left corner.
|
236
|
+
#
|
237
|
+
# @param row [Integer] row index
|
238
|
+
# @param column [Integer] column index
|
239
|
+
# @return (see cursor_up)
|
240
|
+
def cursor_pos(row, column = nil)
|
241
|
+
return column ? "\e[;#{column}H" : "\e[H" unless row
|
242
|
+
column ? "\e[#{row};#{column}H" : "\e[#{row}H"
|
243
|
+
end
|
244
|
+
|
245
|
+
# Show cursor.
|
246
|
+
#
|
247
|
+
# @return (see cursor_up)
|
248
|
+
def cursor_show = +CURSOR_SHOW
|
249
|
+
|
250
|
+
# Hide cursor.
|
251
|
+
#
|
252
|
+
# @return (see cursor_up)
|
253
|
+
def cursor_hide = +CURSOR_HIDE
|
254
|
+
|
255
|
+
# Safe current cursor position.
|
256
|
+
#
|
257
|
+
# @return (see cursor_up)
|
258
|
+
def cursor_pos_safe = +CURSOR_POS_SAFE
|
259
|
+
|
260
|
+
# Restore safed cursor position.
|
261
|
+
#
|
262
|
+
# @return (see cursor_up)
|
263
|
+
def cursor_pos_restore = +CURSOR_POS_RESTORE
|
264
|
+
|
265
|
+
# Erase screen below current cursor line.
|
266
|
+
#
|
267
|
+
# @return (see cursor_up)
|
268
|
+
def screen_erase_below = _screen_erase(0)
|
269
|
+
|
270
|
+
# Erase screen above current cursor line.
|
271
|
+
#
|
272
|
+
# @return (see cursor_up)
|
273
|
+
def screen_erase_above = _screen_erase(1)
|
274
|
+
|
275
|
+
# Erase complete screen.
|
276
|
+
#
|
277
|
+
# @return (see cursor_up)
|
278
|
+
def screen_erase = _screen_erase(2)
|
279
|
+
|
280
|
+
# Erase screen scrollback buffer.
|
281
|
+
#
|
282
|
+
# @return (see cursor_up)
|
283
|
+
def screen_erase_scrollback = _screen_erase(3)
|
284
|
+
|
285
|
+
# Safe current screen.
|
286
|
+
#
|
287
|
+
# @return (see cursor_up)
|
288
|
+
def screen_save = +SCREEN_SAVE
|
289
|
+
|
290
|
+
# Restore current screen.
|
291
|
+
#
|
292
|
+
# @return (see cursor_up)
|
293
|
+
def screen_restore = +SCREEN_RESTORE
|
294
|
+
|
295
|
+
# Use alternative screen buffer.
|
296
|
+
#
|
297
|
+
# @return (see cursor_up)
|
298
|
+
def screen_alternate = +SCREEN_ALTERNATE
|
299
|
+
|
300
|
+
# Do not longer use alternative screen buffer.
|
301
|
+
#
|
302
|
+
# @return (see cursor_up)
|
303
|
+
def screen_alternate_off = +SCREEN_ALTERNATE_OFF
|
304
|
+
|
305
|
+
# Erase line from current column to end of line.
|
306
|
+
#
|
307
|
+
# @return (see cursor_up)
|
308
|
+
def line_erase_to_end = _line_erase(0)
|
309
|
+
|
310
|
+
# Erase line from current column to start of line.
|
311
|
+
#
|
312
|
+
# @return (see cursor_up)
|
313
|
+
def line_erase_to_start = _line_erase(1)
|
314
|
+
|
315
|
+
# Erase current line.
|
316
|
+
#
|
317
|
+
# @return (see cursor_up)
|
318
|
+
def line_erase = _line_erase(2)
|
319
|
+
|
320
|
+
# Scroll window given lines up.
|
321
|
+
#
|
322
|
+
# @param lines [Integer] number of lines to scroll
|
323
|
+
# @return (see cursor_up)
|
324
|
+
def scroll_up(lines = 1) = "\e[;#{lines}S"
|
325
|
+
|
326
|
+
# Scroll window given lines down.
|
327
|
+
#
|
328
|
+
# @param (see scroll_up)
|
329
|
+
# @return (see cursor_up)
|
330
|
+
def scroll_down(lines = 1) = "\e[;#{lines}T"
|
331
|
+
|
332
|
+
# Change window title.
|
333
|
+
# This is not widely supported.
|
334
|
+
#
|
335
|
+
# @param [String] title text
|
336
|
+
# @return (see cursor_up)
|
337
|
+
def window_title(title) = "\e]2;#{title}\e\\"
|
338
|
+
|
339
|
+
# Change tab title.
|
340
|
+
# This is not widely supported.
|
341
|
+
#
|
342
|
+
# @param [String] title text
|
343
|
+
# @return (see cursor_up)
|
344
|
+
def tab_title(title) = "\e]0;#{title}\a"
|
345
|
+
|
346
|
+
# Create a hyperlink.
|
347
|
+
# This is not widely supported.
|
348
|
+
def link(url, text) = "\e]8;;#{url}\e\\#{text}\e]8;;\e\\"
|
349
|
+
|
350
|
+
# @!endgroup
|
351
|
+
|
352
|
+
# @comment seems not widely supported:
|
353
|
+
# @comment doubled!? def cursor_column(column = 1) = "\e[#{column}`"
|
354
|
+
# @comment doubled!? def cursor_row(row = 1) = "\e[#{row}d"
|
355
|
+
# @comment def cursor_column_rel(columns = 1) = "\e[#{columns}a"
|
356
|
+
# @comment def cursor_row_rel(rows = 1) = "\e[#{rows}e"
|
357
|
+
# @comment def cursor_tab(count = 1) = "\e[#{column}I"
|
358
|
+
# @comment def cursor_reverse_tab(count = 1) = "\e[#{count}Z"
|
359
|
+
# @comment def line_insert(lines = 1) = "\e[#{lines}L"
|
360
|
+
# @comment def line_delete(lines = 1) = "\e[#{lines}M"
|
361
|
+
# @comment def chars_delete(count = 1) = "\e[#{count}P"
|
362
|
+
# @comment def chars_erase(count = 1) = "\e[#{count}X"
|
363
|
+
|
364
|
+
private
|
365
|
+
|
366
|
+
def _invalid(name)
|
367
|
+
raise(
|
368
|
+
ArgumentError,
|
369
|
+
"unknown ANSI attribute - #{name.inspect}",
|
370
|
+
caller(1)
|
371
|
+
)
|
372
|
+
end
|
373
|
+
|
374
|
+
def _color(str)
|
375
|
+
if /\A(?<base>fg|bg|on|ul)?_?#?(?<val>[[:xdigit:]]{1,6})\z/ =~ str
|
376
|
+
return(
|
377
|
+
case val.size
|
378
|
+
when 1, 2
|
379
|
+
"#{_color_base(base)};5;#{val.hex}"
|
380
|
+
when 3
|
381
|
+
"#{_color_base(base)};2;#{(val[0] * 2).hex};#{(val[1] * 2).hex};#{
|
382
|
+
(val[2] * 2).hex
|
383
|
+
}"
|
384
|
+
when 6
|
385
|
+
"#{_color_base(base)};2;#{val[0, 2].hex};#{val[2, 2].hex};#{
|
386
|
+
val[4, 2].hex
|
387
|
+
}"
|
388
|
+
end
|
389
|
+
)
|
390
|
+
end
|
391
|
+
if /\A(?<base>fg|bg|on|ul)?_?(?<val>[a-z]{3,}[0-9]{0,3})\z/ =~ str
|
392
|
+
val = NAMED_COLORS[val] and return "#{_color_base(base)};#{val}"
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def _color_base(base)
|
397
|
+
return '48' if base == 'bg' || base == 'on'
|
398
|
+
base == 'ul' ? '58' : '38'
|
399
|
+
end
|
400
|
+
|
401
|
+
def _screen_erase(part) = "\e[#{part}J"
|
402
|
+
def _line_erase(part) = "\e[#{part}K"
|
403
|
+
end
|
404
|
+
|
405
|
+
TEST =
|
406
|
+
/\e
|
407
|
+
(?:\[[\d;:\?]*[ABCDEFGHJKSTfminsuhl])
|
408
|
+
|
|
409
|
+
(?:\]\d+(?:;[^;\a\e]+)*(?:\a|\e\\))
|
410
|
+
/x
|
411
|
+
|
412
|
+
require_relative 'just-ansi/attributes'
|
413
|
+
autoload :NAMED_COLORS, File.join(__dir__, 'just-ansi', 'named_colors')
|
414
|
+
private_constant :TEST, :NAMED_COLORS
|
415
|
+
|
416
|
+
# @!visibility private
|
417
|
+
RESET = self[:reset].freeze
|
418
|
+
|
419
|
+
# @!visibility private
|
420
|
+
CURSOR_HOME = cursor_pos(nil, nil).freeze
|
421
|
+
# @!visibility private
|
422
|
+
CURSOR_FIRST_ROW = cursor_pos(1).freeze
|
423
|
+
# @!visibility private
|
424
|
+
CURSOR_FIRST_COLUMN = cursor_column(1).freeze
|
425
|
+
|
426
|
+
# @!visibility private
|
427
|
+
CURSOR_SHOW = "\e[?25h"
|
428
|
+
# @!visibility private
|
429
|
+
CURSOR_HIDE = "\e[?25l"
|
430
|
+
|
431
|
+
# CURSOR_POS_SAFE_SCO = "\e[s"
|
432
|
+
# CURSOR_POS_SAFE_DEC = "\e7"
|
433
|
+
# @!visibility private
|
434
|
+
CURSOR_POS_SAFE = "\e7"
|
435
|
+
|
436
|
+
# CURSOR_POS_RESTORE_SCO = "\e[u"
|
437
|
+
# CURSOR_POS_RESTORE_DEC = "\e8"
|
438
|
+
# @!visibility private
|
439
|
+
CURSOR_POS_RESTORE = "\e8"
|
440
|
+
|
441
|
+
# @!visibility private
|
442
|
+
SCREEN_ERASE_BELOW = screen_erase_below.freeze
|
443
|
+
# @!visibility private
|
444
|
+
SCREEN_ERASE_ABOVE = screen_erase_above.freeze
|
445
|
+
# @!visibility private
|
446
|
+
SCREEN_ERASE = screen_erase.freeze
|
447
|
+
# @!visibility private
|
448
|
+
SCREEN_ERASE_SCROLLBACK = screen_erase_scrollback.freeze
|
449
|
+
|
450
|
+
# @!visibility private
|
451
|
+
SCREEN_SAVE = "\e[?47h"
|
452
|
+
# @!visibility private
|
453
|
+
SCREEN_RESTORE = "\e[?47l"
|
454
|
+
|
455
|
+
# @!visibility private
|
456
|
+
SCREEN_ALTERNATE = "\e[?1049h"
|
457
|
+
# @!visibility private
|
458
|
+
SCREEN_ALTERNATE_OFF = "\e[?1049l"
|
459
|
+
|
460
|
+
# @!visibility private
|
461
|
+
LINE_ERASE_TO_END = line_erase_to_end.freeze
|
462
|
+
# @!visibility private
|
463
|
+
LINE_ERASE_TO_START = line_erase_to_start.freeze
|
464
|
+
# @!visibility private
|
465
|
+
LINE_ERASE = line_erase.freeze
|
466
|
+
# @!visibility private
|
467
|
+
LINE_PREVIOUS = cursor_previous_line(1).freeze
|
468
|
+
# @!visibility private
|
469
|
+
LINE_NEXT = cursor_next_line(1).freeze
|
470
|
+
end
|
data/lib/just_ansi.rb
ADDED
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: just-ansi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Blumtritt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-09-14 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'Simple and fast ANSI control code processing.
|
14
|
+
|
15
|
+
'
|
16
|
+
email:
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- README.md
|
21
|
+
- LICENSE
|
22
|
+
files:
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
- lib/just-ansi.rb
|
26
|
+
- lib/just-ansi/attributes.rb
|
27
|
+
- lib/just-ansi/named_colors.rb
|
28
|
+
- lib/just-ansi/string.rb
|
29
|
+
- lib/just-ansi/version.rb
|
30
|
+
- lib/just_ansi.rb
|
31
|
+
homepage: https://github.com/mblumtritt/just-ansi
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
metadata:
|
35
|
+
source_code_uri: https://github.com/mblumtritt/just-ansi
|
36
|
+
bug_tracker_uri: https://github.com/mblumtritt/just-ansi/issues
|
37
|
+
documentation_uri: https://rubydoc.info/gems/just-ansi
|
38
|
+
rubygems_mfa_required: 'true'
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubygems_version: 3.5.18
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Simple fast ANSI
|
58
|
+
test_files: []
|