bcat 0.3.0 → 0.4.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.
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'bcat'
3
- s.version = '0.3.0'
4
- s.date = '2010-06-21'
3
+ s.version = '0.4.0'
4
+ s.date = '2010-06-23'
5
5
 
6
6
  s.summary = "browser cat"
7
7
  s.description =
@@ -19,16 +19,21 @@ Gem::Specification.new do |s|
19
19
  README
20
20
  Rakefile
21
21
  bcat.gemspec
22
+ bin/a2h
22
23
  bin/bcat
23
- bin/bcat-encodehtml
24
24
  bin/btee
25
25
  lib/bcat.rb
26
+ lib/bcat/ansi.rb
26
27
  lib/bcat/browser.rb
27
28
  lib/bcat/html.rb
28
29
  lib/bcat/kidgloves.rb
29
30
  lib/bcat/reader.rb
31
+ man/a2h.1.ronn
30
32
  man/bcat.1.ronn
31
33
  man/btee.1.ronn
34
+ test/test_bcat_a2h.rb
35
+ test/test_bcat_ansi.rb
36
+ test/test_bcat_browser.rb
32
37
  test/test_bcat_head_parser.rb
33
38
  ]
34
39
  # = MANIFEST =
data/bin/a2h ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # Usage: a2h [-] [<file>...]
3
+ # Convert ANSI/VT100 escape sequences to HTML.
4
+ require 'bcat/ansi'
5
+ require 'bcat/reader'
6
+
7
+ $stdin.sync = true
8
+ $stdout.sync = true
9
+
10
+ ARGV.push '-' if ARGV.empty?
11
+
12
+ reader = Bcat::Reader.new(ARGV.to_a)
13
+ filter = Bcat::ANSI.new(reader)
14
+ filter.each { |text| $stdout.write(text) }
data/bin/bcat CHANGED
@@ -1,41 +1,45 @@
1
1
  #!/usr/bin/env ruby
2
- #/ Usage: bcat [-ht] [-m <module>] [-T <title>] [<file>]...
2
+ #/ Usage: bcat [-ht] [-a] [-b <browser>] [-T <title>] [<file>]...
3
3
  #/ btee <options> [<file>]...
4
4
  #/ Pipe to browser utility. Read standard input, possibly one or more <file>s,
5
5
  #/ and write concatenated / formatted output to browser. When invoked as btee,
6
6
  #/ also write all input back to standard output.
7
7
  #/
8
- #/ Input format (auto detected by default):
9
- #/ -h, --html input is already HTML encoded, perhaps a whole document
10
- #/ -t, --text input is unencoded text
8
+ #/ Display options:
9
+ #/ -b, --browser=<browser> open <browser> instead of system default browser
10
+ #/ -T, --title=<text> use <text> as the browser title
11
+ #/ -a, --ansi convert ANSI (color) escape sequences to HTML
11
12
  #/
12
- #/ Tweak output with these options:
13
- #/ -T, --title=<text> use <text> as the page title
14
- #/ -m, --module=<m1>[,<m2>]...
15
- #/ inject formatting module(s)
13
+ #/ Input format (auto detected by default):
14
+ #/ -h, --html input is already HTML encoded, doc or fragment
15
+ #/ -t, --text input is unencoded text
16
16
  #/
17
+ #/ Misc options:
17
18
  #/ -d, --debug enable verbose debug logging on stderr
18
19
  require 'optparse'
19
20
 
20
21
  options = {
21
- :format => nil,
22
- :title => Dir.pwd,
23
- :Host => '127.0.0.1',
24
- :Port => 8091,
25
- :debug => false,
26
- :tee => !!($0 =~ /tee$/)
22
+ :Host => '127.0.0.1',
23
+ :Port => 8091,
24
+ :format => nil,
25
+ :title => Dir.pwd,
26
+ :browser => (ENV['BCAT_BROWSER'].to_s.size > 0 ? ENV['BCAT_BROWSER'] : 'default'),
27
+ :ansi => false,
28
+ :debug => false,
29
+ :tee => !!($0 =~ /tee$/)
27
30
  }
28
31
 
29
32
  (class <<self;self;end).send(:define_method, :notice) { |message|
30
33
  warn "#{File.basename($0)}: #{message}" if options[:debug] }
31
34
 
32
35
  ARGV.options do |argv|
