terminal 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54b22e3e05336e785b66eaead924b54a341c3938
4
- data.tar.gz: 0a2f52dd360a0fafeb918ce605ba28c63202aac5
3
+ metadata.gz: ef903d157312bb149fac82a78546b0d92f7280a2
4
+ data.tar.gz: cfd561ae29ce4c0157cb8daf2226ca3f9c1e515f
5
5
  SHA512:
6
- metadata.gz: 65c72b0e4cbba9ff22208bbe619678d362391c22e213143825e9ed2e54ae211e7b3f30b72251408a9ffac04dae4f7484acd938d8d1c7864f87da286a3e90776a
7
- data.tar.gz: 056609e233229daeb9ee4b6f95c1cd84f76ce4a10591a97413da6370050061807bed57d291dd8f7e7875f054576620c677332d675dd3c667c09a937fb5d19956
6
+ metadata.gz: fafa7d5e0e0072b81e2f90ca3b91c300d11b7f71a51dfc62d2b22d3abbae2a5d8c322d8d5a2a181693d2e5ffff98acf3f8507ab931711ea9c043f311eab8a823
7
+ data.tar.gz: 85727be39d6e58c6dac422f02a567644eb337bdbeb4cec280a99a42634421daa8ec9a6e573b79b913d2f4cad868088b8f4c11c997d40e3d633cc87726aec21c3
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- terminal (0.3.2)
4
+ terminal (0.3.3)
5
5
  escape_utils (~> 1.0)
6
6
  gemoji (~> 2.0)
7
7
 
@@ -11,12 +11,15 @@
11
11
  white-space: pre-wrap;
12
12
  }
13
13
 
