tablemaker 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +110 -0
- data/Rakefile +10 -0
- data/lib/tablemaker.rb +15 -0
- data/lib/tablemaker/frame.rb +143 -0
- data/lib/tablemaker/railtie.rb +14 -0
- data/lib/tablemaker/version.rb +3 -0
- data/lib/tablemaker/view_helpers.rb +100 -0
- data/tablemaker.gemspec +24 -0
- data/test/helper.rb +8 -0
- data/test/test_action_view_helper.rb +62 -0
- data/test/test_tablemaker.rb +231 -0
- metadata +134 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Levin Alexander
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# Tablemaker
|
2
|
+
|
3
|
+
HTML table generator that allows arbitrary nested cell subdivisions
|
4
|
+
and applies colspan/rowspan as needed.
|
5
|
+
|
6
|
+
## Examples
|
7
|
+
|
8
|
+
A very basic table:
|
9
|
+
|
10
|
+
# +---+---+
|
11
|
+
# | A | B |
|
12
|
+
# +---+---+
|
13
|
+
# | C | D |
|
14
|
+
# +---+---+
|
15
|
+
#
|
16
|
+
@table2 = Tablemaker.column do |c|
|
17
|
+
c.row do |r|
|
18
|
+
r.cell("A")
|
19
|
+
r.cell("B")
|
20
|
+
end
|
21
|
+
c.row do |r|
|
22
|
+
@c2 = r.cell("C")
|
23
|
+
@d2 = r.cell("D")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# but you can also start with columns and construct the table left-to-right. this produces the exact same result:
|
28
|
+
#
|
29
|
+
Tablemaker.row do |r|
|
30
|
+
r.column do |c|
|
31
|
+
c.cell("A")
|
32
|
+
c.cell("C")
|
33
|
+
end
|
34
|
+
r.column do |c|
|
35
|
+
c.cell("B")
|
36
|
+
c.cell("D")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
A more advanced example:
|
41
|
+
|
42
|
+
# +---+---+---+
|
43
|
+
# | | B | |
|
44
|
+
# | +---+ C |
|
45
|
+
# | | D | |
|
46
|
+
# | A +---+---+
|
47
|
+
# | | | F |
|
48
|
+
# | | E +---+
|
49
|
+
# | | | G |
|
50
|
+
# +---+---+---+
|
51
|
+
#
|
52
|
+
@table = Tablemaker.row do |t|
|
53
|
+
t.cell("A")
|
54
|
+
t.column do |r|
|
55
|
+
r.row do |c|
|
56
|
+
c.column do |rr|
|
57
|
+
rr.cell("B")
|
58
|
+
rr.cell("D")
|
59
|
+
end
|
60
|
+
c.cell("C")
|
61
|
+
end
|
62
|
+
r.row do |c|
|
63
|
+
c.cell("E")
|
64
|
+
c.column do |rr|
|
65
|
+
rr.cell("F")
|
66
|
+
rr.cell("G")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
this will generate the following output:
|
74
|
+
|
75
|
+
<table>
|
76
|
+
<tr>
|
77
|
+
<td rowspan=4>A</td>
|
78
|
+
<td rowspan=2>B</td>
|
79
|
+
<td>D</td>
|
80
|
+
</tr>
|
81
|
+
<tr>
|
82
|
+
<td>E</td>
|
83
|
+
</tr>
|
84
|
+
<tr>
|
85
|
+
<td rowspan=2>C</td>
|
86
|
+
<td>F</td>
|
87
|
+
</tr>
|
88
|
+
<tr>
|
89
|
+
<td>G</td>
|
90
|
+
</tr>
|
91
|
+
</table>
|
92
|
+
|
93
|
+
|
94
|
+
Tablemaker keeps track of all the rowspan/colspan attributes required to generate a valid HTML table
|
95
|
+
|
96
|
+
## Installation
|
97
|
+
|
98
|
+
Add this line to your application's Gemfile:
|
99
|
+
|
100
|
+
gem 'tablemaker'
|
101
|
+
|
102
|
+
And then execute:
|
103
|
+
|
104
|
+
$ bundle
|
105
|
+
|
106
|
+
Or install it yourself as:
|
107
|
+
|
108
|
+
$ gem install tablemaker
|
109
|
+
|
110
|
+
|
data/Rakefile
ADDED
data/lib/tablemaker.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "tablemaker/version"
|
2
|
+
require "tablemaker/frame"
|
3
|
+
require 'fiber'
|
4
|
+
|
5
|
+
module Tablemaker
|
6
|
+
def self.column(&blk)
|
7
|
+
Column.new(&blk)
|
8
|
+
end
|
9
|
+
def self.row(&blk)
|
10
|
+
Row.new(&blk)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'tablemaker/railtie' if defined?(Rails)
|
@@ -0,0 +1,143 @@
|
|
1
|
+
|
2
|
+
module Tablemaker
|
3
|
+
class Frame
|
4
|
+
attr_reader :parent
|
5
|
+
def initialize(parent, idx)
|
6
|
+
@parent = parent
|
7
|
+
@index = idx
|
8
|
+
end
|
9
|
+
def last?
|
10
|
+
return nil unless @parent
|
11
|
+
@index == @parent.items.length-1
|
12
|
+
end
|
13
|
+
def dimensions
|
14
|
+
[columns, rows]
|
15
|
+
end
|
16
|
+
def real_rows
|
17
|
+
return rows unless @parent
|
18
|
+
if @parent.is_a?(Column)
|
19
|
+
return rows unless last?
|
20
|
+
return rows + @parent.real_rows - @parent.rows
|
21
|
+
else
|
22
|
+
@parent.real_rows
|
23
|
+
end
|
24
|
+
end
|
25
|
+
def real_cols
|
26
|
+
return columns unless @parent
|
27
|
+
if @parent.is_a?(Column)
|
28
|
+
@parent.real_cols
|
29
|
+
else
|
30
|
+
return columns unless last?
|
31
|
+
return columns + @parent.real_cols - @parent.columns
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def real_dimensions
|
35
|
+
[real_cols, real_rows]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Cell < Frame
|
40
|
+
def initialize(parent, idx, data)
|
41
|
+
super(parent, idx)
|
42
|
+
@data = data
|
43
|
+
end
|
44
|
+
def data
|
45
|
+
@data
|
46
|
+
end
|
47
|
+
|
48
|
+
def cell_iterator
|
49
|
+
yield self
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def rows; 1 end
|
54
|
+
def columns; 1 end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Node < Frame
|
58
|
+
attr_reader :items
|
59
|
+
include Enumerable
|
60
|
+
|
61
|
+
def initialize(p=nil, idx = nil)
|
62
|
+
super
|
63
|
+
@items = []
|
64
|
+
yield self
|
65
|
+
end
|
66
|
+
|
67
|
+
def cell(*args)
|
68
|
+
Cell.new(self, @items.length, *args).tap { |c| @items << c }
|
69
|
+
end
|
70
|
+
|
71
|
+
def cells
|
72
|
+
f = Fiber.new do
|
73
|
+
cell_iterator do |i|
|
74
|
+
yield i
|
75
|
+
end
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
f = f.resume while f && f.alive?
|
79
|
+
end
|
80
|
+
|
81
|
+
def each_row
|
82
|
+
items = []
|
83
|
+
f = Fiber.new do
|
84
|
+
cell_iterator do |i|
|
85
|
+
items << i
|
86
|
+
end
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
while f && f.alive?
|
91
|
+
f = f.resume
|
92
|
+
yield items unless items.empty?
|
93
|
+
items = []
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class Column < Node
|
99
|
+
def row(&blk)
|
100
|
+
Row.new(self, @items.length, &blk).tap { |r| @items << r }
|
101
|
+
end
|
102
|
+
def columns
|
103
|
+
@items.map(&:columns).max || 0
|
104
|
+
end
|
105
|
+
def rows
|
106
|
+
@items.map(&:rows).inject(0, &:+)
|
107
|
+
end
|
108
|
+
|
109
|
+
def cell_iterator(&blk)
|
110
|
+
@items.each do |i|
|
111
|
+
i.cell_iterator(&blk)
|
112
|
+
Fiber.yield(Fiber.current)
|
113
|
+
end
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Row < Node
|
119
|
+
def column(&blk)
|
120
|
+
Column.new(self, @items.length, &blk).tap { |c| @items << c }
|
121
|
+
end
|
122
|
+
def columns
|
123
|
+
@items.map(&:columns).inject(0, &:+)
|
124
|
+
end
|
125
|
+
def rows
|
126
|
+
@items.map(&:rows).max || 0
|
127
|
+
end
|
128
|
+
|
129
|
+
def cell_iterator(&blk)
|
130
|
+
fibers = @items.map do |i|
|
131
|
+
Fiber.new do
|
132
|
+
i.cell_iterator(&blk)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
while !fibers.empty?
|
137
|
+
fibers = fibers.map { |f| f.resume }.compact
|
138
|
+
Fiber.yield(Fiber.current)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'tablemaker/view_helpers'
|
2
|
+
|
3
|
+
module Tablemaker
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
initializer "tablemaker.configure" do |app|
|
6
|
+
ActiveSupport.on_load :action_view do
|
7
|
+
require 'tablemaker/view_helpers'
|
8
|
+
include Tablemaker::ViewHelpers::ActionView
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
|
3
|
+
module Tablemaker
|
4
|
+
module ViewHelpers
|
5
|
+
module ActionView
|
6
|
+
class TableHelper
|
7
|
+
def initialize(context, &block)
|
8
|
+
@context = context
|
9
|
+
@stack = []
|
10
|
+
@root = Tablemaker.column do |r|
|
11
|
+
stack(r) do
|
12
|
+
yield self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def row
|
18
|
+
current.row do |r|
|
19
|
+
stack(r) do
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def column(&blk)
|
26
|
+
if @stack.size == 1
|
27
|
+
row do
|
28
|
+
column(&blk)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
current.column do |c|
|
32
|
+
stack(c, &blk)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def td(*args, &blk)
|
38
|
+
cell("td", *args, &blk)
|
39
|
+
end
|
40
|
+
|
41
|
+
def th(*args, &blk)
|
42
|
+
cell("th", *args, &blk)
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_html(attrs = {})
|
46
|
+
context.content_tag("table", attrs) do
|
47
|
+
@root.each_row do |r|
|
48
|
+
s = context.content_tag("tr") do
|
49
|
+
r.each do |c|
|
50
|
+
attrs = {}
|
51
|
+
attrs[:rowspan] = c.real_rows if c.real_rows > 1
|
52
|
+
attrs[:colspan] = c.real_cols if c.real_cols > 1
|
53
|
+
s2 = context.content_tag(c.data[:name], c.data[:opts].merge(attrs)) do
|
54
|
+
c.data[:text]
|
55
|
+
end
|
56
|
+
|
57
|
+
context.concat(s2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
context.concat(s)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def cell(name, *args, &block)
|
69
|
+
opts = args.extract_options!
|
70
|
+
text = if block_given?
|
71
|
+
@context.capture(&block)
|
72
|
+
else
|
73
|
+
args.shift
|
74
|
+
end
|
75
|
+
current.cell(text: text, name: name, opts: opts)
|
76
|
+
end
|
77
|
+
|
78
|
+
def stack(frame)
|
79
|
+
@stack.push(frame)
|
80
|
+
yield
|
81
|
+
@stack.pop
|
82
|
+
end
|
83
|
+
|
84
|
+
def context
|
85
|
+
@context
|
86
|
+
end
|
87
|
+
|
88
|
+
def current
|
89
|
+
@stack.last
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def make_table(opts = {}, &block)
|
96
|
+
table = TableHelper.new(self, &block).to_html(opts)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/tablemaker.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/tablemaker/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Levin Alexander"]
|
6
|
+
gem.email = ["mail@levinalex.net"]
|
7
|
+
gem.description = "HTML table generator that allows arbitrary nested cell subdivisions and applies colspan/rowspan as needed."
|
8
|
+
|
9
|
+
gem.summary = ""
|
10
|
+
gem.homepage = "https://github.com/levinalex/tablemaker"
|
11
|
+
|
12
|
+
gem.files = `git ls-files`.split($\)
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "tablemaker"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = Tablemaker::VERSION
|
18
|
+
|
19
|
+
gem.add_dependency "rake"
|
20
|
+
gem.add_dependency "psych"
|
21
|
+
gem.add_development_dependency "minitest"
|
22
|
+
gem.add_development_dependency "rails", ">= 3.1.0"
|
23
|
+
end
|
24
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestTableMaker < ActionView::TestCase
|
4
|
+
include Tablemaker::ViewHelpers::ActionView
|
5
|
+
|
6
|
+
setup do
|
7
|
+
ActionView::Base.send(:include, Tablemaker::ViewHelpers::ActionView)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "should integrate with ActiveRecord::Base" do
|
11
|
+
assert_respond_to ActionView::Base.new, :make_table
|
12
|
+
end
|
13
|
+
|
14
|
+
test "should output simple table correctly" do
|
15
|
+
table = make_table(class: "table") do |t|
|
16
|
+
t.row do
|
17
|
+
t.th("A", style: "color: red")
|
18
|
+
t.td("B")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
expected = "<table class='table'><tr><th style='color: red'>A</th><td>B</td></tr></table>"
|
23
|
+
assert_dom_equal expected, table
|
24
|
+
end
|
25
|
+
|
26
|
+
test "should output simple table starting with columns correctly" do
|
27
|
+
table = make_table do |t|
|
28
|
+
t.column do
|
29
|
+
t.td("A")
|
30
|
+
t.td("B")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
expected = "<table><tr><td>A</td></tr><tr><td>B</td></tr></table>"
|
35
|
+
assert_dom_equal expected, table
|
36
|
+
end
|
37
|
+
|
38
|
+
test "should output complex table correctly" do
|
39
|
+
table = make_table do |t|
|
40
|
+
t.row do
|
41
|
+
t.td("A")
|
42
|
+
t.td("B")
|
43
|
+
t.td("C")
|
44
|
+
end
|
45
|
+
t.row do
|
46
|
+
t.column do
|
47
|
+
t.td("E")
|
48
|
+
t.td("F")
|
49
|
+
end
|
50
|
+
t.td("G")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
expected = "<table>" +
|
55
|
+
"<tr><td>A</td><td>B</td><td>C</td></tr>" +
|
56
|
+
"<tr><td>E</td><td rowspan=2 colspan=2>G</td></tr>" +
|
57
|
+
"<tr><td>F</td></tr>" +
|
58
|
+
"</table>"
|
59
|
+
|
60
|
+
assert_dom_equal expected, table
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
|
4
|
+
def assert_table_structure(structure, table)
|
5
|
+
structure = structure
|
6
|
+
|
7
|
+
t = []
|
8
|
+
table.each_row do |row|
|
9
|
+
r = []
|
10
|
+
row.each do |cell|
|
11
|
+
r << cell
|
12
|
+
end
|
13
|
+
t << r
|
14
|
+
end
|
15
|
+
assert_equal structure, t
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "an example table" do
|
19
|
+
before do
|
20
|
+
|
21
|
+
# +---+---+---+
|
22
|
+
# | | B | |
|
23
|
+
# | +---+ C |
|
24
|
+
# | | D | |
|
25
|
+
# | A +---+---+
|
26
|
+
# | | | F |
|
27
|
+
# | | E +---+
|
28
|
+
# | | | G |
|
29
|
+
# +---+---+---+
|
30
|
+
#
|
31
|
+
@table = Tablemaker.row do |t|
|
32
|
+
@a = t.cell("A")
|
33
|
+
t.column do |r|
|
34
|
+
@row = r.row do |c|
|
35
|
+
@col = c.column do |rr|
|
36
|
+
@b = rr.cell("B")
|
37
|
+
@d = rr.cell("D")
|
38
|
+
end
|
39
|
+
@c = c.cell("C")
|
40
|
+
end
|
41
|
+
r.row do |c|
|
42
|
+
@e = c.cell("E")
|
43
|
+
c.column do |rr|
|
44
|
+
@f = rr.cell("F")
|
45
|
+
@g = rr.cell("G")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should compile without errors" do
|
53
|
+
assert @table
|
54
|
+
assert_kind_of Tablemaker::Node, @table
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return a Row for #row" do
|
58
|
+
assert_kind_of Tablemaker::Row, @row
|
59
|
+
assert_equal 2, @row.rows
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return a Column for #column" do
|
63
|
+
assert_kind_of Tablemaker::Column, @col
|
64
|
+
assert_equal 1, @col.columns
|
65
|
+
assert_equal 2, @col.rows
|
66
|
+
end
|
67
|
+
|
68
|
+
it "items should have correct dimensions" do
|
69
|
+
assert_equal 4, @table.rows
|
70
|
+
assert_equal 3, @table.columns
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have real dimensions for cells" do
|
74
|
+
assert_equal [1,4], @a.real_dimensions
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should yield cells in the correct order" do
|
78
|
+
assert_equal [@a, @b, @c, @d, @e, @f, @g], @table.to_enum(:cells).to_a
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should allow iteration over rows/cols" do
|
82
|
+
assert_table_structure [[@a, @b, @c], [@d], [@e, @f], [@g]], @table
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "a simple column" do
|
87
|
+
before do
|
88
|
+
@col = Tablemaker.column do |c|
|
89
|
+
c.cell("A")
|
90
|
+
c.cell("B")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should have 2 rows, 1 column" do
|
95
|
+
assert_equal 2, @col.rows
|
96
|
+
assert_equal 1, @col.columns
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "nested columns" do
|
101
|
+
before do
|
102
|
+
@col = Tablemaker.column do |c|
|
103
|
+
c.cell("A")
|
104
|
+
@row = c.row do |r|
|
105
|
+
r.column do |c2|
|
106
|
+
c2.cell("B")
|
107
|
+
c2.cell("C")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should have 3 rows, 1 column" do
|
114
|
+
assert_equal 3, @col.rows
|
115
|
+
assert_equal 1, @col.columns
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "simple 3/2" do
|
120
|
+
before do
|
121
|
+
|
122
|
+
# +---+---+---+
|
123
|
+
# | A | B | C |
|
124
|
+
# +---+---+---+
|
125
|
+
# | D | E |
|
126
|
+
# +---+-------+
|
127
|
+
#
|
128
|
+
@table = Tablemaker.column do |t|
|
129
|
+
@r1 = t.row do |r1|
|
130
|
+
@a = r1.cell("A")
|
131
|
+
@b = r1.cell("B")
|
132
|
+
@c = r1.cell("C")
|
133
|
+
end
|
134
|
+
@r2 = t.row do |r2|
|
135
|
+
@d = r2.cell("D")
|
136
|
+
@e = r2.cell("E")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "spanning cols/rows at the same time" do
|
143
|
+
before do
|
144
|
+
|
145
|
+
# +---+---+---+
|
146
|
+
# | A | B | C |
|
147
|
+
# +---+---+---+
|
148
|
+
# | D | |
|
149
|
+
# +---+ F |
|
150
|
+
# | E | |
|
151
|
+
# +---+-------+
|
152
|
+
#
|
153
|
+
@table = Tablemaker.column do |t|
|
154
|
+
@r1 = t.row do |r1|
|
155
|
+
@a = r1.cell("A")
|
156
|
+
@b = r1.cell("B")
|
157
|
+
@c = r1.cell("C")
|
158
|
+
end
|
159
|
+
@r2 = t.row do |r2|
|
160
|
+
@c1 = @c1 = r2.column do |c1|
|
161
|
+
@d = c1.cell("D")
|
162
|
+
@e = c1.cell("E")
|
163
|
+
end
|
164
|
+
@c2 = r2.column do |c2|
|
165
|
+
@f = c2.cell("F")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should correctly identify last cols" do
|
172
|
+
assert !@r1.last?, "r1 is not last col"
|
173
|
+
assert @r2.last?, "r2 is last col"
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should have correct dimensions on items" do
|
177
|
+
assert_equal [3,3], @table.dimensions
|
178
|
+
assert_equal [3,1], @r1.dimensions
|
179
|
+
assert_equal [1,1], @a.dimensions
|
180
|
+
assert_equal [3,2], @r2.real_dimensions
|
181
|
+
assert_equal [1,2], @c1.real_dimensions
|
182
|
+
assert_equal [2,2], @c2.real_dimensions
|
183
|
+
assert_equal [2,2], @f.real_dimensions
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should iterate correctly over subitems" do
|
187
|
+
assert_equal [@a, @b, @c], @r1.to_enum(:cells).to_a
|
188
|
+
assert_equal [@d, @f, @e], @r2.to_enum(:cells).to_a
|
189
|
+
assert_equal [@a, @b, @c, @d, @f, @e], @table.to_enum(:cells).to_a
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
it "should allow iteration over rows/cols" do
|
194
|
+
assert_table_structure [[@a, @b, @c], [@d, @f], [@e]], @table
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "starting with rows or columns does not matter" do
|
199
|
+
|
200
|
+
before do
|
201
|
+
@table1 = Tablemaker.row do |r|
|
202
|
+
r.column do |c|
|
203
|
+
@a1 = c.cell("A")
|
204
|
+
@c1 = c.cell("C")
|
205
|
+
end
|
206
|
+
r.column do |c|
|
207
|
+
@b1 = c.cell("B")
|
208
|
+
@d1 = c.cell("D")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
@table2 = Tablemaker.column do |c|
|
213
|
+
c.row do |r|
|
214
|
+
@a2 = r.cell("A")
|
215
|
+
@b2 = r.cell("B")
|
216
|
+
end
|
217
|
+
c.row do |r|
|
218
|
+
@c2 = r.cell("C")
|
219
|
+
@d2 = r.cell("D")
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should have correct structure" do
|
225
|
+
assert_table_structure [[@a1, @b1], [@c1, @d1]], @table1
|
226
|
+
assert_table_structure [[@a2, @b2], [@c2, @d2]], @table2
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
end
|
231
|
+
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tablemaker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Levin Alexander
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: psych
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: minitest
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 3.1.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 3.1.0
|
78
|
+
description: HTML table generator that allows arbitrary nested cell subdivisions and
|
79
|
+
applies colspan/rowspan as needed.
|
80
|
+
email:
|
81
|
+
- mail@levinalex.net
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- .travis.yml
|
88
|
+
- Gemfile
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
- Rakefile
|
92
|
+
- lib/tablemaker.rb
|
93
|
+
- lib/tablemaker/frame.rb
|
94
|
+
- lib/tablemaker/railtie.rb
|
95
|
+
- lib/tablemaker/version.rb
|
96
|
+
- lib/tablemaker/view_helpers.rb
|
97
|
+
- tablemaker.gemspec
|
98
|
+
- test/helper.rb
|
99
|
+
- test/test_action_view_helper.rb
|
100
|
+
- test/test_tablemaker.rb
|
101
|
+
homepage: https://github.com/levinalex/tablemaker
|
102
|
+
licenses: []
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
segments:
|
114
|
+
- 0
|
115
|
+
hash: 3601937828848287223
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
hash: 3601937828848287223
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 1.8.24
|
128
|
+
signing_key:
|
129
|
+
specification_version: 3
|
130
|
+
summary: ''
|
131
|
+
test_files:
|
132
|
+
- test/helper.rb
|
133
|
+
- test/test_action_view_helper.rb
|
134
|
+
- test/test_tablemaker.rb
|