33
- argv.on('-h', '--html') { options[:format] = 'html' }
34
- argv.on('-t', '--text') { options[:format] = 'text' }
35
- argv.on('-a', '--app=v') { |app| ENV['BCAT_APPLICATION'] = app }
36
- argv.on('-T', '--title=v') { |text| options[:title] = text }
37
- argv.on('-d', '--debug') { options[:debug] = true }
38
- argv.on_tail('--help') { exec "grep ^#/ <#{__FILE__} | cut -c4-" }
36
+ argv.on('-h', '--html') { options[:format] = 'html' }
37
+ argv.on('-t', '--text') { options[:format] = 'text' }
38
+ argv.on('-b', '--browser=v') { |app| options[:browser] = app }
39
+ argv.on('-T', '--title=v') { |text| options[:title] = text }
40
+ argv.on('-a', '--ansi') { options[:ansi] = true }
41
+ argv.on('-d', '--debug') { options[:debug] = true }
42
+ argv.on_tail('--help') { exec "grep ^#/ <#{__FILE__} | cut -c4-" }
39
43
  argv.parse!
40
44
  end
41
45
  ARGV.push '-' if ARGV.empty?
@@ -43,9 +47,9 @@ ARGV.push '-' if ARGV.empty?
43
47
  require 'bcat'
44
48
  notice "loaded bcat v#{Bcat::VERSION}"
45
49
 
46
- include Bcat::Browser
47
- notice "env BCAT_APPLICATION=#{ENV['BCAT_APPLICATION'].inspect}"
48
- notice "env BCAT_COMMAND=#{browser_command.inspect}"
50
+ browser = Bcat::Browser.new(options[:browser])
51
+ notice "env BCAT_BROWSER=#{options[:browser].inspect}"
52
+ notice "env BCAT_COMMAND='#{browser.command}'"
49
53
 
50
54
  notice "starting server"
51
55
  pid = nil
@@ -53,13 +57,13 @@ begin
53
57
  bcat = Bcat.new(ARGV, options)
54
58
  bcat.serve! do |sock|
55
59
  url = "http://#{bcat[:Host]}:#{bcat[:Port]}/#{File.basename(Dir.pwd)}"
56
- pid = browser(url)
60
+ pid = browser.open(url)
57
61
  end
58
62
  rescue Interrupt
59
63
  notice "interrupt"
60
64
  end
61
65
 
62
66
  Process.wait(pid) if pid
63
- status = $?
64
- notice "browser exited with #{status}"
67
+ status = $?.exitstatus
68
+ notice "browser [pid: #{pid}] exited with #{status}"
65
69
  exit status
@@ -1,11 +1,12 @@
1
1
  require 'rack'
2
2
  require 'bcat/reader'
3
+ require 'bcat/ansi'
3
4
  require 'bcat/html'
4
5
  require 'bcat/kidgloves'
5
6
  require 'bcat/browser'
6
7
 
7
8
  class Bcat
8
- VERSION = '0.3.0'
9
+ VERSION = '0.4.0'
9
10
  include Rack::Utils
10
11
 
11
12
  attr_reader :format
@@ -18,6 +19,7 @@ class Bcat
18
19
  @filter = @reader
19
20
  @filter = TeeFilter.new(@filter) if @config[:tee]
20
21
  @filter = TextFilter.new(@filter) if @format == 'text'
22
+ @filter = ANSI.new(@filter) if @format == 'text' || @config[:ansi]
21
23
  end
22
24
 
23
25
  def [](key)
