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