tableview 0.2.0 → 0.3.0
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/README.md +26 -32
- data/lib/generators/tableview/install/install_generator.rb +16 -0
- data/lib/generators/tableview/tableview_generator.rb +23 -0
- data/lib/tableview/helper.rb +3 -2
- data/lib/tableview/output/ascii.rb +13 -9
- data/lib/tableview/output/csv.rb +1 -1
- data/lib/tableview/output/html.rb +27 -24
- data/lib/tableview/output/xls.rb +22 -24
- data/lib/tableview/tv.rb +8 -2
- data/lib/tableview/version.rb +1 -1
- data/lib/tableview/view_handler.rb +25 -6
- data/lib/tableview.rb +1 -1
- data/tableview.gemspec +2 -0
- metadata +19 -3
data/README.md
CHANGED
@@ -16,42 +16,36 @@ In your Gemfile:
|
|
16
16
|
then
|
17
17
|
|
18
18
|
$ bundle install
|
19
|
+
$ rails g tableview:install
|
19
20
|
|
20
|
-
|
21
|
+
To apply to a resource use the built in generator:
|
21
22
|
|
22
|
-
|
23
|
-
include Tableview::Responder
|
24
|
-
end
|
25
|
-
|
26
|
-
Then add this to your controller:
|
27
|
-
|
28
|
-
require "#{Rails.root}/lib/application_responder"
|
29
|
-
self.responder = ApplicationResponder
|
30
|
-
respond_to :html, :csv, :xls, :ascii, :only => :index
|
23
|
+
$ rails g tableview resource_name
|
31
24
|
|
32
|
-
|
25
|
+
This will create a partial named `_table.tv` in which you can use a DSL like this to define your table:
|
33
26
|
|
34
|
-
|
35
|
-
row.cell "First header cell", :align => :right
|
36
|
-
row.cell "You can do", "more cells at once"
|
37
|
-
end
|
27
|
+
=> @registrations
|
38
28
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
29
|
+
+ :first_name
|
30
|
+
+ :surname
|
31
|
+
+ :address {|reg| reg.address + "\n" + reg.postcode }
|
32
|
+
+ :friends if format.html?
|
45
33
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
We now have a column based DSL.
|
51
|
-
|
52
|
-
table.table_for @events
|
34
|
+
if format.xls?
|
35
|
+
= @registrations.some_scope, "Workbook title"
|
36
|
+
= @registration.other_scope, "Works as title in other formats as well"
|
37
|
+
end
|
53
38
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
39
|
+
The DSL is a simple superset of ruby with a few special characters (only work if first printable character on line, won't work with eval and friends).
|
40
|
+
|
41
|
+
Character | Meaning
|
42
|
+
----------|--------
|
43
|
+
`=>` | Use the passed collection for rendering and I18n
|
44
|
+
`*` | Pass a hash to this, is used to configure the formatters.
|
45
|
+
`+` | Defines a column. If passed a symbol, Tableview will use I18n to lookup the header and call the method on the model to get the value. Strings will be used literally. Optionally use a block to generate values.
|
46
|
+
`=` | Render a subtable for the passed collection. Not all formatters support subtables, use at own risk (notably the CSV formatter has no support for this). Is meant mainly to have nice full-featured excel files.
|
47
|
+
|
48
|
+
It will also add a few lines of code to your controller:
|
49
|
+
|
50
|
+
- `self.responder = ApplicationResponder` this sets up the correct code path to use for dynamically rendering all the formats.
|
51
|
+
- `respond_to :html, :json, :csv, :xls, :ascii` a list of supported formats. You will want to use `respond_with` as well.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Tableview
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
desc "Creates the responder file necessary for proper working of the plugin."
|
7
|
+
def create_application_responder
|
8
|
+
# record do |m|
|
9
|
+
# m.file "definition.txt", "definition.txt"
|
10
|
+
# end
|
11
|
+
lib 'application_responder.rb', "class ApplicationResponder < ActionController::Responder\n\tinclude Tableview::Responder\nend"
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Tableview
|
4
|
+
module Generators
|
5
|
+
class TableviewGenerator < ::Rails::Generators::NamedBase
|
6
|
+
namespace "tableview"
|
7
|
+
desc "Generates a partial and some controller code to use tableview."
|
8
|
+
def create_partial
|
9
|
+
cols = file_name.camelize.constantize.column_names
|
10
|
+
template = "=> @#{file_name.tableize}\n\n"
|
11
|
+
cols.each do |col|
|
12
|
+
template << "+ :#{col}\n"
|
13
|
+
end
|
14
|
+
create_file "app/views/#{file_name.tableize}/_table.tv", template
|
15
|
+
end
|
16
|
+
|
17
|
+
def install_into_controller
|
18
|
+
inject_into_class "app/controllers/#{file_name.tableize}_controller.rb", file_name.camelize.pluralize + "Controller", " self.responder = ApplicationResponder\n respond_to :html, :json, :csv, :xls, :ascii"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/tableview/helper.rb
CHANGED
@@ -9,8 +9,9 @@ module Tableview::Helper
|
|
9
9
|
@params[:format] == :html || @params[:format].blank?
|
10
10
|
end
|
11
11
|
|
12
|
-
def method_missing(name, args, &blk)
|
13
|
-
if m = name.match(/^(.+)\?$/)
|
12
|
+
def method_missing(name, *args, &blk)
|
13
|
+
if m = name.to_s.match(/^(.+)\?$/)
|
14
|
+
puts m.inspect, name.inspect
|
14
15
|
@params[:format] == m.captures.first
|
15
16
|
else
|
16
17
|
super
|
@@ -1,19 +1,23 @@
|
|
1
|
-
module Tableview::
|
1
|
+
module Tableview::Output
|
2
2
|
class ASCII
|
3
3
|
require 'terminal-table/import'
|
4
4
|
def process(tv)
|
5
|
-
@table =
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
@table = ""
|
6
|
+
tv.subtables.each do |sub|
|
7
|
+
@table << "# #{sub.title}" unless sub.title.blank?
|
8
|
+
@table << table { |t|
|
9
|
+
sub.parts.each do |part|
|
10
|
+
part.rows.each do |row|
|
11
|
+
t.add_row row.cells.map {|cell| {:value => cell.contents}.merge(cell.options) }
|
12
|
+
end
|
13
|
+
t.add_separator unless part == sub.parts.last
|
9
14
|
end
|
10
|
-
|
11
|
-
|
12
|
-
}
|
15
|
+
}.to_s
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
15
19
|
def to_s
|
16
|
-
@table
|
20
|
+
@table
|
17
21
|
end
|
18
22
|
|
19
23
|
end
|
data/lib/tableview/output/csv.rb
CHANGED
@@ -1,34 +1,37 @@
|
|
1
|
-
module Tableview::
|
1
|
+
module Tableview::Output
|
2
2
|
class HTML
|
3
3
|
def process(tv)
|
4
4
|
@table = ""
|
5
5
|
@p = 0
|
6
|
-
|
6
|
+
tv.subtables.each do |sub|
|
7
|
+
tag :h2, sub.title unless sub.title.blank?
|
8
|
+
tag :table, sub.options do
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
sub.parts.each do |part|
|
11
|
+
tag (case part.class.to_s
|
12
|
+
when "Tableview::ViewHandler::Header"
|
13
|
+
header = true
|
14
|
+
:thead
|
15
|
+
when "Tableview::ViewHandler::Footer"
|
16
|
+
:tfoot
|
17
|
+
when "Tableview::ViewHandler::Body"
|
18
|
+
:tbody
|
19
|
+
end), part.options do
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
part.rows.each do |row|
|
22
|
+
tag :tr, row.options do
|
23
|
+
row.cells.each do |cell|
|
24
|
+
tag( header || cell.options[:header] ? :th : :td, cell.options) do
|
25
|
+
@table += ERB::Util::html_escape(cell.contents.to_s)
|
26
|
+
end #td / #th
|
27
|
+
end
|
28
|
+
end #tr
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
end #t{part}
|
32
|
+
end
|
33
|
+
end #table
|
34
|
+
end
|
32
35
|
end
|
33
36
|
|
34
37
|
def tag(tag, attributes = {})
|
data/lib/tableview/output/xls.rb
CHANGED
@@ -1,38 +1,36 @@
|
|
1
|
-
module Tableview::
|
1
|
+
module Tableview::Output
|
2
2
|
class XLS
|
3
3
|
require 'spreadsheet'
|
4
|
-
HEADER_STYLE = {:align => :center, :weight => :bold
|
4
|
+
HEADER_STYLE = {:align => :center, :weight => :bold}
|
5
5
|
FOOTER_STYLE = {:weight => :bold }
|
6
6
|
|
7
7
|
def process(tv)
|
8
8
|
|
9
9
|
@table = Spreadsheet::Workbook.new
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
{}
|
23
|
-
end.merge part.options
|
10
|
+
tv.subtables.each do |sub|
|
11
|
+
sheet1 = @table.create_worksheet :name => sub.title
|
12
|
+
offset = 0
|
13
|
+
sub.parts.each do |part|
|
14
|
+
p_style = case part.class.to_s
|
15
|
+
when "Tableview::ViewHandler::Header"
|
16
|
+
HEADER_STYLE.dup
|
17
|
+
when "Tableview::ViewHandler::Footer"
|
18
|
+
FOOTER_STYLE.dup
|
19
|
+
else
|
20
|
+
{}
|
21
|
+
end.merge part.options
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
part.rows.each do |row|
|
24
|
+
style = p_style.merge row.options
|
25
|
+
row.cells.each_with_index do |cell, i|
|
26
|
+
format = Spreadsheet::Format.new style.merge(cell.options)
|
27
|
+
sheet1[offset, i] = cell.contents
|
28
|
+
sheet1.row(offset).set_format i, format
|
29
|
+
end
|
30
|
+
offset += 1
|
31
31
|
end
|
32
|
-
offset += 1
|
33
32
|
end
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
|
38
36
|
def to_s
|
data/lib/tableview/tv.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
module Tableview
|
2
2
|
class TV
|
3
3
|
def call(template)
|
4
|
+
source = template.source
|
5
|
+
start, ending = /^\s*/, /\s+(.+?)(?= unless| if| do|\{|#|$)/
|
6
|
+
source.gsub!(/#{start}\+#{ending}/, 'table.column(\1)')
|
7
|
+
source.gsub!(/#{start}\=>#{ending}/, 'table.table_for(\1)')
|
8
|
+
source.gsub!(/#{start}\=#{ending}/, 'table.generate_subtable_for(\1)')
|
9
|
+
source.gsub!(/#{start}\*#{ending}/, 'table.config(\1)')
|
4
10
|
%{
|
5
11
|
format = Tableview::Helper::Format.new(params)
|
6
|
-
tv = Tableview::ViewHandler.
|
7
|
-
#{
|
12
|
+
tv = Tableview::ViewHandler.dsl do |table|
|
13
|
+
#{source}
|
8
14
|
end
|
9
15
|
output = Tableview::output_class(params[:format]).new
|
10
16
|
output.process(tv)
|
data/lib/tableview/version.rb
CHANGED
@@ -6,7 +6,8 @@ module Tableview
|
|
6
6
|
|
7
7
|
attr_reader :table
|
8
8
|
|
9
|
-
def self.
|
9
|
+
def self.dsl(opts = {}, &block)
|
10
|
+
puts "self.dsl called"
|
10
11
|
ret = Table.new opts
|
11
12
|
#ret.instance_eval &block
|
12
13
|
yield(ret)
|
@@ -22,13 +23,13 @@ module Tableview
|
|
22
23
|
end
|
23
24
|
|
24
25
|
class Table < TablePiece
|
25
|
-
attr_accessor :parts
|
26
|
+
attr_accessor :parts, :subtables, :title
|
26
27
|
def initialize(*args)
|
27
28
|
super *args
|
28
29
|
self.parts = []
|
29
30
|
@current_part = Body.new
|
30
31
|
@added = false
|
31
|
-
@headers, @procs = [], []
|
32
|
+
@headers, @procs, @subtables = [], [], []
|
32
33
|
end
|
33
34
|
|
34
35
|
def table_for(s)
|
@@ -104,8 +105,28 @@ module Tableview
|
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
108
|
+
def generate_subtable_for(subcollection, title = nil)
|
109
|
+
t = Table.new
|
110
|
+
t.title = title
|
111
|
+
t.header_row do |row|
|
112
|
+
row.cells = @headers
|
113
|
+
end
|
114
|
+
t.body do |b|
|
115
|
+
subcollection.each do |el|
|
116
|
+
b.row do |r|
|
117
|
+
@procs.each do |proc|
|
118
|
+
r.cell proc.call(el)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end # body
|
123
|
+
@subtables << t
|
124
|
+
@table_generated = true
|
125
|
+
end
|
126
|
+
|
107
127
|
def create_table!
|
108
128
|
return unless @column_based
|
129
|
+
return if @table_generated
|
109
130
|
header_row do |row|
|
110
131
|
row.cells = @headers
|
111
132
|
end
|
@@ -116,6 +137,7 @@ module Tableview
|
|
116
137
|
end
|
117
138
|
end
|
118
139
|
end
|
140
|
+
@subtables << self
|
119
141
|
end
|
120
142
|
|
121
143
|
end
|
@@ -135,15 +157,12 @@ module Tableview
|
|
135
157
|
end
|
136
158
|
|
137
159
|
class Header < Part
|
138
|
-
|
139
160
|
end
|
140
161
|
|
141
162
|
class Body < Part
|
142
|
-
|
143
163
|
end
|
144
164
|
|
145
165
|
class Footer < Part
|
146
|
-
|
147
166
|
end
|
148
167
|
|
149
168
|
class Row < TablePiece
|
data/lib/tableview.rb
CHANGED
data/tableview.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |s|
|
|
18
18
|
|
19
19
|
s.add_dependency "terminal-table", "~> 1.4"
|
20
20
|
s.add_dependency "spreadsheet", "~> 0.6"
|
21
|
+
s.add_dependency "railties", "~> 3.0"
|
22
|
+
#s.add_dependency "thor", "~> 0.14"
|
21
23
|
#s.add_dependency "rails", "~> 3.0"
|
22
24
|
|
23
25
|
s.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jakub Hampl
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-06-01 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -60,6 +60,20 @@ dependencies:
|
|
60
60
|
version: "0.6"
|
61
61
|
type: :runtime
|
62
62
|
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: railties
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ~>
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 3
|
73
|
+
- 0
|
74
|
+
version: "3.0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
63
77
|
description: Supported formats are ASCII, MS Excel, HTML and CSV; it is easy to create your own exporter class.
|
64
78
|
email:
|
65
79
|
- honitom@seznam.cz
|
@@ -75,6 +89,8 @@ files:
|
|
75
89
|
- Gemfile
|
76
90
|
- README.md
|
77
91
|
- Rakefile
|
92
|
+
- lib/generators/tableview/install/install_generator.rb
|
93
|
+
- lib/generators/tableview/tableview_generator.rb
|
78
94
|
- lib/tableview.rb
|
79
95
|
- lib/tableview/helper.rb
|
80
96
|
- lib/tableview/output/ascii.rb
|