tablemaker 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.
- 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
|