Class Bcat::ANSI
In: lib/bcat/ansi.rb
Parent: Object

Converts ANSI color sequences to HTML.

The ANSI module is based on code from the following libraries:

ansi2html.sh:

  http://github.com/pixelb/scripts/blob/master/scripts/ansi2html.sh

HTML::FromANSI:

  http://cpansearch.perl.org/src/NUFFIN/HTML-FromANSI-2.03/lib/HTML/FromANSI.pm

Methods

each   new   push_style   push_tag   reset_styles   to_html   tokenize  

Constants

ESCAPE = "\x1b"
STYLES = { 'ef0' => 'color:#000', 'ef1' => 'color:#A00', 'ef2' => 'color:#0A0', 'ef3' => 'color:#A50', 'ef4' => 'color:#00A', 'ef5' => 'color:#A0A', 'ef6' => 'color:#0AA', 'ef7' => 'color:#AAA', 'ef8' => 'color:#555', 'ef9' => 'color:#F55', 'ef10' => 'color:#5F5', 'ef11' => 'color:#FF5', 'ef12' => 'color:#55F', 'ef13' => 'color:#F5F', 'ef14' => 'color:#5FF', 'ef15' => 'color:#FFF', 'eb0' => 'background-color:#000', 'eb1' => 'background-color:#A00', 'eb2' => 'background-color:#0A0', 'eb3' => 'background-color:#A50', 'eb4' => 'background-color:#00A', 'eb5' => 'background-color:#A0A', 'eb6' => 'background-color:#0AA', 'eb7' => 'background-color:#AAA', 'eb8' => 'background-color:#555', 'eb9' => 'background-color:#F55', 'eb10' => 'background-color:#5F5', 'eb11' => 'background-color:#FF5', 'eb12' => 'background-color:#55F', 'eb13' => 'background-color:#F5F', 'eb14' => 'background-color:#5FF', 'eb15' => 'background-color:#FFF'   Linux console palette

Public Class methods

[Source]

    # File lib/bcat/ansi.rb, line 74
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

Public Instance methods

[Source]

     # File lib/bcat/ansi.rb, line 92
 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, 4     ; yield push_tag("u")
106:             when 5, 6     ; 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

[Source]

     # File lib/bcat/ansi.rb, line 132
132:     def push_style(style)
133:       push_tag "span", style
134:     end

[Source]

     # File lib/bcat/ansi.rb, line 123
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

[Source]

     # File lib/bcat/ansi.rb, line 136
136:     def reset_styles
137:       stack, @stack = @stack, []
138:       stack.reverse.map { |tag| "</#{tag}>" }.join
139:     end

[Source]

    # File lib/bcat/ansi.rb, line 86
86:     def to_html
87:       buf = []
88:       each { |chunk| buf << chunk }
89:       buf.join
90:     end

[Source]

     # File lib/bcat/ansi.rb, line 141
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 = '0' if m.strip.empty?
149:           m.chomp(';').split(';').
150:           each { |code| yield :display, code.to_i };
151:           '' }],
152: 
153:         # malformed sequences
154:         [/\A\x1b\[?[\d;]{0,3}/, lambda { |m| '' }],
155: 
156:         # real text
157:         [/\A([^\x1b\x08]+)/m, lambda { |m| yield :text, m; '' }]
158:       ]
159: 
160:       while (size = text.size) > 0
161:         tokens.each do |pattern, sub|
162:           while text.sub!(pattern) { sub.call($1) }
163:           end
164:         end
165:         break if text.size == size
166:       end
167:     end

[Validate]