sc-ansi 1.0.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.
- 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
|