ansi 1.2.5 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +34 -31
- data/HISTORY.rdoc +18 -0
- data/LICENSE/BSD-2-Clause.txt +25 -0
- data/LICENSE/GPL-2.0.txt +339 -0
- data/LICENSE/MIT.txt +21 -0
- data/LICENSE/RUBY.txt +60 -0
- data/NOTICE.rdoc +116 -4
- data/README.rdoc +6 -12
- data/lib/ansi.rb +6 -0
- data/lib/ansi.rbz +40 -0
- data/lib/ansi.yml +34 -31
- data/lib/ansi/bbcode.rb +3 -0
- data/lib/ansi/chart.rb +95 -0
- data/lib/ansi/code.rb +189 -260
- data/lib/ansi/constants.rb +18 -0
- data/lib/ansi/core.rb +24 -0
- data/lib/ansi/diff.rb +98 -61
- data/lib/ansi/string.rb +7 -8
- data/lib/ansi/terminal.rb +3 -3
- data/qed/01_ansicode.rdoc +0 -7
- data/qed/09_diff.rb +5 -5
- data/qed/10_core.rdoc +11 -0
- data/test/case_ansicode.rb +20 -10
- data/test/case_bbcode.rb +7 -8
- data/test/case_mixin.rb +14 -7
- data/test/case_progressbar.rb +2 -2
- metadata +26 -27
- data/LICENSE +0 -205
- data/Rakefile +0 -4
data/lib/ansi/code.rb
CHANGED
@@ -1,204 +1,130 @@
|
|
1
|
-
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/
|
2
|
-
|
3
1
|
module ANSI
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /(win32|w32)/
|
4
|
+
|
5
|
+
require 'ansi/constants'
|
6
|
+
|
7
|
+
# Global variialbe can be used to prevent ANSI codes
|
8
|
+
# from being used in ANSI's methods that do so to string.
|
9
|
+
#
|
10
|
+
# NOTE: This has no effect of methods that return ANSI codes.
|
11
|
+
$ansi = true
|
7
12
|
|
8
|
-
#
|
13
|
+
# ANSI Codes
|
9
14
|
#
|
10
15
|
# Ansi::Code module makes it very easy to use ANSI codes.
|
11
16
|
# These are esspecially nice for beautifying shell output.
|
12
17
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# red + "Hello" + blue + "World"
|
18
|
+
# Ansi::Code.red + "Hello" + Ansi::Code.blue + "World"
|
16
19
|
# => "\e[31mHello\e[34mWorld"
|
17
20
|
#
|
18
|
-
# red
|
21
|
+
# Ansi::Code.red{ "Hello" } + Ansi::Code.blue{ "World" }
|
19
22
|
# => "\e[31mHello\e[0m\e[34mWorld\e[0m"
|
20
23
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
# The following is a list of supported display codes.
|
24
|
-
#
|
25
|
-
# save
|
26
|
-
# restore
|
27
|
-
# clear_screen
|
28
|
-
# cls # synonym for :clear_screen
|
29
|
-
# clear_line
|
30
|
-
# clr # synonym for :clear_line
|
31
|
-
# move
|
32
|
-
# up
|
33
|
-
# down
|
34
|
-
# left
|
35
|
-
# right
|
36
|
-
#
|
37
|
-
# The following is a list of supported "style" codes.
|
38
|
-
#
|
39
|
-
# clear
|
40
|
-
# reset # synonym for :clear
|
41
|
-
# bold
|
42
|
-
# dark
|
43
|
-
# italic # not widely implemented
|
44
|
-
# underline
|
45
|
-
# underscore # synonym for :underline
|
46
|
-
# blink
|
47
|
-
# rapid_blink # not widely implemented
|
48
|
-
# negative # no reverse because of String#reverse
|
49
|
-
# concealed
|
50
|
-
# strikethrough # not widely implemented
|
51
|
-
#
|
52
|
-
# The following is a list of supported color codes.
|
53
|
-
#
|
54
|
-
# black
|
55
|
-
# red
|
56
|
-
# green
|
57
|
-
# yellow
|
58
|
-
# blue
|
59
|
-
# magenta
|
60
|
-
# cyan
|
61
|
-
# white
|
62
|
-
#
|
63
|
-
# on_black
|
64
|
-
# on_red
|
65
|
-
# on_green
|
66
|
-
# on_yellow
|
67
|
-
# on_blue
|
68
|
-
# on_magenta
|
69
|
-
# on_cyan
|
70
|
-
# on_white
|
24
|
+
# IMPORTANT! Do not mixin Ansi::Code, instead use {ANSI::Mixin}.
|
71
25
|
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
# == Acknowledgement
|
75
|
-
#
|
76
|
-
# This library is a partial adaptation of ANSIColor by Florian Frank.
|
77
|
-
#
|
78
|
-
# ANSIColor Copyright (c) 2002 Florian Frank
|
79
|
-
#
|
80
|
-
# == Developer's Notes
|
81
|
-
#
|
82
|
-
# TODO: Any ANSI codes left to add? Modes?
|
26
|
+
# See {ANSI::Code::CHART} for list of all supported codes.
|
83
27
|
#
|
28
|
+
#--
|
84
29
|
# TODO: up, down, right, left, etc could have yielding methods too?
|
30
|
+
#++
|
85
31
|
|
86
32
|
module Code
|
87
33
|
extend self
|
88
34
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
UNDERLINE = "\e[4m"
|
95
|
-
UNDERSCORE = "\e[4m"
|
96
|
-
BLINK = "\e[5m"
|
97
|
-
RAPID = "\e[6m" # not widely implemented
|
98
|
-
REVERSE = "\e[7m"
|
99
|
-
NEGATIVE = "\e[7m" # alternate to reverse because of String#reverse
|
100
|
-
CONCEALED = "\e[8m"
|
101
|
-
STRIKE = "\e[9m" # not widely implemented
|
102
|
-
|
103
|
-
BLACK = "\e[30m"
|
104
|
-
RED = "\e[31m"
|
105
|
-
GREEN = "\e[32m"
|
106
|
-
YELLOW = "\e[33m"
|
107
|
-
BLUE = "\e[34m"
|
108
|
-
MAGENTA = "\e[35m"
|
109
|
-
CYAN = "\e[36m"
|
110
|
-
WHITE = "\e[37m"
|
111
|
-
|
112
|
-
ON_BLACK = "\e[40m"
|
113
|
-
ON_RED = "\e[41m"
|
114
|
-
ON_GREEN = "\e[42m"
|
115
|
-
ON_YELLOW = "\e[43m"
|
116
|
-
ON_BLUE = "\e[44m"
|
117
|
-
ON_MAGENTA = "\e[45m"
|
118
|
-
ON_CYAN = "\e[46m"
|
119
|
-
ON_WHITE = "\e[47m"
|
120
|
-
|
121
|
-
# Save current cursor positon.
|
122
|
-
SAVE = "\e[s"
|
123
|
-
|
124
|
-
# Restore saved cursor positon.
|
125
|
-
RESTORE = "\e[u"
|
126
|
-
|
127
|
-
# Clear to the end of the current line.
|
128
|
-
CLEAR_LINE = "\e[K"
|
129
|
-
|
130
|
-
# Clear to the end of the current line.
|
131
|
-
CLR = "\e[K"
|
132
|
-
|
133
|
-
# Clear the screen and move cursor to home.
|
134
|
-
CLEAR_SCREEN = "\e[2J"
|
135
|
-
|
136
|
-
# Clear the screen and move cursor to home.
|
137
|
-
CLS = "\e[2J"
|
35
|
+
# include ANSI Constants
|
36
|
+
include Constants
|
37
|
+
|
38
|
+
# Regexp for matching most ANSI codes.
|
39
|
+
PATTERN = /\e\[(\d+)m/
|
138
40
|
|
41
|
+
# ANSI clear code.
|
42
|
+
ENDCODE = "\e[0m"
|
43
|
+
|
44
|
+
# List of primary styles.
|
139
45
|
def self.styles
|
140
46
|
%w{bold dark italic underline underscore blink rapid reverse negative concealed strike}
|
141
47
|
end
|
142
48
|
|
49
|
+
# List of primary colors.
|
50
|
+
def self.colors
|
51
|
+
%w{black red green yellow blue magenta cyan white}
|
52
|
+
end
|
53
|
+
|
54
|
+
=begin
|
143
55
|
styles.each do |style|
|
144
56
|
module_eval <<-END, __FILE__, __LINE__
|
145
57
|
def #{style}(string=nil)
|
146
58
|
if string
|
59
|
+
return string unless $ansi
|
147
60
|
#warn "use ANSI block notation for future versions"
|
148
|
-
return "\#{#{style.upcase}}\#{string}\#{
|
61
|
+
return "\#{#{style.upcase}}\#{string}\#{ENDCODE}"
|
149
62
|
end
|
150
63
|
if block_given?
|
151
|
-
return
|
64
|
+
return yield unless $ansi
|
65
|
+
return "\#{#{style.upcase}}\#{yield}\#{ENDCODE}"
|
152
66
|
end
|
153
67
|
#{style.upcase}
|
154
68
|
end
|
155
69
|
END
|
156
70
|
end
|
71
|
+
=end
|
157
72
|
|
158
|
-
|
159
|
-
%w{black red green yellow blue magenta cyan white}
|
160
|
-
end
|
161
|
-
|
73
|
+
=begin
|
162
74
|
# Dynamically create color methods.
|
163
75
|
|
164
76
|
colors.each do |color|
|
165
77
|
module_eval <<-END, __FILE__, __LINE__
|
166
78
|
def #{color}(string=nil)
|
167
79
|
if string
|
80
|
+
return string unless $ansi
|
168
81
|
#warn "use ANSI block notation for future versions"
|
169
|
-
return "\#{#{color.upcase}}\#{string}\#{
|
82
|
+
return "\#{#{color.upcase}}\#{string}\#{ENDCODE}"
|
170
83
|
end
|
171
84
|
if block_given?
|
172
|
-
return
|
85
|
+
return yield unless $ansi
|
86
|
+
return "\#{#{color.upcase}}\#{yield}\#{ENDCODE}"
|
173
87
|
end
|
174
88
|
#{color.upcase}
|
175
89
|
end
|
176
90
|
|
177
91
|
def on_#{color}(string=nil)
|
178
92
|
if string
|
93
|
+
return string unless $ansi
|
179
94
|
#warn "use ANSI block notation for future versions"
|
180
|
-
return "\#{ON_#{color.upcase}}\#{string}\#{
|
95
|
+
return "\#{ON_#{color.upcase}}\#{string}\#{ENDCODE}"
|
181
96
|
end
|
182
97
|
if block_given?
|
183
|
-
return
|
98
|
+
return yield unless $ansi
|
99
|
+
return "\#{ON_#{color.upcase}}\#{yield}\#{ENDCODE}"
|
184
100
|
end
|
185
101
|
ON_#{color.upcase}
|
186
102
|
end
|
187
103
|
END
|
188
104
|
end
|
105
|
+
=end
|
189
106
|
|
190
|
-
#
|
107
|
+
# Return ANSI code given a list of symbolic names.
|
108
|
+
def [](*codes)
|
109
|
+
code(*codes)
|
110
|
+
end
|
191
111
|
|
112
|
+
# Dynamically create color on color methods.
|
113
|
+
#
|
114
|
+
# @deprecated
|
115
|
+
#
|
192
116
|
colors.each do |color|
|
193
117
|
colors.each do |on_color|
|
194
118
|
module_eval <<-END, __FILE__, __LINE__
|
195
119
|
def #{color}_on_#{on_color}(string=nil)
|
196
120
|
if string
|
121
|
+
return string unless $ansi
|
197
122
|
#warn "use ANSI block notation for future versions"
|
198
|
-
return #{color.upcase} + ON_#{color.upcase} + string +
|
123
|
+
return #{color.upcase} + ON_#{color.upcase} + string + ENDCODE
|
199
124
|
end
|
200
125
|
if block_given?
|
201
|
-
|
126
|
+
return yield unless $ansi
|
127
|
+
#{color.upcase} + ON_#{on_color.upcase} + yield.to_s + ENDCODE
|
202
128
|
else
|
203
129
|
#{color.upcase} + ON_#{on_color.upcase}
|
204
130
|
end
|
@@ -207,45 +133,35 @@ module ANSI
|
|
207
133
|
end
|
208
134
|
end
|
209
135
|
|
210
|
-
#
|
211
|
-
def
|
212
|
-
|
213
|
-
end
|
214
|
-
|
215
|
-
# Reset code.
|
216
|
-
def reset
|
217
|
-
RESET
|
218
|
-
end
|
219
|
-
|
220
|
-
# Save current cursor positon.
|
221
|
-
def save
|
222
|
-
SAVE
|
223
|
-
end
|
136
|
+
# Use method missing to dispatch ANSI code methods.
|
137
|
+
def method_missing(code, *args, &blk)
|
138
|
+
esc = nil
|
224
139
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
# Clear to the end of the current line.
|
231
|
-
def clear_line
|
232
|
-
CLEAR_LINE
|
233
|
-
end
|
234
|
-
|
235
|
-
# Clear to the end of the current line.
|
236
|
-
def clr
|
237
|
-
CLR
|
238
|
-
end
|
140
|
+
if CHART.key?(code)
|
141
|
+
esc = "\e[#{CHART[code]}m"
|
142
|
+
elsif SPECIAL_CHART.key?(code)
|
143
|
+
esc = SPECIAL_CHART[code]
|
144
|
+
end
|
239
145
|
|
240
|
-
|
241
|
-
|
242
|
-
|
146
|
+
if esc
|
147
|
+
if string = args.first
|
148
|
+
return string unless $ansi
|
149
|
+
#warn "use ANSI block notation for future versions"
|
150
|
+
return "#{esc}#{string}#{ENDCODE}"
|
151
|
+
end
|
152
|
+
if block_given?
|
153
|
+
return yield unless $ansi
|
154
|
+
return "#{esc}#{yield}#{ENDCODE}"
|
155
|
+
end
|
156
|
+
esc
|
157
|
+
else
|
158
|
+
super(code, *args, &blk)
|
159
|
+
end
|
243
160
|
end
|
244
161
|
|
245
|
-
#
|
246
|
-
|
247
|
-
|
248
|
-
end
|
162
|
+
# TODO: How to deal with position codes when $ansi is false?
|
163
|
+
# Should we reaise an error or just not push the codes?
|
164
|
+
# For now, we will leave this it as is.
|
249
165
|
|
250
166
|
# Like +move+ but returns to original positon after
|
251
167
|
# yielding the block.
|
@@ -292,127 +208,140 @@ module ANSI
|
|
292
208
|
# "\e[#;#R"
|
293
209
|
#end
|
294
210
|
|
295
|
-
# Apply
|
211
|
+
# Apply ANSI codes to a first argument or block value.
|
296
212
|
#
|
297
|
-
#
|
213
|
+
# @example
|
214
|
+
# ansi("Valentine", :red, :on_white)
|
298
215
|
#
|
299
|
-
|
300
|
-
|
301
|
-
codes.each do |code|
|
302
|
-
s << "\e[#{TABLE[code]}m"
|
303
|
-
end
|
304
|
-
s << yield.to_s
|
305
|
-
s << CLEAR
|
306
|
-
end
|
307
|
-
|
308
|
-
# Alternate term for #style.
|
309
|
-
alias_method :color, :style
|
310
|
-
|
216
|
+
# @example
|
217
|
+
# ansi(:red, :on_white){ "Valentine" }
|
311
218
|
#
|
312
|
-
|
219
|
+
# @return [String]
|
220
|
+
# String wrapped ANSI code.
|
221
|
+
#
|
222
|
+
def ansi(*codes) #:yield:
|
313
223
|
if block_given?
|
314
|
-
yield.
|
224
|
+
string = yield.to_s
|
315
225
|
else
|
316
|
-
|
226
|
+
string = codes.shift.to_s
|
317
227
|
end
|
228
|
+
|
229
|
+
return string unless $ansi
|
230
|
+
|
231
|
+
code(*codes) + string + ENDCODE
|
318
232
|
end
|
319
233
|
|
234
|
+
# Remove ANSI codes from string or block value.
|
320
235
|
#
|
321
|
-
|
322
|
-
|
323
|
-
#
|
324
|
-
|
325
|
-
|
236
|
+
# @param [String]
|
237
|
+
# String from which to remove ANSI codes.
|
238
|
+
#
|
239
|
+
# @return [String]
|
240
|
+
# String wrapped ANSI code.
|
241
|
+
#
|
242
|
+
#--
|
243
|
+
# TODO: Allow selective removal using *codes argument?
|
244
|
+
#++
|
245
|
+
def unansi(string=nil) #:yield:
|
326
246
|
if block_given?
|
327
|
-
yield.
|
328
|
-
elsif string
|
329
|
-
string.gsub(PATTERN, '')
|
247
|
+
string = yield.to_s
|
330
248
|
else
|
331
|
-
|
249
|
+
string = string.to_s
|
332
250
|
end
|
251
|
+
string.gsub(PATTERN, '')
|
333
252
|
end
|
334
253
|
|
335
|
-
#
|
336
|
-
# rather than a block. The primary purpose of this method
|
337
|
-
# is to speed up the String#ansi call.
|
254
|
+
# Alias for #ansi method.
|
338
255
|
#
|
339
|
-
#
|
256
|
+
# @deprecated
|
257
|
+
# Here for backward scompatibility.
|
258
|
+
alias_method :style, :ansi
|
259
|
+
|
260
|
+
# Alias for #unansi method.
|
261
|
+
#
|
262
|
+
# @deprecated
|
263
|
+
# Here for backwards compatibility.
|
264
|
+
alias_method :unstyle, :unansi
|
265
|
+
|
266
|
+
# Alternate term for #ansi.
|
267
|
+
#
|
268
|
+
# @deprecated
|
269
|
+
# May change in future definition.
|
270
|
+
alias_method :color, :ansi
|
271
|
+
|
272
|
+
# Alias for unansi.
|
340
273
|
#
|
341
|
-
|
342
|
-
|
274
|
+
# @deprecated
|
275
|
+
# May change in future definition.
|
276
|
+
alias_method :uncolor, :unansi
|
277
|
+
|
278
|
+
# Look-up code from chart, or if Integer simply pass through.
|
279
|
+
# Also resolves :random and :on_random.
|
280
|
+
#
|
281
|
+
# @param codes [Array<Symbol,Integer]
|
282
|
+
# Symbols or integers to covnert to ANSI code.
|
283
|
+
#
|
284
|
+
# @return [String] ANSI code
|
285
|
+
def code(*codes)
|
286
|
+
list = []
|
343
287
|
codes.each do |code|
|
344
|
-
|
288
|
+
list << \
|
289
|
+
case code
|
290
|
+
when Integer
|
291
|
+
code
|
292
|
+
when Array
|
293
|
+
rgb(*code)
|
294
|
+
when :random
|
295
|
+
random
|
296
|
+
when :on_random
|
297
|
+
random(true)
|
298
|
+
else
|
299
|
+
CHART[code.to_sym]
|
300
|
+
end
|
345
301
|
end
|
346
|
-
|
347
|
-
s << CLEAR
|
302
|
+
"\e[" + (list * ";") + "m"
|
348
303
|
end
|
349
304
|
|
350
|
-
#
|
351
|
-
#
|
352
|
-
|
353
|
-
|
305
|
+
# Provides a random primary ANSI color.
|
306
|
+
#
|
307
|
+
# @param background [Boolean]
|
308
|
+
# Use `true` for background color, otherwise foreground color.
|
309
|
+
#
|
310
|
+
# @return [Integer] ANSI color number
|
311
|
+
def random(background=false)
|
312
|
+
(background ? 40 : 30) + rand(8)
|
354
313
|
end
|
355
314
|
|
356
|
-
#
|
357
|
-
|
358
|
-
|
359
|
-
#
|
360
|
-
|
361
|
-
|
362
|
-
:
|
363
|
-
|
364
|
-
:dark => 2,
|
365
|
-
:italic => 3,
|
366
|
-
:underline => 4,
|
367
|
-
:underscore => 4,
|
368
|
-
:blink => 5,
|
369
|
-
:rapid => 6,
|
370
|
-
:reverse => 7,
|
371
|
-
:negative => 7,
|
372
|
-
:concealed => 8,
|
373
|
-
:strike => 9,
|
374
|
-
:black => 30,
|
375
|
-
:red => 31,
|
376
|
-
:green => 32,
|
377
|
-
:yellow => 33,
|
378
|
-
:blue => 34,
|
379
|
-
:magenta => 35,
|
380
|
-
:cyan => 36,
|
381
|
-
:white => 37,
|
382
|
-
:on_black => 40,
|
383
|
-
:on_red => 41,
|
384
|
-
:on_green => 42,
|
385
|
-
:on_yellow => 43,
|
386
|
-
:on_blue => 44,
|
387
|
-
:on_magenta => 45,
|
388
|
-
:on_cyan => 46,
|
389
|
-
:on_white => 47
|
390
|
-
}
|
391
|
-
end
|
315
|
+
# Creates an xterm-256 color from rgb value.
|
316
|
+
#
|
317
|
+
# @param background [Boolean]
|
318
|
+
# Use `true` for background color, otherwise foreground color.
|
319
|
+
#
|
320
|
+
def rgb(red, green, blue, background=false)
|
321
|
+
"#{background ? 48 : 38};5;#{rgb_value(red, green, blue)}"
|
322
|
+
end
|
392
323
|
|
393
|
-
|
394
|
-
|
324
|
+
# Creates an xterm-256 color from a CSS-style color string.
|
325
|
+
def hex(string, background=false)
|
326
|
+
string.tr!('#','')
|
327
|
+
x = (string.size == 6 ? 2 : 1)
|
328
|
+
r, g, b = [0,1,2].map{ |i| string[i*x,2].to_i(16) }
|
329
|
+
rgb(r, g, b, background)
|
330
|
+
end
|
395
331
|
|
396
|
-
|
397
|
-
class String
|
398
|
-
#
|
399
|
-
def ansi(*codes)
|
400
|
-
ANSI::Code.ansi(self, *codes)
|
401
|
-
end
|
332
|
+
private
|
402
333
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
334
|
+
# Gets closest xterm-256 color.
|
335
|
+
def rgb_256(r, g, b)
|
336
|
+
r, g, b = [r, g, b].map{ |c| rgb_valid(c); (6 * (c.to_f / 256.0)).to_i }
|
337
|
+
v = (r * 36 + g * 6 + b + 16).abs
|
338
|
+
raise ArgumentError, "RGB value outside 0-255 range" if v > 255
|
339
|
+
v
|
340
|
+
end
|
407
341
|
|
408
|
-
#
|
409
|
-
def unansi
|
410
|
-
ANSI::Code.unansi(self)
|
411
342
|
end
|
412
343
|
|
413
344
|
#
|
414
|
-
|
415
|
-
replace(unansi)
|
416
|
-
end
|
345
|
+
extend Code
|
417
346
|
end
|
418
347
|
|