sc-ansi 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +54 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/lib/ansi.rb +177 -0
- data/lib/ansi/code.rb +91 -0
- data/lib/ansi/color.rb +127 -0
- data/lib/ansi/cursor.rb +26 -0
- data/lib/ansi/display.rb +54 -0
- data/lib/ansi/match.rb +35 -0
- data/lib/ansi/vt100.rb +177 -0
- data/lib/core_ext/object.rb +15 -0
- data/lib/core_ext/string.rb +34 -0
- data/lib/sc-ansi.rb +9 -0
- data/sc-ansi.gemspec +79 -0
- data/spec/lib/ansi/color_spec.rb +102 -0
- data/spec/lib/ansi/cursor_spec.rb +37 -0
- data/spec/lib/ansi/display_spec.rb +21 -0
- data/spec/lib/ansi/match_spec.rb +53 -0
- data/spec/lib/ansi_spec.rb +44 -0
- data/spec/lib/core_ext/object_spec.rb +19 -0
- data/spec/lib/core_ext/string_spec.rb +68 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- metadata +122 -0
data/lib/ansi/cursor.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module ANSI
|
2
|
+
# Defines ANSI escape codes relating to cursor movement:
|
3
|
+
#
|
4
|
+
# move_to - accepts an X and Y screen location; X is the column and Y is the row.
|
5
|
+
# move - accepts a key (A, B, C, D) and an amount which defaults to 1.
|
6
|
+
# move_up - accepts an amount, which defaults to 1.
|
7
|
+
# move_down - accepts an amount, which defaults to 1.
|
8
|
+
# move_right - accepts an amount, which defaults to 1.
|
9
|
+
# move_left - accepts an amount, which defaults to 1.
|
10
|
+
#
|
11
|
+
# save_cursor_position - saves the current cursor position.
|
12
|
+
# restore_cursor_position - restores the cursor position.
|
13
|
+
#
|
14
|
+
module Cursor
|
15
|
+
ANSI.define('move_to') { |x, y| "\e[#{y || 0};#{x || 0}H" }
|
16
|
+
|
17
|
+
ANSI.define('move') { |key, amt| "\e[#{amt || 1}#{key}" }
|
18
|
+
ANSI.define('move_up', 'cursor_up', 'cuu') { |amt| move('A', amt) }
|
19
|
+
ANSI.define('move_down', 'cursor_down', 'cud') { |amt| move('B', amt) }
|
20
|
+
ANSI.define('move_right', 'cursor_forward', 'cuf') { |amt| move('C', amt) }
|
21
|
+
ANSI.define('move_left', 'cursor_backward', 'cub') { |amt| move('D', amt) }
|
22
|
+
|
23
|
+
ANSI.define('save_cursor_position') { "\e[s" }
|
24
|
+
ANSI.define('restore_cursor_position') { "\e[u" }
|
25
|
+
end
|
26
|
+
end
|
data/lib/ansi/display.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module ANSI
|
2
|
+
# Defines ANSI codes for changing screen resolution. Sequences with the following names are created:
|
3
|
+
#
|
4
|
+
# * erase_display, clear_display, clear, cls
|
5
|
+
# * Clears the screen.
|
6
|
+
# * erase_line, clear_line, clr
|
7
|
+
# * Erases a line beginning with the cursor position.
|
8
|
+
# * set_mode, mode
|
9
|
+
# * Sets a particular display mode. Expects a numeric value.
|
10
|
+
# * unset_mode, reset_mode
|
11
|
+
# * Resets a specified display mode. Expects a numeric value.
|
12
|
+
#
|
13
|
+
# set_40x25m - enters 40x25 monochrome mode.
|
14
|
+
# set_40x25 - enters 40x25 color mode.
|
15
|
+
# set_80x25m - enters 80x25 monochrome mode.
|
16
|
+
# set_320x200_4 - enters 320x200 4-color mode.
|
17
|
+
# set_320x200m - enters 320x200 monochrome mode.
|
18
|
+
# set_320x200 - enters 320x200 color mode.
|
19
|
+
# set_320x200_256 - enters 320x200 256-color mode.
|
20
|
+
# set_640x200m - enters 640x200 monochrome mode.
|
21
|
+
# set_640x200 - enters 640x200 color mode.
|
22
|
+
# set_640x350m - enters 640x350 monochrome mode.
|
23
|
+
# set_640x350 - enters 640x350 color mode.
|
24
|
+
# set_640x480m - enters 640x480 monochrome mode.
|
25
|
+
# set_640x480 - enters 640x480 color mode.
|
26
|
+
#
|
27
|
+
# All of the above modes also have an unset_ or reset_ counterpart.
|
28
|
+
#
|
29
|
+
# wrap - turns on word wrapping.
|
30
|
+
# unwrap - turns off word wrapping.
|
31
|
+
#
|
32
|
+
module Display
|
33
|
+
ANSI.define("erase_display", "clear_display", "clear", "cls") { "\e[2J" }
|
34
|
+
ANSI.define("erase_line", "clear_line", "clr") { "\e[K" }
|
35
|
+
|
36
|
+
# Various set and unset/reset methods for display modes.
|
37
|
+
# set_320x200, unset_320x200, reset_320x200, etc.
|
38
|
+
{ "set_" => 'h', '' => 'h', "unset_" => 'l', "reset_" => 'l'}.each do |prefix, symbol|
|
39
|
+
ANSI.define("#{prefix}mode") { |value| "\e[=#{value || 0}#{symbol}" }
|
40
|
+
|
41
|
+
%w(40x25m 40x25 80x25m 80x25 320x200_4 320x200m 640x200m).each_with_index do |mode, index|
|
42
|
+
next if prefix == ""
|
43
|
+
ANSI.define("#{prefix}#{mode}") { send("#{prefix}mode", index) }
|
44
|
+
# (ie set_40x25m => 0, set_320x200_4 => 4)
|
45
|
+
end
|
46
|
+
%w(320x200 640x200 640x350m 640x350 640x480m 640x480 320x200_256).each_with_index do |mode, index|
|
47
|
+
next if prefix == ""
|
48
|
+
ANSI.define("#{prefix}#{mode}") { send("#{prefix}mode", index+13) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
ANSI.define("wrap") { set_mode(7) }
|
52
|
+
ANSI.define("unwrap") { unset_mode(7) }
|
53
|
+
end
|
54
|
+
end
|
data/lib/ansi/match.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module ANSI
|
2
|
+
class Match
|
3
|
+
attr_reader :codes, :args
|
4
|
+
|
5
|
+
# An object is considered to be equal to an ANSI::Match if:
|
6
|
+
# - it is an instance of ANSI::Match and both its arguments and relevant instances of ANSI::Code are equal.
|
7
|
+
# - it is an instance of ANSI::Code which is contained in the #codes array of this ANSI::Match.
|
8
|
+
def ==(other)
|
9
|
+
if other.kind_of?(ANSI::Match)
|
10
|
+
other.codes == @codes && other.args == @args
|
11
|
+
elsif other.kind_of?(ANSI::Code)
|
12
|
+
@codes.include?(other)
|
13
|
+
else
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"#<ANSI::Match(#{@codes.join("|")}) args=#{@args.inspect}>"
|
20
|
+
end
|
21
|
+
|
22
|
+
alias to_s inspect
|
23
|
+
|
24
|
+
def initialize(*args)
|
25
|
+
args.flatten!
|
26
|
+
@args = args
|
27
|
+
@codes = []
|
28
|
+
end
|
29
|
+
|
30
|
+
# Shorthand for adding an ANSI::Code to the #codes array.
|
31
|
+
def <<(code)
|
32
|
+
@codes << code
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/ansi/vt100.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
module ANSI
|
2
|
+
# Defines escape sequences related VT100 terminals as well as VT52 compatibility mode. These codes
|
3
|
+
# come from the VT100 user manual. Constants are created automatically using the UPPERCASE name of
|
4
|
+
# each code name. For instance, both the "vt100_set_uk_g0_charset" and "setukg0" names (which both
|
5
|
+
# refer to the same escape sequence) are converted to the constants VT100_SET_UK_G0_CHARSET and
|
6
|
+
# SETUKG0, respectively.
|
7
|
+
#
|
8
|
+
# View the source of this file to see the full listing (it's not painful, I promise).
|
9
|
+
#
|
10
|
+
module VT100
|
11
|
+
ANSI.define("vt100_newline_mode") { "\e[20h" }
|
12
|
+
ANSI.define("vt100_set_cursor_key_application") { "\e[?1h" }
|
13
|
+
ANSI.define("vt100_set_columns_132") { "\e[?3h" }
|
14
|
+
ANSI.define("vt100_set_smooth_scrolling") { "\e[?4h" }
|
15
|
+
ANSI.define("vt100_set_reverse_video") { "\e[?5h" }
|
16
|
+
ANSI.define("vt100_set_origin_relative") { "\e[?6h" }
|
17
|
+
ANSI.define("vt100_set_autowrap") { "\e[?7h" }
|
18
|
+
ANSI.define("vt100_set_autorepeat") { "\e[?8h" }
|
19
|
+
ANSI.define("vt100_set_interlacing") { "\e[?9h" }
|
20
|
+
|
21
|
+
ANSI.define("vt100_set_line_feed_mode") { "\e[20l" }
|
22
|
+
ANSI.define("vt100_set_cursor_key_cursor") { "\e[?1l" }
|
23
|
+
ANSI.define("vt100_set_vt52") { "\e[?2l" }
|
24
|
+
ANSI.define("vt100_set_columns_80") { "\e[?3l" }
|
25
|
+
ANSI.define("vt100_set_jump_scrolling") { "\e[?4l" }
|
26
|
+
ANSI.define("vt100_set_normal_video") { "\e[?5l" }
|
27
|
+
ANSI.define("vt100_set_origin_absolute") { "\e[?6l" }
|
28
|
+
ANSI.define("vt100_reset_autowrap") { "\e[?7l" }
|
29
|
+
ANSI.define("vt100_reset_autorepeat") { "\e[?8l" }
|
30
|
+
ANSI.define("vt100_reset_interlacing") { "\e[?9l" }
|
31
|
+
|
32
|
+
ANSI.define("vt100_set_alt_keypad") { "\e=" }
|
33
|
+
ANSI.define("vt100_set_num_keypad") { "\e>" }
|
34
|
+
|
35
|
+
ANSI.define("vt100_set_uk_g0_charset", "setukg0") { "\e(A" }
|
36
|
+
ANSI.define("vt100_set_uk_g1_charset", "setukg1") { "\e)A" }
|
37
|
+
ANSI.define("vt100_set_us_g0_charset", "setusg0") { "\e(B" }
|
38
|
+
ANSI.define("vt100_set_us_g1_charset", "setusg1") { "\e)B" }
|
39
|
+
ANSI.define("vt100_set_g0_special_charset", "setspecg0") { "\e(0" }
|
40
|
+
ANSI.define("vt100_set_g1_special_charset", "setspecg1") { "\e)0" }
|
41
|
+
ANSI.define("vt100_set_g0_alt_char_rom", "setaltg0") { "\e(1" }
|
42
|
+
ANSI.define("vt100_set_g1_alt_char_rom", "setaltg1") { "\e)1" }
|
43
|
+
ANSI.define("vt100_set_g0_alt_char_rom_graphics", "setaltspecg0") { "\e(2" }
|
44
|
+
ANSI.define("vt100_set_g1_alt_char_rom_graphics", "setaltspecg1") { "\e)2" }
|
45
|
+
|
46
|
+
ANSI.define("vt100_single_shift_2", "ss2") { "\eN" }
|
47
|
+
ANSI.define("vt100_single_shift_3", "ss3") { "\eO" }
|
48
|
+
|
49
|
+
ANSI.define("vt100_char_attrs_off", "sgr0") { "\e[0m" }
|
50
|
+
ANSI.define("vt100_bold", "sgr1") { "\e[1m" }
|
51
|
+
ANSI.define("vt100_low_intensity", "sgr2") { "\e[2m" }
|
52
|
+
ANSI.define("vt100_underline", "sgr4") { "\e[4m" }
|
53
|
+
ANSI.define("vt100_blink", "sgr5") { "\e[5m" }
|
54
|
+
ANSI.define("vt100_reverse_video", "sgr7") { "\e[6m" }
|
55
|
+
ANSI.define("vt100_invisible_text", "sgr8") { "\e[8m" }
|
56
|
+
|
57
|
+
ANSI.define("vt100_set_top_and_bottom", "decstbm") { |a,b| "\e[#{a || 0};#{b || 0}r" }
|
58
|
+
|
59
|
+
ANSI.define("vt100_move_cursor_up", "cuu") { |amt| "\e[#{amt || 1}A" }
|
60
|
+
ANSI.define("vt100_move_cursor_down", "cud") { |amt| "\e[#{amt || 1}B" }
|
61
|
+
ANSI.define("vt100_move_cursor_left", "cuf") { |amt| "\e[#{amt || 1}C" }
|
62
|
+
ANSI.define("vt100_move_cursor_right", "cub") { |amt| "\e[#{amt || 1}D" }
|
63
|
+
ANSI.define("vt100_move_cursor_home", "cursorhome") { "\e[H" }
|
64
|
+
ANSI.define("vt100_move_cursor_to", "cup") { |line,col| "\e[#{line};#{col}H" }
|
65
|
+
ANSI.define("hvhome") { "\e[f" }
|
66
|
+
ANSI.define("vt100_up", "ind") { "\eD" }
|
67
|
+
ANSI.define("vt100_down", "ri") { "\eM" }
|
68
|
+
ANSI.define("vt100_next_line", "nel") { "\eE" }
|
69
|
+
ANSI.define("vt100_save_cursor", "decsc") { "\e7" }
|
70
|
+
ANSI.define("vt100_restore_cursor", "decrc") { "\e8" }
|
71
|
+
|
72
|
+
ANSI.define("vt100_set_tab", "hts") { "\eH" }
|
73
|
+
ANSI.define("vt100_clear_tab", "tbc") { "\e[0g" }
|
74
|
+
ANSI.define("vt100_clear_all_tabs", "tbca") { "\e[3g" }
|
75
|
+
|
76
|
+
ANSI.define("vt100_dbl_height_top") { "\e#3" }
|
77
|
+
ANSI.define("vt100_dbl_height_btm") { "\e#4" }
|
78
|
+
ANSI.define("vt100_sgl_width") { "\e#5" }
|
79
|
+
ANSI.define("vt100_dbl_width") { "\e#6" }
|
80
|
+
|
81
|
+
ANSI.define("vt100_clear_right", "el0") { "\e[0K" }
|
82
|
+
ANSI.define("vt100_clear_left", "el1") { "\e[1K" }
|
83
|
+
ANSI.define("vt100_clear_line", "el2") { "\e[2K" }
|
84
|
+
ANSI.define("vt100_clear_down", "ed0") { "\e[0J" }
|
85
|
+
ANSI.define("vt100_clear_up", "ed1") { "\e[1J" }
|
86
|
+
ANSI.define("vt100_clear_screen","ed2") { "\e[2J" }
|
87
|
+
|
88
|
+
ANSI.define("vt100_device_status_report", "dsr") { "\e5n" }
|
89
|
+
# Responses from terminal:
|
90
|
+
ANSI.define("vt100_device_status_ok") { "\e0n" }
|
91
|
+
ANSI.define("vt100_device_status_not_ok") { "\e3n" }
|
92
|
+
|
93
|
+
ANSI.define("vt100_get_cursor_pos") { "\e6n" }
|
94
|
+
# Response from terminal:
|
95
|
+
ANSI.define("vt100_cursor_position") { |line, col| "\e#{line || 0};#{col || 0}R" }
|
96
|
+
|
97
|
+
ANSI.define("vt100_get_terminal_type") { "\e[c" }
|
98
|
+
# Response from terminal:
|
99
|
+
ANSI.define("vt100_terminal_type") { |val| "\e[?1;#{val}0c" }
|
100
|
+
|
101
|
+
ANSI.define("vt100_reset_to_init") { "\ec" }
|
102
|
+
|
103
|
+
ANSI.define("vt100_screen_alignment_display") { "\e#8" }
|
104
|
+
ANSI.define("vt100_confidence_power_up_test") { "\e[2;1y" }
|
105
|
+
ANSI.define("vt100_confidence_loopback_test") { "\e[2;2y" }
|
106
|
+
ANSI.define("vt100_repeat_power_up_test") { "\e[2;9y" }
|
107
|
+
ANSI.define("vt100_repeat_loopback_test") { "\e[2;10y" }
|
108
|
+
|
109
|
+
ANSI.define("vt100_all_leds_off", "decll0") { "\e[0q" }
|
110
|
+
ANSI.define("vt100_led1_on", "decll1") { "\e[1q" }
|
111
|
+
ANSI.define("vt100_led2_on", "decll2") { "\e[2q" }
|
112
|
+
ANSI.define("vt100_led3_on", "decll3") { "\e[3q" }
|
113
|
+
ANSI.define("vt100_led4_on", "decll4") { "\e[4q" }
|
114
|
+
|
115
|
+
# Codes for use in VT52 compatibility mode
|
116
|
+
ANSI.define("vt52_enter_ansi_mode", "vt100_exit_ansi_mode", "vt52_setansi") { "\e<" }
|
117
|
+
ANSI.define("vt52_enter_alt_keypad_mode", "vt52_altkeypad") { "\e=" }
|
118
|
+
ANSI.define("vt52_exit_alt_keypad_mode", "vt52_numkeypad") { "\e>" }
|
119
|
+
ANSI.define("vt52_use_special_graphics_charset", "vt52_setgr") { "\eF" }
|
120
|
+
ANSI.define("vt52_use_normal_charset", "vt52_resetgr") { "\eG" }
|
121
|
+
ANSI.define("vt52_move_cursor_up", "vt52_cursorup") { "\eA" }
|
122
|
+
ANSI.define("vt52_move_cursor_down", "vt52_cursordown") { "\eB" }
|
123
|
+
ANSI.define("vt52_move_cursor_right", "vt52_cursorrt") { "\eC" }
|
124
|
+
ANSI.define("vt52_move_cursor_left", "vt52_cursorlf") { "\eD" }
|
125
|
+
ANSI.define("vt52_move_cursor_home", "vt52_cursorhome") { "\eH" }
|
126
|
+
ANSI.define("vt52_generate_reverse_linefeed", "vt52_revindex") { "\eI" }
|
127
|
+
ANSI.define("vt52_erase_to_eol", "vt52_cleareol") { "\eK" }
|
128
|
+
ANSI.define("vt52_erase_to_eos", "vt52_cleareos") { "\eJ" }
|
129
|
+
ANSI.define("vt52_identify", "vt52_ident") { "\eZ" }
|
130
|
+
ANSI.define("vt52_identify_response", "vt52_identresp") { "\e/Z" }
|
131
|
+
|
132
|
+
|
133
|
+
# VT100 Special Key Codes
|
134
|
+
#
|
135
|
+
# These are sent from the terminal back to the computer when the particular key
|
136
|
+
# is pressed. Note that the numeric keypad keys send different codes in numeric
|
137
|
+
# mode than in alternate mode. See escape codes above to change keypad mode.
|
138
|
+
|
139
|
+
# Function keys:
|
140
|
+
ANSI.define("vt100_sp_pf1", "pf1") { "\eOP" }
|
141
|
+
ANSI.define("vt100_sp_pf2", "pf2") { "\eOQ" }
|
142
|
+
ANSI.define("vt100_sp_pf3", "pf3") { "\eOR" }
|
143
|
+
ANSI.define("vt100_sp_pf4", "pf4") { "\eOS" }
|
144
|
+
|
145
|
+
# Arrow keys:
|
146
|
+
ANSI.define("vt100_sp_up_reset") { "\eA" }
|
147
|
+
ANSI.define("vt100_sp_down_reset") { "\eB" }
|
148
|
+
ANSI.define("vt100_sp_right_reset") { "\eC" }
|
149
|
+
ANSI.define("vt100_sp_left_reset") { "\eD" }
|
150
|
+
ANSI.define("vt100_sp_up_set") { "\eOA" }
|
151
|
+
ANSI.define("vt100_sp_down_set") { "\eOB" }
|
152
|
+
ANSI.define("vt100_sp_right_set") { "\eOC" }
|
153
|
+
ANSI.define("vt100_sp_left_set") { "\eOD" }
|
154
|
+
|
155
|
+
# Numeric keypad keys:
|
156
|
+
ANSI.define("vt100_sp_num0") { "\eOp" }
|
157
|
+
ANSI.define("vt100_sp_num1") { "\eOq" }
|
158
|
+
ANSI.define("vt100_sp_num2") { "\eOr" }
|
159
|
+
ANSI.define("vt100_sp_num3") { "\eOs" }
|
160
|
+
ANSI.define("vt100_sp_num4") { "\eOt" }
|
161
|
+
ANSI.define("vt100_sp_num5") { "\eOu" }
|
162
|
+
ANSI.define("vt100_sp_num6") { "\eOv" }
|
163
|
+
ANSI.define("vt100_sp_num7") { "\eOw" }
|
164
|
+
ANSI.define("vt100_sp_num8") { "\eOx" }
|
165
|
+
ANSI.define("vt100_sp_num9") { "\eOy" }
|
166
|
+
ANSI.define("vt100_sp_num_minus") { "\eOm" }
|
167
|
+
ANSI.define("vt100_sp_num_comma") { "\eOl" }
|
168
|
+
ANSI.define("vt100_sp_num_period") { "\eOn" }
|
169
|
+
ANSI.define("vt100_sp_num_ctrl_m") { "\eOM" }
|
170
|
+
|
171
|
+
# Printing:
|
172
|
+
ANSI.define("vt100_sp_print_screen") { "\e[i" }
|
173
|
+
ANSI.define("vt100_sp_print_line") { "\e[1i" }
|
174
|
+
ANSI.define("vt100_sp_stop_print_log") { "\e[4i" }
|
175
|
+
ANSI.define("vt100_sp_start_print_log") { "\e[5i" }
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Object
|
2
|
+
unless defined?(instance_exec)
|
3
|
+
def instance_exec(*args, &block)
|
4
|
+
mname = "__instance_exec_#{Thread.current.object_id.abs}"
|
5
|
+
eigen = class << self; self; end
|
6
|
+
eigen.class_eval { define_method(mname, &block) }
|
7
|
+
begin
|
8
|
+
ret = send(mname, *args)
|
9
|
+
ensure
|
10
|
+
eigen.class_eval { undef_method(mname) } rescue nil
|
11
|
+
end
|
12
|
+
ret
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class String
|
2
|
+
prefix = "[]?><()#/"
|
3
|
+
ANSI_ESCAPE_SEQUENCE_RX = /\e([#{Regexp::escape prefix}]?)([0-9;\{\?\}]*)([0-#{Regexp::escape 176.chr}])/
|
4
|
+
|
5
|
+
# returns an array listing all detected ANSI sequences in self. These are instances of ANSI::Code.
|
6
|
+
def ansi_sequences
|
7
|
+
ANSI_ESCAPE_SEQUENCE_RX.each_match(self).collect do |match|
|
8
|
+
ANSI.recognize(match[0])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Creates a new String that is a copy of this String. Takes a block
|
13
|
+
# which will receive each occurrance of an ANSI escape sequence; the
|
14
|
+
# escape sequence is replaced by the return value of the block.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
# ANSI.red { "hello" }.replace_ansi do |match|
|
18
|
+
# case match
|
19
|
+
# when RED then "(red)"
|
20
|
+
# when RESET_COLOR then "(normal)"
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# #=> "(red)hello(normal)"
|
24
|
+
#
|
25
|
+
def replace_ansi
|
26
|
+
copy = self.dup
|
27
|
+
ANSI_ESCAPE_SEQUENCE_RX.each_match(copy).collect do |match|
|
28
|
+
ansi_match = ANSI.recognize(match[0])
|
29
|
+
result = yield ansi_match
|
30
|
+
copy.gsub!(match[0], result)
|
31
|
+
end
|
32
|
+
copy
|
33
|
+
end
|
34
|
+
end
|
data/lib/sc-ansi.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "ansi")
|
2
|
+
|
3
|
+
# This file is here as a way to differentiate between the sc-ansi gem and any other ANSI-related gem you may be
|
4
|
+
# harboring. If this is not true in your case, feel free to require 'ansi' directly. The other reason for this file
|
5
|
+
# is to take some confusion out of loading the gem from a Rails project, as Rails will automatically load a file
|
6
|
+
# whose name matches the gem. Yay.
|
7
|
+
module ANSI
|
8
|
+
|
9
|
+
end
|
data/sc-ansi.gemspec
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{sc-ansi}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Colin MacKenzie IV"]
|
12
|
+
s.date = %q{2010-08-05}
|
13
|
+
s.description = %q{Handles every aspect (that I could think of) of dealing with ANSI escape sequences.}
|
14
|
+
s.email = %q{sinisterchipmunk@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/ansi.rb",
|
27
|
+
"lib/ansi/code.rb",
|
28
|
+
"lib/ansi/color.rb",
|
29
|
+
"lib/ansi/cursor.rb",
|
30
|
+
"lib/ansi/display.rb",
|
31
|
+
"lib/ansi/match.rb",
|
32
|
+
"lib/ansi/vt100.rb",
|
33
|
+
"lib/core_ext/object.rb",
|
34
|
+
"lib/core_ext/string.rb",
|
35
|
+
"lib/sc-ansi.rb",
|
36
|
+
"sc-ansi.gemspec",
|
37
|
+
"spec/lib/ansi/color_spec.rb",
|
38
|
+
"spec/lib/ansi/cursor_spec.rb",
|
39
|
+
"spec/lib/ansi/display_spec.rb",
|
40
|
+
"spec/lib/ansi/match_spec.rb",
|
41
|
+
"spec/lib/ansi_spec.rb",
|
42
|
+
"spec/lib/core_ext/object_spec.rb",
|
43
|
+
"spec/lib/core_ext/string_spec.rb",
|
44
|
+
"spec/spec.opts",
|
45
|
+
"spec/spec_helper.rb"
|
46
|
+
]
|
47
|
+
s.homepage = %q{http://github.com/sinisterchipmunk/sc-ansi}
|
48
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = %q{1.3.6}
|
51
|
+
s.summary = %q{Handles every aspect (that I could think of) of dealing with ANSI escape sequences.}
|
52
|
+
s.test_files = [
|
53
|
+
"spec/lib/ansi/color_spec.rb",
|
54
|
+
"spec/lib/ansi/cursor_spec.rb",
|
55
|
+
"spec/lib/ansi/display_spec.rb",
|
56
|
+
"spec/lib/ansi/match_spec.rb",
|
57
|
+
"spec/lib/ansi_spec.rb",
|
58
|
+
"spec/lib/core_ext/object_spec.rb",
|
59
|
+
"spec/lib/core_ext/string_spec.rb",
|
60
|
+
"spec/spec_helper.rb"
|
61
|
+
]
|
62
|
+
|
63
|
+
if s.respond_to? :specification_version then
|
64
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
65
|
+
s.specification_version = 3
|
66
|
+
|
67
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
68
|
+
s.add_runtime_dependency(%q<sc-core-ext>, [">= 1.2.1"])
|
69
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<sc-core-ext>, [">= 1.2.1"])
|
72
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
73
|
+
end
|
74
|
+
else
|
75
|
+
s.add_dependency(%q<sc-core-ext>, [">= 1.2.1"])
|
76
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ANSI::Color do
|
4
|
+
include ANSI
|
5
|
+
|
6
|
+
context "a single fg color" do
|
7
|
+
it "should wrap a string using a block" do
|
8
|
+
red { "a string!" }.should == red + "a string!" + reset_color
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be added to String" do
|
12
|
+
"a string!".red.should == red + "a string!" + reset_color
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be added to Symbol" do
|
16
|
+
:a_string!.red.should == red + "a_string!" + reset_color
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "a single attribute color" do
|
21
|
+
it "should wrap a string using a block" do
|
22
|
+
blink { "a string!" }.should == blink + "a string!" + reset_color
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be added to String" do
|
26
|
+
"a string!".blink.should == blink + "a string!" + reset_color
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be added to Symbol" do
|
30
|
+
:a_string!.blink.should == blink + "a_string!" + reset_color
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "a single bg color" do
|
35
|
+
it "should wrap a string using a block" do
|
36
|
+
bg_red { "a string!" }.should == bg_red + "a string!" + reset_color
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be added to String" do
|
40
|
+
"a string!".bg_red.should == bg_red + "a string!" + reset_color
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be added to Symbol" do
|
44
|
+
:a_string!.bg_red.should == bg_red + "a_string!" + reset_color
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "a combo of attribute, fg_color" do
|
49
|
+
it "should wrap a string using a block" do
|
50
|
+
blink_red { "a string!" }.should == blink_red + "a string!" + reset_color
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be added to String" do
|
54
|
+
"a string!".blink_red.should == blink_red + "a string!" + reset_color
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be added to Symbol" do
|
58
|
+
:a_string!.blink_red.should == blink_red + "a_string!" + reset_color
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "a combo of fg_color, bg_color" do
|
63
|
+
it "should wrap a string using a block" do
|
64
|
+
red_on_white { "a string!" }.should == red_on_white + "a string!" + reset_color
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be added to String" do
|
68
|
+
"a string!".red_on_white.should == red_on_white + "a string!" + reset_color
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be added to Symbol" do
|
72
|
+
:a_string!.red_on_white.should == red_on_white + "a_string!" + reset_color
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "a combo of attribute, fg_color, bg_color" do
|
77
|
+
it "should wrap a string using a block" do
|
78
|
+
blink_red_on_white { "a string!" }.should == blink_red_on_white + "a string!" + reset_color
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be added to String" do
|
82
|
+
"a string!".blink_red_on_white.should == blink_red_on_white + "a string!" + reset_color
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should be added to Symbol" do
|
86
|
+
:a_string!.blink_red_on_white.should == blink_red_on_white + "a_string!" + reset_color
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should produce red" do
|
91
|
+
red.should == "\e[31m"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should set color mode" do
|
95
|
+
set_color(1).should == "\e[1m"
|
96
|
+
set_color(1, 2, 3).should == "\e[1;2;3m"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should reset color mode" do
|
100
|
+
reset_color.should == "\e[0m"
|
101
|
+
end
|
102
|
+
end
|