@@ -0,0 +1,169 @@
1
+ class Bcat
2
+
3
+ # Converts ANSI color sequences to HTML.
4
+ #
5
+ # The ANSI module is based on code from the following libraries:
6
+ #
7
+ # ansi2html.sh:
8
+ # http://code.google.com/p/wrdese/source/browse/trunk/b/ansi2html.sh?r=5
9
+ #
10
+ # HTML::FromANSI:
11
+ # http://cpansearch.perl.org/src/NUFFIN/HTML-FromANSI-2.03/lib/HTML/FromANSI.pm
12
+ class ANSI
13
+ ESCAPE = "\x1b"
14
+
15
+ # Linux console palette
16
+ STYLES = {
17
+ 'ef0' => 'color:#000',
18
+ 'ef1' => 'color:#A00',
19
+ 'ef2' => 'color:#0A0',
20
+ 'ef3' => 'color:#A50',
21
+ 'ef4' => 'color:#00A',
22
+ 'ef5' => 'color:#A0A',
23
+ 'ef6' => 'color:#0AA',
24
+ 'ef7' => 'color:#AAA',
25
+ 'ef8' => 'color:#555',
26
+ 'ef9' => 'color:#F55',
27
+ 'ef10' => 'color:#5F5',
28
+ 'ef11' => 'color:#FF5',
29
+ 'ef12' => 'color:#55F',
30
+ 'ef13' => 'color:#F5F',
31
+ 'ef14' => 'color:#5FF',
32
+ 'ef15' => 'color:#FFF',
33
+ 'eb0' => 'background-color:#000',
34
+ 'eb1' => 'background-color:#A00',
35
+ 'eb2' => 'background-color:#0A0',
36
+ 'eb3' => 'background-color:#A50',
37
+ 'eb4' => 'background-color:#00A',
38
+ 'eb5' => 'background-color:#A0A',
39
+ 'eb6' => 'background-color:#0AA',
40
+ 'eb7' => 'background-color:#AAA',
41
+ 'eb8' => 'background-color:#555',
42
+ 'eb9' => 'background-color:#F55',
43
+ 'eb10' => 'background-color:#5F5',
44
+ 'eb11' => 'background-color:#FF5',
45
+ 'eb12' => 'background-color:#55F',
46
+ 'eb13' => 'background-color:#F5F',
47
+ 'eb14' => 'background-color:#5FF',
48
+ 'eb15' => 'background-color:#FFF'
49
+ }
50
+
51
+ ##
52
+ # The default xterm 256 colour palette
53
+
54
+ (0..5).each do |red|
55
+ (0..5).each do |green|
56
+ (0..5).each do |blue|
57
+ c = 16 + (red * 36) + (green * 6) + blue
58
+ r = red > 0 ? red * 40 + 55 : 0
59
+ g = green > 0 ? green * 40 + 55 : 0
60
+ b = blue > 0 ? blue * 40 + 55 : 0
61
+ STYLES["ef#{c}"] = "color:#%2.2x%2.2x%2.2x" % [r, g, b]
62
+ STYLES["eb#{c}"] = "background-color:#%2.2x%2.2x%2.2x" % [r, g, b]
63
+ end
64
+ end
65
+ end
66
+
67
+ (0..23).each do |gray|
68
+ c = gray+232
69
+ l = gray*10 + 8
70
+ STYLES["ef#{c}"] = "color:#%2.2x%2.2x%2.2x" % [l, l, l]
71
+ STYLES["eb#{c}"] = "background-color:#%2.2x%2.2x%2.2x" % [l, l, l]
72
+ end
73
+
74
+ def initialize(input)
75
+ @input =
76
+ if input.respond_to?(:to_str)
77
+ [input]
78
+ elsif !input.respond_to?(:each)
79
+ raise ArgumentError, "input must respond to each"
80
+ else
81
+ input
82
+ end
83
+ @stack = []
84
+ end
85
+
86
+ def to_html
87
+ buf = []
88
+ each { |chunk| buf << chunk }
89
+ buf.join
90
+ end
91
+
92
+ def each
93
+ buf = ''
94
+ @input.each do |chunk|
95
+ buf << chunk
96
+ tokenize(buf) do |tok, data|
97
+ case tok
98
+ when :text
99
+ yield data
100
+ when :display
101
+ case code = data
102
+ when 0 ; yield reset_styles if @stack.any?
103
+ when 1 ; yield push_tag("b") # bright
104
+ when 2 ; #dim
105
+ when 3 ; yield push_tag("u")
106
+ when 5 ; yield push_tag("blink")
107
+ when 7 ; #reverse
108
+ when 8 ; yield push_style("display:none")
109
+ when 9 ; yield push_tag("strike")
110
+ when 30..37 ; yield push_style("ef#{code - 30}")
111
+ when 40..47 ; yield push_style("eb#{code - 40}")
112
+ when 90..97 ; yield push_style("ef#{8 + code - 90}")
113
+ when 100..107 ; yield push_style("eb#{8 + code - 100}")
114
+ end
115
+ end
116
+ end
117
+ end
118
+ yield buf if !buf.empty?
119
+ yield reset_styles if @stack.any?
120
+ self
121
+ end
122
+
123
+ def push_tag(tag, style=nil)
124
+ style = STYLES[style] if style && !style.include?(':')
125
+ @stack.push tag
126
+ [ "<#{tag}",
127
+ (" style='#{style}'" if style),
128
+ ">"
129
+ ].join
130
+ end
131
+
132
+ def push_style(style)
133
+ push_tag "span", style
134
+ end
135
+
136
+ def reset_styles
137
+ stack, @stack = @stack, []
138
+ stack.reverse.map { |tag| "</#{tag}>" }.join
139
+ end
140
+
141
+ def tokenize(text)
142
+ tokens = [
143
+ # characters to remove completely
144
+ [/\A\x08+/, lambda { |m| '' }],
145
+
146
+ # ansi escape sequences that mess with the display
147
+ [/\A\x1b\[((?:\d{1,3};?)+)m/, lambda { |m|
148
+ m.chomp(';').split(';').
149
+ each { |code| yield :display, code.to_i };
150
+ '' }],
151
+
152
+ # malformed sequences
153
+ [/\A\x1b\[?[\d;]{0,3}/, lambda { |m| '' }],
154
+
155
+ # real text
156
+ [/\A([^\x1b\x08]+)/m, lambda { |m| yield :text, m; '' }]
157
+ ]
158
+
159
+ while (size = text.size) > 0
160
+ tokens.each do |pattern, sub|
161
+ while text.sub!(pattern) { sub.call($1) }
162
+ end
163
+ end
164
+ break if text.size == size
165
+ end
166
+ end
167
+
168
+ end
169
+ end
@@ -1,24 +1,69 @@
1
1
  class Bcat
2
- module Browser
3
- def browser(url, application=ENV['BCAT_APPLICATION'])
2
+ class Browser
3
+ ENVIRONMENT =
4
+ case `uname`
5
+ when /Darwin/ ; 'Darwin'
6
+ when /Linux/, /BSD/ ; 'X11'
7
+ else 'X11'
8
+ end
9
+
10
+ # browser name -> command mappings
11
+ COMMANDS = {
12
+ 'Darwin' => {
13
+ 'default' => "open",
14
+ 'safari' => "open -a Safari",
15
+ 'firefox' => "open -a Firefox",
16
+ 'chrome' => "open -a Google\\ Chrome",
17
+ 'chromium' => "open -a Chromium",
18
+ 'opera' => "open -a Opera",
19
+ 'curl' => "curl -s"
20
+ },
21
+
22
+ 'X11' => {
23
+ 'default' => "xdg-open",
24
+ 'firefox' => "firefox",
25
+ 'chrome' => "google-chrome",
26
+ 'chromium' => "chromium",
27
+ 'mozilla' => "mozilla",
28
+ 'epiphany' => "epiphany",
29
+ 'curl' => "curl -s"
30
+ }
31
+ }
32
+
33
+ # alternative names for browsers
34
+ ALIASES = {
35
+ 'google-chrome' => 'chrome',
36
+ 'google chrome' => 'chrome',
37
+ 'gnome' => 'epiphany'
38
+ }
39
+
40
+ def initialize(browser, command=ENV['BCAT_COMMAND'])
41
+ @browser = browser
42
+ @command = command
43
+ end
44
+
45
+ def open(url)
4
46
  command = browser_command
5
47
  fork do
6
48
  [$stdin, $stdout].each { |fd| fd.close }
7
- ENV['BCAT_ARGS'] = "-a '#{application}'" if !application.to_s.empty?
8
- ENV['BCAT_URL'] = url
9
- ENV['BCAT_COMMAND'] = command
10
- exec "/bin/sh -c \"#{command.gsub(/"/, '\"')}\""
49
+ exec "#{command} #{shell_quote(url)}"
11
50
  end
