bcat 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bcat.gemspec +8 -3
- data/bin/a2h +14 -0
- data/bin/bcat +30 -26
- data/lib/bcat.rb +3 -1
- data/lib/bcat/ansi.rb +169 -0
- data/lib/bcat/browser.rb +58 -13
- data/man/a2h.1.ronn +39 -0
- data/man/bcat.1.ronn +29 -16
- data/man/btee.1.ronn +29 -16
- data/test/test_bcat_a2h.rb +19 -0
- data/test/test_bcat_ansi.rb +115 -0
- data/test/test_bcat_browser.rb +5 -0
- metadata +31 -10
- data/bin/bcat-encodehtml +0 -14
data/bcat.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'bcat'
|
3
|
-
s.version = '0.
|
4
|
-
s.date = '2010-06-
|
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] [-
|
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
|
-
#/
|
9
|
-
#/ -
|
10
|
-
#/ -
|
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
|
-
#/
|
13
|
-
#/ -
|
14
|
-
#/ -
|
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
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
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')
|
34
|
-
argv.on('-t', '--text')
|
35
|
-
argv.on('-
|
36
|
-
argv.on('-T', '--title=v')
|
37
|
-
argv.on('-
|
38
|
-
argv.
|
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
|
-
|
47
|
-
notice "env
|
48
|
-
notice "env BCAT_COMMAND
|
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
|
data/lib/bcat.rb
CHANGED
@@ -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.
|
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)
|
data/lib/bcat/ansi.rb
ADDED
@@ -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
|
data/lib/bcat/browser.rb
CHANGED
@@ -1,24 +1,69 @@
|
|
1
1
|
class Bcat
|
2
|
-
|
3
|
-
|
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
|
-
|
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
|
15
|
-
return
|
53
|
+
def command
|
54
|
+
return @command if @command
|
55
|
+
browser_command
|
56
|
+
end
|
16
57
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
data/man/a2h.1.ronn
ADDED
@@ -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)
|
data/man/bcat.1.ronn
CHANGED
@@ -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
|
-
|
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
|
-
* `
|
52
|
-
|
53
|
-
|
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
|
-
* `
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
|
data/man/btee.1.ronn
CHANGED
@@ -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
|
-
|
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
|
-
* `
|
52
|
-
|
53
|
-
|
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
|
-
* `
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bcat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
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-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
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.
|
97
|
+
rubygems_version: 1.3.7
|
77
98
|
signing_key:
|
78
99
|
specification_version: 3
|
79
100
|
summary: browser cat
|
data/bin/bcat-encodehtml
DELETED
@@ -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('<')
|
9
|
-
when ?&
|
10
|
-
$stdout.write('&')
|
11
|
-
else
|
12
|
-
$stdout.putc(char)
|
13
|
-
end
|
14
|
-
end
|