ansi_art 0.0.1

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