14
+ .term-fg1 { } /* don't bold beccause it looks weird */
15
+ .term-fg4 { text-decoration: underline; } /* underline */
16
+
14
17
  .term-fg30 { color: #666; } /* black (but we can't use black, so a diff color) */
15
18
  .term-fg31 { color: #e10c02; } /* red */
16
- .term-fg32 { color: #00bd02; } /* green */
19
+ .term-fg32 { color: #99ff5e; } /* green */
17
20
  .term-fg33 { color: #c6c502; } /* yellow */
18
21
  .term-fg34 { color: #8db7e0; } /* blue */
19
- .term-fg35 { color: #ceacde; } /* magenta */
22
+ .term-fg35 { color: #f271fb; } /* magenta */
20
23
  .term-fg36 { color: #00cdd9; } /* cyan */
21
24
 
22
25
  /* high intense colors */
@@ -25,6 +28,10 @@
25
28
 
26
29
  /* background colors */
27
30
  .term-bg42 { background: #99ff5f; }
31
+ .term-bg40 { background: #676767; }
32
+
33
+ /* custom foreground/background combos for readability */
34
+ .term-fg31.term-bg40 { color: #F8A39F; }
28
35
 
29
36
  /* xterm colors */
30
37
  .term-fgx16 { color: #000000; }
@@ -13,18 +13,29 @@ Usage:
13
13
 
14
14
  Help:
15
15
  $ terminal -h
16
+ $ terminal --help
17
+
18
+ Version:
19
+ $ terminal -v
20
+ $ terminal --version
16
21
 
17
22
  Preview in the browser:
18
23
  $ terminal --preview
19
24
 
20
- See https://buildboxhq.github.io/terminal for more information.
25
+ See https://buildbox.github.io/terminal for more information.
21
26
  usage
22
27
  end
23
28
 
29
+ def version
30
+ puts "terminal v#{Terminal::VERSION}"
31
+ end
32
+
24
33
  preview = ARGV.delete('--preview')
25
34
 
26
35
  if ($stdin.tty? && ARGV.empty?) || ARGV.delete('-h') || ARGV.delete('--help')
27
36
  help
37
+ elsif ARGV.delete('-v') || ARGV.delete('--version')
38
+ version
28
39
  else
29
40
  raw = ARGF.read
30
41
  rendered = Terminal.render(raw)
@@ -1,4 +1,4 @@
1
1
  #!/bin/bash
2
2
 
3
3
  echo -e "\033[90m$\033[0m curl -o /tmp/file.txt https://example.com/file.txt"
4
- curl -o /tmp/buildbox-agent.tar.gz https://github.com/buildboxhq/buildbox-agent/releases/download/v0.1-alpha/buildbox-agent-darwin-386.tar.gz
4
+ curl -o /tmp/buildbox-agent.tar.gz https://github.com/buildbox/buildbox-agent/releases/download/v0.1-alpha/buildbox-agent-darwin-386.tar.gz
@@ -1,4 +1,5 @@
1
1
  require "terminal/version"
2
+ require "terminal/cache"
2
3
  require "terminal/screen"
3
4
  require "terminal/renderer"
4
5
  require "terminal/cli"
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module Terminal
4
+ module Cache
5
+ extend self
6
+
7
+ def cache(table, key, &block)
8
+ @cache ||= {}
9
+ @cache[table] ||= {}
10
+ @cache[table][key] ||= yield
11
+ end
12
+ end
13
+ end
@@ -5,10 +5,16 @@ require 'emoji'
5
5
 
6
6
  module Terminal
7
7
  class Renderer
8
- EMOJI_UNICODE_REGEXP = /[\u{1f600}-\u{1f64f}]|[\u{2702}-\u{27b0}]|[\u{1f680}-\u{1f6ff}]|[\u{24C2}-\u{1F251}]|[\u{1f300}-\u{1f5ff}]/
9
- ESCAPE_CONTROL_CHARACTERS = "qQmKGgKAaBbCcDd"
10
8
  MEGABYTES = 1024 * 1024
11
9
 
10
+ EMOJI_UNICODE_REGEXP = /[\u{1f600}-\u{1f64f}]|[\u{2702}-\u{27b0}]|[\u{1f680}-\u{1f6ff}]|[\u{24C2}-\u{1F251}]|[\u{1f300}-\u{1f5ff}]/
11
+ EMOJI_IGNORE = [ "heavy_check_mark".freeze, "heavy_multiplication_x".freeze ]
12
+
13
+ ESCAPE_CONTROL_CHARACTERS = "qQmKGgKAaBbCcDd".freeze
14
+ ESCAPE_CAPTURE_REGEX = /\e\[(.*)([#{ESCAPE_CONTROL_CHARACTERS}])/
15
+
16
+ INTERESTING_PARTS_REGEX=/[\n\r\b]|\e\[[\d;]*[#{ESCAPE_CONTROL_CHARACTERS}]|./
17
+
12
18
  def initialize(output, options = {})
13
19
  @output = output
14
20
 
@@ -19,30 +25,14 @@ module Terminal
19
25
  end
20
26
 
21
27
  def render
22
- return "" if @output.nil? || @output.strip.length == 0
28
+ return "" if @output.nil?
23
29
 
24
30
  # First duplicate the string, because we're going to be editing and chopping it
25
31
  # up directly.
26
- output = @output.dup
32
+ output = @output.to_s.dup
27
33
 
28
- # Limit the entire size of the output to 4 meg
29
- max_total_size = 4 * MEGABYTES
30
- if output.bytesize > max_total_size
31
- output = output.byteslice(0, max_total_size)
32
- output << "\n\nWarning: Terminal has chopped off the rest of the build as it's over the allowed 4 megabyte limit for logs."
33
- end
34
-
35
- # Limit each line to (x) chars
36
- # TODO: Move this to the screen
37
- max_line_length = 50_000
38
- output = output.split("\n").map do |line|
39
- if line.length > max_line_length
40
- line = line[0..max_line_length]
41
- line << " Warning: Terminal has chopped the rest of this line off as it's over the allowed #{max_line_length} characters per line limit."
42
- else
43
- line
44
- end
45
- end.join("\n")
34
+ output = check_size(output)
35
+ output = check_line_lengths(output)
46
36
 
47
37
  # Force encoding on the output first
48
38
  force_encoding!(output)
@@ -54,17 +44,45 @@ module Terminal
54
44
  output = convert_screen_to_string
55
45
 
56
46
  # Escape any HTML
57
- output = escape_html(output)
47
+ escaped_html = escape_html(output)
58
48
 
59
49
  # Now convert the colors to HTML
60
- output = convert_to_html(output)
50
+ convert_to_html!(escaped_html)
61
51
 
62
52
  # And emojify
63
- replace_unicode_with_emoji(output)
53
+ replace_unicode_with_emoji!(escaped_html)
54
+
55
+ escaped_html
64
56
  end
65
57
 
66
58
  private
67
59
 
60
+ def check_size(output)
61
+ # Limit the entire size of the output to 4 meg
62
+ max_total_size = 4 * MEGABYTES
63
+ if output.bytesize > max_total_size
64
+ new_output = output.byteslice(0, max_total_size)
65
+ new_output << "\n\nWarning: Terminal has chopped off the rest of the build as it's over the allowed 4 megabyte limit for logs."
66
+ new_output
67
+ else
68
+ output
69
+ end
70
+ end
71
+
72
+ def check_line_lengths(output)
73
+ # Limit each line to (x) chars
74
+ # TODO: Move this to the screen
75
+ max_line_length = 50_000
76
+ output.split("\n".freeze).map do |line|
77
+ if line.length > max_line_length
78
+ line = line[0..max_line_length]
79
+ line << " Warning: Terminal has chopped the rest of this line off as it's over the allowed #{max_line_length} characters per line limit."
80
+ else
81
+ line
82
+ end
83
+ end.join("\n".freeze)
84
+ end
85
+
68
86
  def force_encoding!(string)
69
87
  string.force_encoding('UTF-8')
70
88
 
@@ -75,29 +93,58 @@ module Terminal
75
93
  end
76
94
  end
77
95
 
96
+ # Scan the string to create an array of interesting things, for example
97
+ # it would look like this:
98
+ # [ '\n', '\r', 'a', 'b', '\e123m' ]
99
+ def split_by_escape_character(string)
100
+ string.scan(INTERESTING_PARTS_REGEX)
101
+ end
102
+
78
103
  def render_to_screen(string)
79
104
  # The when cases are ordered by most likely, the lest checks it has to go
80
105
  # through before matching, the faster the render will be. Colors are
81
106
  # usually most likey, so that's first.
82
107
  split_by_escape_character(string).each do |char|
83
- # Hackers way of not having to run a regex over every
84
- # character.
85
- if char.length == 1
86
- case char
87
- when "\n"
108
+ if char == "\n".freeze
109
+ @screen.x = 0
110
+ @screen.y += 1
111
+ elsif char == "\r".freeze
112
+ @screen.x = 0
113
+ elsif char == "\b".freeze
114
+ @screen.x -= 1
115
+ elsif char[0] == "\e".freeze && char.length > 1
116
+ sequence = char.match(ESCAPE_CAPTURE_REGEX)
117
+
118
+ instruction = sequence[1]
119
+ code = sequence[2]
120
+
121
+ if code == "".freeze
122
+ # no-op - an empty \e
123
+ elsif code == "m".freeze
124
+ @screen.color(instruction)
125
+ elsif code == "G".freeze || code == "g".freeze
88
126
  @screen.x = 0
89
- @screen.y += 1
90
- when "\r"
91
- @screen.x = 0
92
- when "\r"
93
- @screen.x = 0
94
- when "\b"
95
- @screen.x -= 1
96
- else
97
- @screen << char
127
+ elsif code == "K".freeze || code == "k".freeze
128
+ if instruction == nil || instruction == "0".freeze
129
+ # clear everything after the current x co-ordinate
130
+ @screen.clear(@screen.y, @screen.x, Screen::END_OF_LINE)
131
+ elsif instruction == "1".freeze
132
+ # clear everything before the current x co-ordinate
133
+ @screen.clear(@screen.y, Screen::START_OF_LINE, @screen.x)
134
+ elsif instruction == "2".freeze
135
+ @screen.clear(@screen.y, Screen::START_OF_LINE, Screen::END_OF_LINE)
136
+ end
137
+ elsif code == "A".freeze
138
+ @screen.up(instruction)
139
+ elsif code == "B".freeze
140
+ @screen.down(instruction)
141
+ elsif code == "C".freeze
142
+ @screen.foward(instruction)
143
+ elsif code == "D".freeze
144
+ @screen.backward(instruction)
98
145
  end
99
146
  else
100
- handle_escape_code(char)
147
+ @screen << char
101
148
  end
102
149
  end
103
150
  end
@@ -110,67 +157,20 @@ module Terminal
110
157
  @screen.to_s
111
158
  end
112
159
 
113
- def handle_escape_code(sequence)
114
- # Escapes have the following: \e [ (instruction) (code)
115
- parts = sequence.match(/\e\[(.*)([#{ESCAPE_CONTROL_CHARACTERS}])/)
116
-
117
- instruction = parts[1].to_s
118
- code = parts[2].to_s
119
-
120
- case code
121
- when ""
122
- # no-op - an empty \e
123
- when "m"
124
- @screen.color(instruction)
125
- when "G", "g"
126
- @screen.x = 0
127
- when "K", "k"
128
- case instruction
129
- when nil, "0"
130
- # clear everything after the current x co-ordinate
131
- @screen.clear(@screen.y, @screen.x, Screen::END_OF_LINE)
132
- when "1"
133
- # clear everything before the current x co-ordinate
134
- @screen.clear(@screen.y, Screen::START_OF_LINE, @screen.x)
135
- when "2"
136
- @screen.clear(@screen.y, Screen::START_OF_LINE, Screen::END_OF_LINE)
137
- end
138
- when "A"
139
- @screen.up(instruction)
140
- when "B"
141
- @screen.down(instruction)
142
- when "C"
143
- @screen.foward(instruction)
144
- when "D"
145
- @screen.backward(instruction)
146
- end
147
- end
160
+ def convert_to_html!(string)
161
+ string.gsub!("\terminal[0]", "</span>")
148
162
 
149
- def convert_to_html(string)
150
- string = string.gsub(/\e\[([^;m]+);([^;m]+)?;m/) do |match|
151
- if $2
152
- %{<span class='term-#{$1} term-#{$2}'>}
153
- else
154
- %{<span class='term-#{$1}'>}
155
- end
163
+ string.gsub!(/\terminal\[([^\]]+)\]/) do |match|
164
+ %{<span class='#{$1}'>}
156
165
  end
157
166
 
158
- string = string.gsub("\e[0m", "</span>")
159
-
160
167
  # Replace empty lines with a non breaking space.
161
- string.gsub(/$^/, "&nbsp;")
162
- end
163
-
164
- # Scan the string to create an array of interesting things, for example
165
- # it would look like this:
166
- # [ '\n', '\r', 'a', 'b', '\e123m' ]
167
- def split_by_escape_character(string)
168
- string.scan(/[\n\r\b]|\e\[[\d;]*[#{ESCAPE_CONTROL_CHARACTERS}]|./)
168
+ string.gsub!(/$^/, "&nbsp;")
169
169
  end
170
170
 
171
- def replace_unicode_with_emoji(string)
172
- string.gsub(EMOJI_UNICODE_REGEXP) do |match|
173
- emoji_image_from_unicode(match)
171
+ def replace_unicode_with_emoji!(string)
172
+ string.gsub!(EMOJI_UNICODE_REGEXP) do |match|
173
+ Terminal::Cache.cache(:emoji, match) { emoji_image_from_unicode(match) }
174
174
  end
175
175
  end
176
176
 
@@ -181,7 +181,7 @@ module Terminal
181
181
  def emoji_image_from_unicode(unicode)
182
182
  emoji = Emoji.find_by_unicode(unicode)
183
183
 
184
- if emoji
184
+ if emoji && !EMOJI_IGNORE.include?(emoji.name)
185
185
  name = ":#{emoji.name}:"
186
186
  path = File.join(@options[:emoji_asset_path], emoji.image_filename)
187
187
 
@@ -27,27 +27,11 @@
27
27
 
28
28
  module Terminal
29
29
  class Screen
30
- class Node < Struct.new(:blob, :fg, :bg)
30
+ class Node < Struct.new(:blob, :style)
31
31
  def ==(value)
32
32
  blob == value
33
33
  end
34
34
 
35
- # Every node has a style, a foreground style, and a background
36
- # style. This method returns what essentially becomes the escape
37
- # sequence:
38
- #
39
- # \e[fg;bg;
40
- #
41
- # As the screen is turned into a string, the style is used to compare
42
- # whether or not a new escape sequence is required.
43
- def style
44
- if fg || bg
45
- "#{fg};#{bg};"
46
- else
47
- nil
48
- end
49
- end
50
-
51
35
  def to_s
52
36
  blob
53
37
  end
@@ -55,7 +39,7 @@ module Terminal
55
39
 
56
40
  END_OF_LINE = :end_of_line
57
41
  START_OF_LINE = :start_of_line
58
- EMPTY = Node.new(" ")
42
+ EMPTY = Node.new(" ", [])
59
43
 
60
44
  attr_reader :x, :y
61
45
 
@@ -63,7 +47,10 @@ module Terminal
63
47
  @x = 0
64
48
  @y = 0
65
49
  @screen = []
66
- @fg = nil
50
+
51
+ @fg_color = nil
52
+ @bg_color = nil
53
+ @other_colors = []
67
54
  end
68
55
 
69
56
  def write(character)
@@ -81,21 +68,28 @@ module Terminal
81
68
  end
82
69
 
83
70
  # Write the character to the slot
84
- line[@x] = Node.new(character, @fg, @bg)
71
+ line[@x] = Node.new(character, [ @fg_color, @bg_color, *@other_colors ].compact)
85
72
  end
86
73
 
87
74
  def <<(character)
88
75
  write(character)
89
76
  @x += 1
90
- character
91
77
  end
92
78
 
93
79
  def x=(value)
94
- @x = value > 0 ? value : 0
80
+ if value > 0
81
+ @x = value
82
+ else
83
+ @x = 0
84
+ end
95
85
  end
96
86
 
97
87
  def y=(value)
98
- @y = value > 0 ? value : 0
88
+ if value > 0
89
+ @y = value
90
+ else
91
+ @y = 0
92
+ end
99
93
  end
100
94
 
101
95
  def clear(y, x_start, x_end)
@@ -117,54 +111,60 @@ module Terminal
117
111
  # Changes the current foreground color that all new characters
118
112
  # will be written with.
119
113
  def color(color_code)
120
- # Reset all styles
121
- if color_code == "0"
122
- @fg = nil
123
- @bg = nil
124
- return color_code
125
- end
126
-
127
- # Reset foreground color only
128
- if color_code == "39"
129
- @fg = nil
130
- return color_code
131
- end
132
-
133
- # Reset background color only
134
- if color_code == "49"
135
- @bg = nil
136
- return color_code
137
- end
138
-
139
- colors = color_code.to_s.split(";")
114
+ colors = color_code.scan(/\d+/)
140
115
 
141
116
  # Extended set foreground x-term color
142
117
  if colors[0] == "38" && colors[1] == "5"
143
- return @fg = "fgx#{colors[2]}"
118
+ return @fg_color = "term-fgx#{colors[2]}"
144
119
  end
145
120
 
146
121
  # Extended set background x-term color
147
122
  if colors[0] == "48" && colors[1] == "5"
148
- return @bg = "bgx#{colors[2]}"
123
+ return @bg_color = "term-bgx#{colors[2]}"
149
124
  end
150
125
 
151
- # If multiple colors are defined, i.e. \e[30;42m\e
152
- # then loop through each one, and assign it to @fg
153
- # or @bg
126
+ # If multiple colors are defined, i.e. \e[30;42m\e then loop through each
127
+ # one, and assign it to @fg_color or @bg_color
154
128
  colors.each do |cc|
155
- # If the number is between 30–37, then it's a foreground color,
156
- # if it's 40–47, then it's a background color. 90-97 is like the regular
157
- # foreground 30-37, but it's high intensity
158
- #
159
- # I don't use ranges and a select because I've found that to be rather
160
- # slow.
161
129
  c_integer = cc.to_i
162
- if c_integer >= 30 && c_integer <= 37
163
- @fg = "fg#{cc}"
130
+
131
+ # Reset all styles
132
+ if c_integer == 0
133
+ @fg_color = nil
134
+ @bg_color = nil
135
+ @other_colors = []
136
+
137
+ # Primary (default) font
138
+ elsif c_integer == 10
139
+ # no-op
140
+
141
+ # Reset foreground color only
142
+ elsif c_integer == 39
143
+ @fg_color = nil
144
+
145
+ # Reset background color only
146
+ elsif c_integer == 49
147
+ @bg_color = nil
148
+
149
+ # 30–37, then it's a foreground color
150
+ elsif c_integer >= 30 && c_integer <= 37
151
+ @fg_color = "term-fg#{cc}"
152
+
153
+ # 40–47, then it's a background color.
164
154
  elsif c_integer >= 40 && c_integer <= 47
165
- @bg = "bg#{cc}"
155
+ @bg_color = "term-bg#{cc}"
156
+
157
+ # 90-97 is like the regular fg color, but high intensity
166
158
  elsif c_integer >= 90 && c_integer <= 97
167
- @fg = "fgi#{cc}"
159
+ @fg_color = "term-fgi#{cc}"
160
+
161
+ # 100-107 is like the regular bg color, but high intensity
162
+ elsif c_integer >= 100 && c_integer <= 107
163
+ @fg_color = "term-bgi#{cc}"
164
+
165
+ # 1-9 random other styles
166
+ elsif c_integer >= 1 && c_integer <= 9
167
+ @other_colors << "term-fg#{cc}"
168
168
  end
169
169
  end
170
170
  end
@@ -231,8 +231,8 @@ module Terminal
231
231
  line.each do |node|
232
232
  # If there is no previous node, and the current node has a color
233
233
  # (first node in a line) then add the escape character.
234
- if !previous && node.style
235
- buffer << "\e[#{node.style}m"
234
+ if !previous && node.style.length > 0
235
+ buffer << "\terminal[#{node.style.join(" ")}]"
236
236
 
237
237
  # Increment the open style counter
238
238
  open_styles += 1
@@ -242,14 +242,14 @@ module Terminal
242
242
  elsif previous && previous.style != node.style
243
243
  # If the new node has no style, that means that all the styles
244
244
  # have been closed.
245
- if !node.style
245
+ if node.style.length == 0
246
246
  # Add our reset escape character
247
- buffer << "\e[0m"
247
+ buffer << "\terminal[0]"
248
248
 
249
249
  # Decrement the open style counter
250
250
  open_styles -= 1
251
251
  else
252
- buffer << "\e[#{node.style}m"
252
+ buffer << "\terminal[#{node.style.join(" ")}]"
253
253
 
254
254
  # Increment the open style counter
255
255
  open_styles += 1
@@ -264,7 +264,7 @@ module Terminal
264
264
  end
265
265
 
266
266
  # Be sure to close off any open styles for this line
267
- open_styles.times { buffer << "\e[0m" }
267
+ open_styles.times { buffer << "\terminal[0]" }
268
268
 
269
269
  # Add a new line as long as this line isn't the last
270
270
  buffer << "\n" if line_index != last_line_index
@@ -276,7 +276,11 @@ module Terminal
276
276
  private
277
277
 
278
278
  def parse_integer(value)
279
- value.nil? || value == "" ? 1 : value.to_i
279
+ if value == nil || value == ""
280
+ 1
281
+ else
282
+ value.to_i
283
+ end
280
284
  end
281
285
  end
282
286
  end
@@ -1,3 +1,3 @@
1
1
  module Terminal
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
@@ -6,15 +6,23 @@ require 'terminal'
6
6
  require 'benchmark/ips'
7
7
  require 'timeout'
8
8
 
9
- Benchmark.ips do |bm|
10
- Dir.glob("spec/fixtures/*.raw").each do |file|
11
- output = File.read(file)
12
- basename = File.basename(file)
9
+ def benchmark(bm, file)
10
+ output = File.read(file)
11
+ basename = File.basename(file)
12
+
13
+ bm.report basename do
14
+ Timeout.timeout(100) do
15
+ Terminal.render(output)
16
+ end
17
+ end
18
+ end
13
19
 
14
- bm.report basename do
15
- Timeout.timeout(100) do
16
- Terminal.render(output)
17
- end
20
+ Benchmark.ips do |bm|
21
+ if ARGV[0]
22
+ benchmark(bm, ARGV[0])
23
+ else
24
+ Dir.glob("spec/fixtures/*.raw").each do |file|
25
+ benchmark(bm, file)
18
26
  end
19
27
  end
20
28
  end
@@ -7,9 +7,14 @@ require 'method_profiler'
7
7
 
8
8
  screen_profiler = MethodProfiler.observe(Terminal::Screen)
9
9
  render_profiler = MethodProfiler.observe(Terminal::Renderer)
10
- iterations = 10
11
10
 
12
- Dir.glob("spec/fixtures/*.raw").each do |file|
11
+ iterations = if ARGV[1]
12
+ ARGV[1].to_i
13
+ else
14
+ 10
15
+ end
16
+
17
+ def profile(file, iterations)
13
18
  output = File.read(file)
14
19
  basename = File.basename(file)
15
20
 
@@ -17,5 +22,11 @@ Dir.glob("spec/fixtures/*.raw").each do |file|
17
22
  iterations.times { Terminal.render(output) }
18
23
  end
19
24
 
25
+ if ARGV[0]
26
+ profile(ARGV[0], iterations)
27
+ else
28
+ Dir.glob("spec/fixtures/*.raw").each { |file| profile(file, iterations) }
29
+ end
30
+
20
31
  puts screen_profiler.report
21
32
  puts render_profiler.report
@@ -203,9 +203,27 @@ describe Terminal::Renderer do
203
203
 
204
204
  it "returns nothing if the unicode emoji can't be found" do
205
205
  expect(Emoji).to receive(:unicodes_index) { {} }
206
- raw = "this is great 👍"
206
+ raw = "this is great 😎"
207
+
208
+ expect(render(raw)).to eql(%{this is great 😎})
209
+ end
210
+
211
+ it "leaves the tick emoji alone (it looks better and is colored)" do
212
+ raw = "works ✔"
213
+
214
+ expect(render(raw)).to eql(%{works ✔})
215
+ end
216
+
217
+ it "leaves the ✖ emoji alone as well" do
218
+ raw = "broke ✖"
219
+
220
+ expect(render(raw)).to eql(%{broke ✖})
221
+ end
222
+
223
+ it "handles colors with 3 attributes" do
224
+ raw = "\e[0;10;4m\e[1m\e[34mgood news\e[0;10m\n\neveryone"
207
225
 
208
- expect(render(raw)).to eql(%{this is great 👍})
226
+ expect(render(raw)).to eql("<span class='term-fg34 term-fg4 term-fg1'>good news</span>\n&nbsp;\neveryone")
209
227
  end
210
228
  end
211
229
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Pitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-29 00:00:00.000000000 Z
11
+ date: 2014-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -131,6 +131,7 @@ files:
131
131
  - examples/pikachu.ansi
132
132
  - examples/pikachu.sh
133
133
  - lib/terminal.rb
134
+ - lib/terminal/cache.rb
134
135
  - lib/terminal/cli.rb
135
136
  - lib/terminal/engine.rb
136
137
  - lib/terminal/preview.rb