box_layout 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-03-24
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
data/Manifest.txt ADDED
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/box_layout.rb
6
+ test/test_box_layout.rb
data/README.txt ADDED
@@ -0,0 +1,65 @@
1
+ BoxParse
2
+ ported to ruby by Ryan Davis, ryand-ruby@zenspider.com
3
+ http://seattlerb.rubyforge.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Allows you to lay out HTML using ASCII art. Stolen from psykotic's
8
+ code posted to reddit: http://programming.reddit.com/info/k9dx/comments
9
+
10
+ == SYNOPSIS:
11
+
12
+ require 'box_layout'
13
+
14
+ page_template = <<-END
15
+ ----------
16
+ | |
17
+ ----------
18
+ | | | |
19
+ | | | |
20
+ | | | |
21
+ | | | |
22
+ ----------
23
+ | |
24
+ ----------
25
+ END
26
+
27
+ layout = BoxLayout.html page_template
28
+ puts "<title>cute</title>"
29
+ puts "<style>* { border: 1px solid black }</style>"
30
+ puts layout % %w[header left body right footer].map {|s| "**#{s}**" }
31
+
32
+ == REQUIREMENTS:
33
+
34
+ * ruby 1.8+
35
+ * rubygems
36
+ * hoe
37
+
38
+ == INSTALL:
39
+
40
+ * sudo gem install box_layout
41
+
42
+ == LICENSE:
43
+
44
+ (The MIT License)
45
+
46
+ Copyright (c) 2007 Ryan Davis, ryand-ruby@zenspider.com
47
+
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of this software and associated documentation files (the
50
+ 'Software'), to deal in the Software without restriction, including
51
+ without limitation the rights to use, copy, modify, merge, publish,
52
+ distribute, sublicense, and/or sell copies of the Software, and to
53
+ permit persons to whom the Software is furnished to do so, subject to
54
+ the following conditions:
55
+
56
+ The above copyright notice and this permission notice shall be
57
+ included in all copies or substantial portions of the Software.
58
+
59
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
60
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
62
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
64
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
65
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/box_layout.rb'
6
+
7
+ Hoe.new('box_layout', BoxLayout::VERSION) do |p|
8
+ p.rubyforge_name = 'seattlerb'
9
+ p.summary = 'Allows you to lay out HTML using ASCII art.'
10
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
11
+ p.url = p.paragraphs_of('README.txt', 0).first[/http.*/]
12
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
13
+ end
14
+
15
+ # vim: syntax=Ruby
data/lib/box_layout.rb ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'set'
4
+
5
+ class Box
6
+ attr_accessor :x, :y, :right, :bottom
7
+ def initialize(x, y, right, bottom)
8
+ @x, @y, @right, @bottom = x, y, right, bottom
9
+ end
10
+
11
+ def == o
12
+ x = o.x and y = o.y and right == o.right and bottom == o.bottom
13
+ end
14
+ alias :eql? :==
15
+
16
+ def hash
17
+ [x, y, right, bottom].hash
18
+ end
19
+
20
+ def inspect
21
+ "Box[x=%d, y=%d, r=%d, b=%d]" % [x, y, right, bottom]
22
+ end
23
+ end
24
+
25
+ class BoxLayout
26
+ VERSION = '1.0.0'
27
+
28
+ def self.html(str)
29
+ layout = self.new
30
+ layout.parse(str)
31
+ layout.to_s
32
+ end
33
+
34
+ attr_reader :boxes, :grid
35
+ def initialize
36
+ @grid = []
37
+ @boxes = []
38
+ end
39
+
40
+ def parse(str)
41
+ @grid = str.strip.split(/\n/)
42
+ @boxes = [] # in case some dork is calling parse multiple times
43
+
44
+ grid.size.times do |y|
45
+ grid[y].size.times do |x|
46
+ if %w(- |).include? self[x, y] and
47
+ self[x, y + 1] == '|' and
48
+ self[x + 1, y] == '-' then
49
+ boxes << Box.new(x, y, box_right(x, y), box_bottom(x, y))
50
+ end
51
+ end
52
+ end
53
+ return boxes
54
+ end
55
+
56
+ def to_s
57
+ rowspans, colspans = box_rowspans, box_colspans
58
+ table = "<table border=\"border\">\n"
59
+ box_rows.each do |row|
60
+ table += " <tr>\n"
61
+ row.each do |box|
62
+ r, c = rowspans[box], colspans[box]
63
+ table += " <td"
64
+ table += " rowspan=\"%d\"" % r if r > 1
65
+ table += " colspan=\"%d\"" % c if c > 1
66
+ table += ">%s</td>\n"
67
+ end
68
+ table += " </tr>\n"
69
+ end
70
+ table += "</table>"
71
+ table
72
+ end
73
+
74
+ def box_x_delimeters
75
+ boxes.map { |box| box.right }.uniq.sort
76
+ end
77
+
78
+ def box_y_delimeters
79
+ boxes.map { |box| box.bottom }.uniq.sort
80
+ end
81
+
82
+ def box_rowspans
83
+ rowspans = Hash.new(0)
84
+ boxes.each do |box| rowspans[box] = 0 end
85
+
86
+ box_y_delimeters.each do |delim|
87
+ boxes.each do |box|
88
+ rowspans[box] += 1 if box.y < delim and box.bottom >= delim
89
+ end
90
+ end
91
+
92
+ rowspans
93
+ end
94
+
95
+ def box_colspans
96
+ colspans = Hash.new(0)
97
+ boxes.each do |box| colspans[box] = 0 end
98
+
99
+ box_x_delimeters.each do |delim|
100
+ boxes.each do |box|
101
+ colspans[box] += 1 if box.x < delim and box.right >= delim
102
+ end
103
+ end
104
+
105
+ colspans
106
+ end
107
+
108
+ def box_rows
109
+ rows, boxes_left = [], boxes.uniq
110
+ box_y_delimeters.each do |delim|
111
+ boxes_in_row, boxes_left = boxes_left.partition { |box| box.y < delim }
112
+ rows.push(boxes_in_row.sort_by { |box| box.x })
113
+ end
114
+ rows
115
+ end
116
+
117
+ # Rendering and parsing tables.
118
+
119
+ def [](x, y)
120
+ grid[y][x].chr rescue " "
121
+ end
122
+
123
+ def box_right(x, y)
124
+ # todo: find
125
+ (x..grid[y+1].size).each do |right|
126
+ return right if self[right + 1, y + 1] == '|'
127
+ end
128
+ raise "Unterminated box. c=#{self[x, y].inspect}"
129
+ end
130
+
131
+ def box_bottom(x, y)
132
+ # todo: find
133
+ (y..grid.size).each do |bottom|
134
+ return bottom if self[x + 1, bottom + 1] == '-'
135
+ end
136
+ raise "Unterminated box. c=#{self[x, y].inspect}"
137
+ end
138
+
139
+ def parse_ascii_table(table)
140
+ grid = table.strip.split(/\n/)
141
+ boxes = []
142
+
143
+ grid.size.times do |y|
144
+ grid[y].size.times do |x|
145
+ if %w(- |).include? self[x, y] and
146
+ self[x, y + 1] == '|' and
147
+ self[x + 1, y] == '-' then
148
+ boxes << Box.new(x, y, box_right(x, y), box_bottom(x, y))
149
+ end
150
+ end
151
+ end
152
+ return boxes
153
+ end
154
+ end
@@ -0,0 +1,150 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'test/unit'
4
+ require 'box_layout'
5
+
6
+ class TestBoxLayout < Test::Unit::TestCase
7
+ def setup
8
+ @grid = "
9
+ ---------
10
+ | | |
11
+ ---------
12
+ | |
13
+ ---------
14
+ ".strip.split(/\n/)
15
+
16
+ @layout = BoxLayout.new
17
+ @layout.parse(@grid.join("\n"))
18
+
19
+ @boxes = []
20
+ @boxes << Box.new(0, 0, 3, 1)
21
+ @boxes << Box.new(4, 0, 7, 1)
22
+ @boxes << Box.new(0, 2, 7, 3)
23
+
24
+ @expected_html = "
25
+ <table border=\"border\">
26
+ <tr>
27
+ <td>%s</td>
28
+ <td>%s</td>
29
+ </tr>
30
+ <tr>
31
+ <td colspan=\"2\">%s</td>
32
+ </tr>
33
+ </table>
34
+ ".strip
35
+
36
+
37
+ end
38
+
39
+ def test_class_html
40
+ html = BoxLayout.html(@grid.join("\n"))
41
+ assert_equal @expected_html, html
42
+ end
43
+
44
+ def test_class_html_big
45
+ table = "
46
+ ---------------------------
47
+ | | | |
48
+ | | | |
49
+ | | | |
50
+ | |-------| |
51
+ | | | |
52
+ | | |-------|
53
+ | | | |
54
+ | | | |
55
+ |---------| |-------|
56
+ | | | | |
57
+ | | |-------| |
58
+ | | | | |
59
+ | | | | |
60
+ | | | | |
61
+ ---------------------------
62
+ "
63
+ expected = "<table border=\"border\">
64
+ <tr>
65
+ <td rowspan=\"3\" colspan=\"2\">%s</td>
66
+ <td>%s</td>
67
+ <td rowspan=\"2\">%s</td>
68
+ </tr>
69
+ <tr>
70
+ <td rowspan=\"3\">%s</td>
71
+ </tr>
72
+ <tr>
73
+ <td>%s</td>
74
+ </tr>
75
+ <tr>
76
+ <td rowspan=\"2\">%s</td>
77
+ <td rowspan=\"2\">%s</td>
78
+ <td rowspan=\"2\">%s</td>
79
+ </tr>
80
+ <tr>
81
+ <td>%s</td>
82
+ </tr>
83
+ </table>"
84
+
85
+ html = BoxLayout.html(table)
86
+ assert_equal expected, html
87
+ end
88
+
89
+ def test_to_s
90
+ assert_equal @expected_html, @layout.to_s
91
+ end
92
+
93
+ def test_char
94
+ assert_equal '-', @layout[0, 0]
95
+ assert_equal '|', @layout[0, 1]
96
+ assert_equal '-', @layout[0, 2]
97
+ assert_equal '-', @layout[1, 0]
98
+ assert_equal '-', @layout[2, 0]
99
+ assert_equal ' ', @layout[1, 1]
100
+ end
101
+
102
+ def test_box_bottom
103
+ assert_equal(1, @layout.box_bottom(0, 0))
104
+ assert_equal(3, @layout.box_bottom(0, 2))
105
+ assert_equal(3, @layout.box_bottom(4, 2))
106
+ assert_equal(3, @layout.box_bottom(7, 2))
107
+ end
108
+
109
+ def test_box_right
110
+ assert_equal(3, @layout.box_right(0, 0))
111
+ assert_equal(7, @layout.box_right(0, 2))
112
+ assert_equal(7, @layout.box_right(4, 2))
113
+ assert_equal(7, @layout.box_right(7, 2))
114
+ end
115
+
116
+ def test_box_colspans
117
+ expect = {
118
+ @boxes[0] => 1,
119
+ @boxes[1] => 1,
120
+ @boxes[2] => 2,
121
+ }
122
+ assert_equal expect, @layout.box_colspans
123
+ end
124
+
125
+ def test_box_rowspans
126
+ expect = {
127
+ @boxes[0] => 1,
128
+ @boxes[1] => 1,
129
+ @boxes[2] => 1,
130
+ }
131
+ assert_equal expect, @layout.box_rowspans
132
+ end
133
+
134
+ def test_box_rows
135
+ assert_equal [@boxes[0..1], [@boxes[2]]], @layout.box_rows
136
+ end
137
+
138
+ def test_box_x_delimeters
139
+ assert_equal [3, 7], @layout.box_x_delimeters
140
+ end
141
+
142
+ def test_box_y_delimeters
143
+ assert_equal [1, 3], @layout.box_y_delimeters
144
+ end
145
+
146
+ def test_parse
147
+ result = @layout.parse(@grid.join("\n"))
148
+ assert_equal @boxes, result
149
+ end
150
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0.9
3
+ specification_version: 1
4
+ name: box_layout
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-03-24 00:00:00 -07:00
8
+ summary: Allows you to lay out HTML using ASCII art.
9
+ require_paths:
10
+ - lib
11
+ email: ryand-ruby@zenspider.com
12
+ homepage: http://seattlerb.rubyforge.org/
13
+ rubyforge_project: seattlerb
14
+ description: "Allows you to lay out HTML using ASCII art. Stolen from psykotic's code posted to reddit: http://programming.reddit.com/info/k9dx/comments == SYNOPSIS: require 'box_layout' page_template = <<-END ---------- | | ---------- | | | | | | | | | | | | | | | | ---------- | | ---------- END layout = BoxLayout.html page_template puts \"<title>cute</title>\" puts \"<style>* { border: 1px solid black }</style>\" puts layout % %w[header left body right footer].map {|s| \"**#{s}**\" } == REQUIREMENTS:"
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Ryan Davis
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - lib/box_layout.rb
37
+ - test/test_box_layout.rb
38
+ test_files:
39
+ - test/test_box_layout.rb
40
+ rdoc_options: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ requirements: []
49
+
50
+ dependencies:
51
+ - !ruby/object:Gem::Dependency
52
+ name: hoe
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Version::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 1.2.0
59
+ version: