terminal 0.3.2 → 0.3.3

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 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