ansi_art 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ansi_art.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright [2011] [ansiProject]
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,72 @@
1
+ # AnsiArt
2
+
3
+ This project is under refactoring.
4
+
5
+ Pending issues:
6
+
7
+ * Currently it only supports Ruby 1.9.2 or above because it uses `String#encode!`
8
+ * It requires `uming.ttc` font file in current working directory. This is inconvenient.
9
+ * The CSS should be moved somewhere else.
10
+
11
+ I saw there are some code to use `gd2` gem in ruby 1.8.x. I think that doesn't work.
12
+
13
+ ## Requirement
14
+
15
+ * Ruby 1.9.2 or above
16
+ * libgd
17
+
18
+ ## Installation
19
+
20
+ It's not on rubygems.org yet. Just clone the git reposiory and execute.
21
+
22
+ rake install
23
+
24
+ ## Example: Get it working
25
+
26
+ This gem requires CJK font `AR PL UMing` for PNG rendering, which is licensed under Arphic Public License.
27
+ Put a `uming.tcc` font file in your working directory.
28
+
29
+ Ways to find it:
30
+
31
+ * In Ubuntu, it might be at `/usr/share/fonts/truetype/arphic/uming.ttc`.
32
+ * Download it from [freedesktop.org] (http://www.freedesktop.org/wiki/Software/CJKUnifonts/Download)
33
+
34
+ Download a ansi file:
35
+
36
+ wget http://ansi.loli.tw/ansiarts/static/803.ans
37
+
38
+ And here is the ruby snippet:
39
+
40
+ require 'rubygems'
41
+ gem 'ansi_art'
42
+ require 'ansi_art'
43
+
44
+ c = AnsiArt::Document.new(IO.read('803.ans'))
45
+ html = c.to_html
46
+ File.open('out.html', 'w') { |f| f.write(html) }
47
+ png = c.to_png
48
+ File.open('out.png', 'wb') { |f| f.write(png) }
49
+
50
+ You should see `out.html` and `out.png` in your working directory.
51
+
52
+ ## Make HTML display correctly
53
+ HTML output needs to be wraped under a `<div class="ansi-block">` tag, and apply required css files.
54
+
55
+ Example:
56
+
57
+ <!doctype html>
58
+ <html>
59
+ <head>
60
+ <title>ANSI art test page</title>
61
+ <link href="ansi.css" rel="stylesheet" type="text/css">
62
+ <!--[if IE 9]>
63
+ <link href="ansi.ie9.css" rel="stylesheet" type="text/css">
64
+ <![endif]-->
65
+ </head>
66
+ <body>
67
+ <div class="ansi-block">
68
+ <%= c.to_html %>
69
+ </div>
70
+ </body>
71
+ </html>
72
+
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,42 @@
1
+ .ansi-block{
2
+ background-color: black;
3
+ font: 20px "細明體","AR PL UMing TW","MS Mincho","SimHei",monospace;
4
+ line-height: 100%;
5
+ color:silver;
6
+ width:800px;
7
+ overflow:hidden;
8
+ white-space: nowrap;
9
+ margin:0 auto;
10
+ padding:5px;
11
+ border:1px solid gray;
12
+ position:relative;
13
+ }
14
+
15
+ .ansi-block div{
16
+ height:20px;
17
+ overflow:hidden;
18
+ position:relative;
19
+ }
20
+ .float-char{
21
+ position:absolute;
22
+ width:10px;
23
+ height:20px;
24
+ overflow:hidden;
25
+ }
26
+
27
+ .f0{color:black} .f1{color:Maroon} .f2{color:Green} .f3{color:Olive}
28
+ .f4{color:Navy} .f5{color:Purple} .f6{color:Teal} .f7{color:Silver}
29
+
30
+ .fb0{color:Gray} .fb1{color:Red} .fb2{color:lime} .fb3{color:yellow}
31
+ .fb4{color:blue} .fb5{color:Fuchsia} .fb6{color:Aqua} .fb7{color:white}
32
+
33
+ .b0{background-color:black}
34
+ .b1{background-color:Maroon}
35
+ .b2{background-color:Green}
36
+ .b3{background-color:Olive}
37
+ .b4{background-color:Navy}
38
+ .b5{background-color:Purple}
39
+ .b6{background-color:Teal}
40
+ .b7{background-color:Silver}
41
+
42
+
@@ -0,0 +1,4 @@
1
+ .ansi-block span{
2
+ display:inline-block;
3
+ line-height:normal
4
+ }
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ansi_art/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ansi_art"
7
+ s.version = AnsiArt::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["albb0920", "miaout17"]
10
+ s.email = ["albb0920@gmail.com"]
11
+ s.homepage = "https://github.com/albb0920/big5-ansiart"
12
+ s.summary = %q{ANSI AsciiArt Renderer}
13
+ s.description = %q{Render AsciiArt to HTML and PNG format}
14
+
15
+ s.rubyforge_project = "ansi_art"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'gd2-ffij', '~> 0.0.3'
23
+ s.add_dependency 'ffi', '~> 1.0.9'
24
+ end
@@ -0,0 +1,6 @@
1
+ require 'ansi_art/buffer'
2
+ require 'ansi_art/converter'
3
+ require 'ansi_art/document'
4
+ require 'ansi_art/html_converter'
5
+ require 'ansi_art/png_converter'
6
+ require 'ansi_art/version'
@@ -0,0 +1,26 @@
1
+ module AnsiArt
2
+ class Buffer < Array
3
+ def initialize
4
+ super
5
+ end
6
+
7
+ def conv str
8
+ str.encode! 'utf-8','big5-uao',{:invalid => :replace, :undef => :replace}
9
+
10
+ # Patch for special chars
11
+ str.tr!("\u00AF","\u203E")
12
+
13
+ str
14
+ end
15
+
16
+ def to_s
17
+ return conv(self.pack('C*'))
18
+ end
19
+
20
+ def to_s! # to string and clean up
21
+ output = self.to_s
22
+ self.clear
23
+ return output
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ module AnsiArt
2
+ class Converter
3
+ def initialize
4
+ reset_color
5
+ end
6
+ def wait_half_char! # store dual color char left side color
7
+ @leftColor = @color.clone
8
+ end
9
+ def set_color fg,bg,bri
10
+ @color = {:fg => fg, :bg => bg, :bri => bri}
11
+ end
12
+ def set_color_for key,color
13
+ @color[key] = color
14
+ end
15
+ def reset_color
16
+ set_color 7,0,false
17
+ end
18
+ def commit_color
19
+ #this is when new color is ACKed, do nothing by default
20
+ end
21
+ def output
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,75 @@
1
+ module AnsiArt
2
+ class Document
3
+ def initialize ansi
4
+ @ansi = ansi
5
+ end
6
+
7
+ def to_html
8
+ return convert HtmlConverter.new
9
+ end
10
+
11
+ def to_png w=800, o={}
12
+ return convert PngConverter.new(w,o)
13
+ end
14
+
15
+ def convert conv
16
+ buffer = Buffer.new
17
+ ctrl_seq = ""
18
+ high_byte = false # current status
19
+
20
+ @ansi.bytes do |b|
21
+ if(ctrl_seq.empty? && b != 0x1B) #if is not ctrl sequence
22
+ case b
23
+ when 10 #newline
24
+ conv.put buffer.to_s!
25
+ conv.newLine
26
+ when 13 #ignore \r
27
+ else
28
+ buffer.push b
29
+ high_byte = (!high_byte && b > 128)
30
+ end
31
+ else # is control sequence
32
+ ctrl_seq += (c = [b].pack('C*'))
33
+ if(c.match(/[0-9;\[\x1B]/).nil?)
34
+ if(c == "m") # terminal color config
35
+ ## ANSI Convert##
36
+ # Remove half byte from string before put to converter
37
+ half_char = buffer.slice!(-1) if high_byte
38
+ # puts string with old color settings
39
+ conv.put buffer.to_s! unless buffer.empty?
40
+
41
+ if high_byte
42
+ buffer.push half_char
43
+ # ask converter to store left side color
44
+ conv.wait_half_char!
45
+ end
46
+
47
+ # Strip esc chars and "[" and tail char
48
+ ctrl_seq.gsub! /[\x1B\[]/ , ''
49
+ ctrl_seq.slice! -1
50
+
51
+ #split with ";" spliter
52
+ confs = ctrl_seq.split(';')
53
+ if(confs.empty?) #*[m = clear setting
54
+ conv.reset_color
55
+ else
56
+ ctrl_seq.split(';').each do |conf|
57
+ case conf = conf.to_i
58
+ when 0 then conv.reset_color
59
+ when 1 then conv.set_color_for :bri, true
60
+ when 30..37 then conv.set_color_for :fg, conf % 10
61
+ when 40..47 then conv.set_color_for :bg, conf % 10
62
+ end
63
+ end
64
+ end
65
+ conv.commit_color
66
+ end
67
+ ctrl_seq = ""
68
+ end
69
+ end
70
+ end
71
+ conv.put buffer.to_s
72
+ return conv.output
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,43 @@
1
+ module AnsiArt
2
+ class HtmlConverter < Converter
3
+ def initialize
4
+ super
5
+ @output = '<div><span class="f7 b0">'
6
+ end
7
+ def put str
8
+ putHalfChar str[/./] unless @leftColor.nil?
9
+
10
+ # behave like PCMan, need option for user to choose, though
11
+ str.gsub!(/\u00B7/,"\u00B7 ")
12
+ str.gsub!(/\u00A7/,"\u00A7 ")
13
+ str.gsub!(/\uFF89/,"\uFF89 ")
14
+ str.gsub!(/\u2665/,"\u2665 ")
15
+
16
+ # HTML special chars
17
+ str.gsub!(/&/, '&amp;')
18
+ str.gsub!(/</, '&lt;')
19
+ str.gsub!(/>/, '&gt;')
20
+ str.gsub!(/"/, '&quot;')
21
+
22
+ @output += str.gsub(/ /,'&nbsp;')
23
+ end
24
+ def newLine
25
+ @output += "</span></div><div><span class=\"#{formatColor}\">"
26
+ end
27
+ def commit_color
28
+ @output += '</span><span class="' + formatColor + '">'
29
+ end
30
+ def output
31
+ return @output + '</span></div>'
32
+ end
33
+
34
+ private
35
+ def formatColor color=@color
36
+ return "f#{((color[:bri])? 'b' : '')+color[:fg].to_s} b#{color[:bg].to_s}"
37
+ end
38
+ def putHalfChar chr
39
+ @output += "<span class=\"float-char #{formatColor @leftColor}\">#{chr}</span>"
40
+ @leftColor = nil
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,124 @@
1
+ #encoding: utf-8
2
+ module AnsiArt
3
+ class PngConverter < Converter
4
+ def initialize width, options
5
+ super()
6
+
7
+ # GD Image Library
8
+ if RUBY_VERSION > '1.9'
9
+ require 'gd2-ffij'
10
+ else
11
+ require 'gd2'
12
+ $KCODE = 'u'
13
+ require 'jcode'
14
+ String.class_eval do
15
+ def ascii_only?
16
+ !self.mb_char?
17
+ end
18
+ end
19
+ end
20
+ self.class.class_eval('include GD2')
21
+ Image.class_eval('def p *arg; end;') # the gd2 gem puts useless data, mute it
22
+
23
+ @options = options
24
+ @fontsize = width.to_i / 40
25
+ height = @fontsize * 23
26
+ @image = Image::TrueColor.new(width,height)
27
+ @canvas = Canvas.new @image
28
+ @canvas.font = Font::TrueType['./uming.ttc', @fontsize,{
29
+ :dpi => 72,
30
+ :charmap => Font::TrueType::CHARMAP_UNICODE,
31
+ :linespacing => 1.0}]
32
+ @canvas.move 0, - (@drift=@canvas.font.bounding_rectangle('龜')[:upper_left][1])
33
+
34
+ @palette = {:normal => [Color[0,0,0],Color[128,0,0],Color[0,128,0],Color[128,128,0],
35
+ Color[0,0,128],Color[128,0,128],Color[0,128,128],Color[192,192,192]],
36
+ :bright => [Color[128,128,128],Color[255,0,0],Color[0,255,0],Color[255,255,0],
37
+ Color[0,0,255],Color[255,0,255],Color[0,255,255],Color[255,255,255]]}
38
+ end
39
+ def put str
40
+ return if str.empty?
41
+
42
+ # if we got a dual color char, draw it now
43
+ unless @leftColor.nil?
44
+ c = str[/./]
45
+ drawChar c,false
46
+
47
+ # overlap left part
48
+ @image.with_clipping x = @canvas.location[0],
49
+ y = @canvas.location[1] + @drift,
50
+ x + @fontsize/2 -1,
51
+ y + @fontsize - 1 do |image|
52
+ drawChar c, true, @leftColor
53
+ end
54
+ str[/./] = ''
55
+ @leftColor = nil
56
+ end
57
+
58
+ str.each_char do |c|
59
+ drawChar c
60
+ end
61
+ end
62
+ def newLine
63
+ @canvas.move_to 0, @canvas.location[1] + @fontsize
64
+ # if no enough space for the new line, resize image
65
+ if @canvas.location[1] + @fontsize + @drift > @image.height && !@options[:fixedHeight]
66
+ @image.crop! 0,0,@image.width,@image.height + @fontsize
67
+ end
68
+ end
69
+ def output
70
+ if @options[:path]
71
+ @image.export @options[:path], {:format => 'png',:level => 9};
72
+ return @options[:path] # return a path back
73
+ else
74
+ return @image.png(9)
75
+ end
76
+ end
77
+ private
78
+ def drawChar c, move=true, color=@color
79
+ width = @fontsize * ((c.ascii_only?)? 0.5 : 1)
80
+
81
+ # draw background first
82
+ @canvas.color = @palette[:normal][color[:bg]]
83
+
84
+ x = @canvas.location[0]
85
+ y = @canvas.location[1] + @drift
86
+ @canvas.rectangle x, y, x+width-1, y+@fontsize - 1,true
87
+
88
+ # draw text
89
+ @canvas.color = @palette[(color[:bri])? :bright : :normal][color[:fg]]
90
+
91
+ @canvas.text c unless graphChar c,x,y
92
+
93
+ @canvas.move width,0 if move
94
+ end
95
+ def graphChar ch, x, y
96
+ # right bottom point of full width char
97
+ y2 = y + @fontsize - 1
98
+ x2 = x + @fontsize - 1
99
+
100
+ case ch.ord
101
+ when (0x2581..0x2588) # 1/8 to full block, see Unicode Spec
102
+ @canvas.rectangle x, y + (0x2588 - ch.ord).to_f / 8 * @fontsize,
103
+ x2, y2, true
104
+ when (0x2589..0x258F) # 7/8 - 1/8 left block
105
+ @canvas.rectangle x, y,
106
+ x + (0x258F - ch.ord).to_f / 8 * @fontsize,
107
+ y2, true
108
+ when 0x25E2 # /|
109
+ @canvas.polygon [[x,y2], [x2,y], [x2,y2]],true
110
+ when 0x25E3 # |\
111
+ @canvas.polygon [[x,y], [x,y2], [x2,y2]], true
112
+ when 0x25E4 # |/
113
+ @canvas.polygon [[x,y], [x, y2], [x2,y]], true
114
+ when 0x25E5 # \|
115
+ @canvas.polygon [[x,y], [x2,y], [x2,y2]], true
116
+ when 0xFFE3
117
+ @canvas.rectangle x, y,
118
+ x2, y + @fontsize / 8, true
119
+ else return false
120
+ end
121
+ true
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,3 @@
1
+ module AnsiArt
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ansi_art
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - albb0920
14
+ - miaout17
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-08-29 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: gd2-ffij
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 25
30
+ segments:
31
+ - 0
32
+ - 0
33
+ - 3
34
+ version: 0.0.3
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ffi
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 5
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 9
50
+ version: 1.0.9
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ description: Render AsciiArt to HTML and PNG format
54
+ email:
55
+ - albb0920@gmail.com
56
+ executables: []
57
+
58
+ extensions: []
59
+
60
+ extra_rdoc_files: []
61
+
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - LICENSE
66
+ - README.md
67
+ - Rakefile
68
+ - ansi.css
69
+ - ansi.ie9.css
70
+ - ansi_art.gemspec
71
+ - lib/ansi_art.rb
72
+ - lib/ansi_art/buffer.rb
73
+ - lib/ansi_art/converter.rb
74
+ - lib/ansi_art/document.rb
75
+ - lib/ansi_art/html_converter.rb
76
+ - lib/ansi_art/png_converter.rb
77
+ - lib/ansi_art/version.rb
78
+ homepage: https://github.com/albb0920/big5-ansiart
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project: ansi_art
107
+ rubygems_version: 1.8.6
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: ANSI AsciiArt Renderer
111
+ test_files: []
112
+