12
51
  end
13
52
 
14
- def browser_command
15
- return ENV['BCAT_COMMAND'] if !ENV['BCAT_COMMAND'].to_s.empty?
53
+ def command
54
+ return @command if @command
55
+ browser_command
56
+ end
16
57
 
17
- case `uname`
18
- when /Darwin/ ; 'open $BCAT_ARGS "$BCAT_URL"'
19
- when /Linux/, /BSD/ ; 'xdg-open $BCAT_ARGS "$BCAT_URL"'
20
- else ; 'xdg-open "$BCAT_URL"'
21
- end
58
+ def browser_command(browser=@browser)
59
+ browser ||= 'default'
60
+ browser = browser.downcase
61
+ browser = ALIASES[browser] || browser
62
+ COMMANDS[ENVIRONMENT][browser]
63
+ end
64
+
65
+ def shell_quote(argument)
66
+ arg = argument.to_s.gsub(/([\\'])/) { "\\" + $1 }
22
67
  end
23
68
  end
24
69
  end
@@ -0,0 +1,39 @@
1
+ a2h(1) -- convert ANSI/VT100 escape sequences to HTML
2
+ =====================================================
3
+
4
+ ## SYNOPSIS
5
+
6
+ `a2h` [-] [<file>...]
7
+
8
+ ## DESCRIPTION
9
+
10
+ The `a2h` utility reads from standard input, or one or more <file>s, and
11
+ converts ANSI/VT100 escape sequences to inline HTML.
12
+
13
+ ## ESCAPE SEQUENCES
14
+
15
+ The following escape sequences are supported:
16
+
17
+ * `<ESC>[0m`:
18
+ Resets all attributes / closes all HTML tags.
19
+ * `<ESC>[1m`=`<b>`:
20
+ Bold.
21
+ * `<ESC>[4m`=`<u>`:
22
+ Underscore.
23
+ * `<ESC>[5m`=`<blink>`:
24
+ Blink. Really.
25
+ * `<ESC>[8m`=`<span style='display:none'>`:
26
+ Hidden.
27
+ * `<ESC>[30-37m`=`<span style='color:`<color>`>`:
28
+ Foreground color.
29
+ * `<ESC>[40-47m`=`<span style='background-color:`<color>`>`:
30
+ Background color.
31
+ * `<ESC>[90-97m`=`<span style='color:`<color>`>`:
32
+ Light foreground colors.
33
+ * `<ESC>[100-107m`=`<span style='background-color:`<color>`>`:
34
+ Light background color.
35
+
36
+ ## SEE ALSO
37
+
38
+ [ansi2html.sh](http://code.google.com/p/wrdese/source/browse/trunk/b/ansi2html.sh?r=5),
39
+ [HTML::FromANSI](http://cpansearch.perl.org/src/NUFFIN/HTML-FromANSI-2.03/lib/HTML/FromANSI.pm)
@@ -17,6 +17,25 @@ addition to being piped into the browser.
17
17
 
18
18
  ## OPTIONS
19
19
 
20
+ `bcat` opens a simple, undecorated page with the system default web browser and
21
+ immediately begins streaming input. The following options control the browser
22
+ display:
23
+
24
+ * `-b`, `--browser`=default|firefox|safari|chrome|opera|<other>
25
+ The name of the browser application. Defaults to the value of the
26
+ `BCAT_BROWSER` environment variable, or the system default browser when
27
+ no `BCAT_BROWSER` is defined.
28
+
29
+ * `-T`, `--title`=<text>:
30
+ Use <text> as the page `<title>`. By default, the path to the current working
31
+ directory is used as the title.
32
+
33
+ * `-a`, `--ansi`:
34
+ Turns on VT100/ANSI escape sequence conversion. This causes all input to be
35
+ piped through a2h(1), replacing ANSI escape sequences with HTML for things
36
+ like bold, underline, and colors. On by default when the input is text; use
37
+ the `-a` option to turn it on when the input is HTML.
38
+
20
39
  By default, `bcat` attempts to detect whether input is HTML or plain text using
21
40
  a simple heuristic, but you can force input to be treated as one or the other
22
41
  with these options:
@@ -32,15 +51,7 @@ with these options:
32
51
  document, or it may be an HTML fragment. `bcat` outputs `<html>`, `<head>`,
33
52
  and `<body>` elements even if they are not included in the input.
34
53
 
35
- Customization
36
-
37
- * `-T`, `--title`=<text>:
38
- Use <text> as the page `<title>`. By default, the path to the current working
39
- directory is used as the title.
40
-
41
- * `-a`, `--app`=`Safari`|`Google Chrome`|`Firefox`:
42
- MacOS only. The name of the browser application. This can also be set using
43
- the `BCAT_APPLICATION` environment variable.
54
+ Miscellaneous options:
44
55
 
45
56
  * `-d`, `--debug`:
46
57
  Turn on verbose debug logging to standard error. Include this output when
@@ -48,14 +59,16 @@ Customization
48
59
 
49
60
  ## ENVIRONMENT
50
61
 
51
- * `BCAT_COMMAND`=`open -a $BCAT_APPLICATION $url`:
52
- * `BCAT_COMMAND`=`xdg-open "$url"`:
53
- The command used to launch to the browser application.
62
+ * `BCAT_BROWSER`=default|firefox|safari|chrome|opera|<other>:
63
+ The name of the browser to use by default. `bcat` maps this to an
64
+ actual browser command based on the current platform. The special
65
+ value "default" maps to the system default browser.
54
66
 
55
- * `BCAT_APPLICATION`=[`Safari` | `Google Chrome` | `Firefox`]:
56
- MacOS X only. The name of the browser application . This is given as the
57
- value of the `-a` argument to open(1). When `BCAT_APPLICATION` is undefined,
58
- the system default browser is used.
67
+ * `BCAT_COMMAND`=<command>:
68
+ The entire browser command line (to be executed by `/bin/sh`). This
69
+ overrides the `BCAT_BROWSER` environment variable and makes the `--browser`
70
+ (`-b`) option a no-op. This should only be necessary when running a
71
+ browser unknown to bcat or in order to pass special arguments.
59
72
 
60
73
  ## SEE ALSO
61
74
 
@@ -17,6 +17,25 @@ addition to being piped into the browser.
17
17
 
18
18
  ## OPTIONS
19
19
 
20
+ `bcat` opens a simple, undecorated page with the system default web browser and
21
+ immediately begins streaming input. The following options control the browser
22
+ display:
23
+
24
+ * `-b`, `--browser`=default|firefox|safari|chrome|opera|<other>
25
+ The name of the browser application. Defaults to the value of the
26
+ `BCAT_BROWSER` environment variable, or the system default browser when
27
+ no `BCAT_BROWSER` is defined.
28
+
29
+ * `-T`, `--title`=<text>:
30
+ Use <text> as the page `<title>`. By default, the path to the current working
31
+ directory is used as the title.
32
+
33
+ * `-a`, `--ansi`:
34
+ Turns on VT100/ANSI escape sequence conversion. This causes all input to be
35
+ piped through a2h(1), replacing ANSI escape sequences with HTML for things
36
+ like bold, underline, and colors. On by default when the input is text; use
37
+ the `-a` option to turn it on when the input is HTML.
38
+
20
39
  By default, `bcat` attempts to detect whether input is HTML or plain text using
21
40
  a simple heuristic, but you can force input to be treated as one or the other
22
41
  with these options:
@@ -32,15 +51,7 @@ with these options:
32
51
  document, or it may be an HTML fragment. `bcat` outputs `<html>`, `<head>`,
33
52
  and `<body>` elements even if they are not included in the input.
34
53
 
35
- Customization
36
-
37
- * `-T`, `--title`=<text>:
38
- Use <text> as the page `<title>`. By default, the path to the current working
39
- directory is used as the title.
40
-
41
- * `-a`, `--app`=`Safari`|`Google Chrome`|`Firefox`:
42
- MacOS only. The name of the browser application. This can also be set using
43
- the `BCAT_APPLICATION` environment variable.
54
+ Miscellaneous options:
44
55
 
45
56
  * `-d`, `--debug`:
46
57
  Turn on verbose debug logging to standard error. Include this output when
@@ -48,14 +59,16 @@ Customization
48
59
 
49
60
  ## ENVIRONMENT
50
61
 
51
- * `BCAT_COMMAND`=`open -a $BCAT_APPLICATION $url`:
52
- * `BCAT_COMMAND`=`xdg-open "$url"`:
53
- The command used to launch to the browser application.
62
+ * `BCAT_BROWSER`=default|firefox|safari|chrome|opera|<other>:
63
+ The name of the browser to use by default. `bcat` maps this to an
64
+ actual browser command based on the current platform. The special
65
+ value "default" maps to the system default browser.
54
66
 
55
- * `BCAT_APPLICATION`=[`Safari` | `Google Chrome` | `Firefox`]:
56
- MacOS X only. The name of the browser application . This is given as the
57
- value of the `-a` argument to open(1). When `BCAT_APPLICATION` is undefined,
58
- the system default browser is used.
67
+ * `BCAT_COMMAND`=<command>:
68
+ The entire browser command line (to be executed by `/bin/sh`). This
69
+ overrides the `BCAT_BROWSER` environment variable and makes the `--browser`
70
+ (`-b`) option a no-op. This should only be necessary when running a
71
+ browser unknown to bcat or in order to pass special arguments.
59
72
 
60
73
  ## SEE ALSO
61
74
 
@@ -0,0 +1,19 @@
1
+ require 'contest'
2
+
3
+ ENV['PATH'] = [File.expand_path('../../bin'), ENV['PATH']].join(':')
4
+
5
+ class ANSI2HTMLCommandTest < Test::Unit::TestCase
6
+ test "piping stuff through a2h" do
7
+ IO.popen("a2h", 'w+') do |io|
8
+ io.sync = true
9
+ io.puts "hello there"
10
+ io.flush
11
+ assert_equal "hello there\n", io.read("hello there\n".size)
12
+ io.puts "and \x1b[1mhere's some bold"
13
+ assert_equal "and <b>here's some bold\n", io.read(24)
14
+ io.close_write
15
+ assert_equal "</b>", io.read(4)
16
+ io.close
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,115 @@
1
+ require 'contest'
2
+ require 'bcat/ansi'
3
+
4
+ class ANSITest < Test::Unit::TestCase
5
+ test 'should not modify input string' do
6
+ text = "some text"
7
+ Bcat::ANSI.new(text).to_html
8
+ assert_equal "some text", text
9
+ end
10
+
11
+ test 'passing through text with no escapes' do
12
+ text = "hello\nthis is bcat\n"
13
+ ansi = Bcat::ANSI.new(text)
14
+ assert_equal text, ansi.to_html
15
+ end
16
+
17
+ test "removing backspace characters" do
18
+ text = "like this"
19
+ ansi = Bcat::ANSI.new(text)
20
+ assert_equal "like this", ansi.to_html
21
+ end
22
+
23
+ test "foreground colors" do
24
+ text = "colors: \x1b[30mblack\x1b[37mwhite"
25
+ expect = "colors: " +
26
+ "<span style='color:#000'>black" +
27
+ "<span style='color:#AAA'>white" +
28
+ "</span></span>"
29
+ assert_equal expect, Bcat::ANSI.new(text).to_html
30
+ end
31
+
32
+ test "light foreground colors" do
33
+ text = "colors: \x1b[90mblack\x1b[97mwhite"
34
+ expect = "colors: " +
35
+ "<span style='color:#555'>black" +
36
+ "<span style='color:#FFF'>white" +
37
+ "</span></span>"
38
+ assert_equal expect, Bcat::ANSI.new(text).to_html
39
+ end
40
+
41
+ test "background colors" do
42
+ text = "colors: \x1b[40mblack\x1b[47mwhite"
43
+ expect = "colors: " +
44
+ "<span style='background-color:#000'>black" +
45
+ "<span style='background-color:#AAA'>white" +
46
+ "</span></span>"
47
+ assert_equal expect, Bcat::ANSI.new(text).to_html
48
+ end
49
+
50
+ test "light background colors" do
51
+ text = "colors: \x1b[100mblack\x1b[107mwhite"
52
+ expect = "colors: " +
53
+ "<span style='background-color:#555'>black" +
54
+ "<span style='background-color:#FFF'>white" +
55
+ "</span></span>"
56
+ assert_equal expect, Bcat::ANSI.new(text).to_html
57
+ end
58
+
59
+ test "strikethrough" do
60
+ text = "strike: \x1b[9mthat"
61
+ expect = "strike: <strike>that</strike>"
62
+ assert_equal expect, Bcat::ANSI.new(text).to_html
63
+ end
64
+
65
+ test "blink!" do
66
+ text = "blink: \x1b[5mwhat"
67
+ expect = "blink: <blink>what</blink>"
68
+ assert_equal expect, Bcat::ANSI.new(text).to_html
69
+ end
70
+
71
+ test "underline" do
72
+ text = "underline: \x1b[3mstuff"
73
+ expect = "underline: <u>stuff</u>"
74
+ assert_equal expect, Bcat::ANSI.new(text).to_html
75
+ end
76
+
77
+ test "bold" do
78
+ text = "bold: \x1b[1mstuff"
79
+ expect = "bold: <b>stuff</b>"
80
+ assert_equal expect, Bcat::ANSI.new(text).to_html
81
+ end
82
+
83
+ test "resetting a single sequence" do
84
+ text = "\x1b[1mthis is bold\x1b[0m, but this isn't"
85
+ expect = "<b>this is bold</b>, but this isn't"
86
+ assert_equal expect, Bcat::ANSI.new(text).to_html
87
+ end
88
+
89
+ test "resetting many sequences" do
90
+ text = "normal, \x1b[1mbold, \x1b[3munderline, \x1b[31mred\x1b[0m, normal"
91
+ expect = "normal, <b>bold, <u>underline, " +
92
+ "<span style='color:#A00'>red</span></u></b>, normal"
93
+ assert_equal expect, Bcat::ANSI.new(text).to_html
94
+ end
95
+
96
+ test "multi-attribute sequences" do
97
+ text = "normal, \x1b[1;3;31mbold, underline, and red\x1b[0m, normal"
98
+ expect = "normal, <b><u><span style='color:#A00'>" +
99
+ "bold, underline, and red</span></u></b>, normal"
100
+ assert_equal expect, Bcat::ANSI.new(text).to_html
101
+ end
102
+
103
+ test "multi-attribute sequences with a trailing semi-colon" do
104
+ text = "normal, \x1b[1;3;31;mbold, underline, and red\x1b[0m, normal"
105
+ expect = "normal, <b><u><span style='color:#A00'>" +
106
+ "bold, underline, and red</span></u></b>, normal"
107
+ assert_equal expect, Bcat::ANSI.new(text).to_html
108
+ end
109
+
110
+ test "eating malformed sequences" do
111
+ text = "\x1b[25oops forgot the 'm'"
112
+ expect = "oops forgot the 'm'"
113
+ assert_equal expect, Bcat::ANSI.new(text).to_html
114
+ end
115
+ end
@@ -0,0 +1,5 @@
1
+ require 'contest'
2
+ require 'bcat/browser'
3
+
4
+ class BrowserTest < Test::Unit::TestCase
5
+ end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bcat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Ryan Tomayko
@@ -9,19 +15,23 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-06-21 00:00:00 -07:00
18
+ date: 2010-06-23 00:00:00 -07:00
13
19
  default_executable: bcat
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rack
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
23
32
  version: "0"
24
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
25
35
  description: Concatenate input from standard input, or one or more files, and write progressive output to a browser.
26
36
  email: rtomayko@gmail.com
27
37
  executables:
@@ -37,16 +47,21 @@ files:
37
47
  - README
38
48
  - Rakefile
39
49
  - bcat.gemspec
50
+ - bin/a2h
40
51
  - bin/bcat
41
- - bin/bcat-encodehtml
42
52
  - bin/btee
43
53
  - lib/bcat.rb
54
+ - lib/bcat/ansi.rb
44
55
  - lib/bcat/browser.rb
45
56
  - lib/bcat/html.rb
46
57
  - lib/bcat/kidgloves.rb
47
58
  - lib/bcat/reader.rb
59
+ - man/a2h.1.ronn
48
60
  - man/bcat.1.ronn
49
61
  - man/btee.1.ronn
62
+ - test/test_bcat_a2h.rb
63
+ - test/test_bcat_ansi.rb
64
+ - test/test_bcat_browser.rb
50
65
  - test/test_bcat_head_parser.rb
51
66
  has_rdoc: true
52
67
  homepage: http://github.com/rtomayko/bcat/
@@ -59,21 +74,27 @@ rdoc_options:
59
74
  require_paths:
60
75
  - lib
61
76
  required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
62
78
  requirements:
63
79
  - - ">="
64
80
  - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
65
84
  version: "0"
66
- version:
67
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
68
87
  requirements:
69
88
  - - ">="
70
89
  - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
71
93
  version: "0"
72
- version:
73
94
  requirements: []
74
95
 
75
96
  rubyforge_project:
76
- rubygems_version: 1.3.5
97
+ rubygems_version: 1.3.7
77
98
  signing_key:
78
99
  specification_version: 3
79
100
  summary: browser cat
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # Usage: bcat-encodehtml
3
- # Read text from stdin and write HTML encoded result to stdout.
4
-
5
- while char = $stdin.getc
6
- case char
7
- when ?<
8
- $stdout.write('&lt;')
9
- when ?&
10
- $stdout.write('&amp;')
11
- else
12
- $stdout.putc(char)
13
- end
14
- end