ruport 1.0.2 → 1.2.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/AUTHORS +3 -0
- data/README +11 -5
- data/Rakefile +2 -2
- data/examples/btree/commaleon/commaleon.rb +1 -1
- data/examples/simple_templating_example.rb +34 -0
- data/examples/tattle_rubygems_version.rb +6 -5
- data/examples/trac_ticket_status.rb +2 -2
- data/lib/ruport.rb +5 -4
- data/lib/ruport/acts_as_reportable.rb +63 -37
- data/lib/ruport/data.rb +1 -0
- data/lib/ruport/data/feeder.rb +111 -0
- data/lib/ruport/data/grouping.rb +84 -22
- data/lib/ruport/data/record.rb +1 -1
- data/lib/ruport/data/table.rb +127 -87
- data/lib/ruport/formatter.rb +22 -9
- data/lib/ruport/formatter/csv.rb +27 -3
- data/lib/ruport/formatter/html.rb +26 -6
- data/lib/ruport/formatter/pdf.rb +169 -36
- data/lib/ruport/formatter/template.rb +167 -0
- data/lib/ruport/formatter/text.rb +47 -15
- data/lib/ruport/query.rb +1 -1
- data/lib/ruport/renderer.rb +46 -56
- data/test/acts_as_reportable_test.rb +20 -20
- data/test/csv_formatter_test.rb +26 -1
- data/test/data_feeder_test.rb +88 -0
- data/test/grouping_test.rb +90 -4
- data/test/html_formatter_test.rb +25 -2
- data/test/pdf_formatter_test.rb +69 -3
- data/test/query_test.rb +3 -2
- data/test/record_test.rb +2 -1
- data/test/renderer_test.rb +49 -3
- data/test/sql_split_test.rb +4 -2
- data/test/table_test.rb +159 -65
- data/test/template_test.rb +37 -0
- data/test/text_formatter_test.rb +33 -1
- metadata +9 -4
- data/lib/ruport/renderer.rb.orig +0 -542
- data/test/renderer_test.rb.orig +0 -512
data/lib/ruport/data/grouping.rb
CHANGED
@@ -51,16 +51,7 @@ module Ruport::Data
|
|
51
51
|
base.renders_as_group
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
|
-
#
|
56
|
-
# Example:
|
57
|
-
#
|
58
|
-
# one = Group.new :name => 'test',
|
59
|
-
# :data => [[1,2], [3,4]],
|
60
|
-
# :column_names => %w[a b]
|
61
|
-
# two = one.dup
|
62
|
-
#
|
63
|
-
def initialize_copy(from)
|
54
|
+
def initialize_copy(from) #:nodoc:
|
64
55
|
super
|
65
56
|
@name = from.name
|
66
57
|
@subgroups = from.subgroups.inject({}) { |h,d|
|
@@ -149,20 +140,34 @@ module Ruport::Data
|
|
149
140
|
#
|
150
141
|
# Valid options:
|
151
142
|
# <b><tt>:by</tt></b>:: A column name or array of column names that the
|
152
|
-
# data will be grouped on.
|
143
|
+
# data will be grouped on.
|
144
|
+
# <b><tt>:order</tt></b>:: Determines the iteration and presentation order
|
145
|
+
# of a Grouping object. Set to :name to order by
|
146
|
+
# Group names. You can also provide a lambda which
|
147
|
+
# will be passed Group objects, and use semantics
|
148
|
+
# similar to Enumerable#group_by
|
153
149
|
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
# table = [[1,2,3],[4,5,6]].to_table(%w[a b c])
|
150
|
+
# Examples:
|
157
151
|
#
|
152
|
+
# table = [[1,2,3],[4,5,6],[1,1,2]].to_table(%w[a b c])
|
153
|
+
#
|
154
|
+
# # unordered
|
158
155
|
# grouping = Grouping.new(table, :by => "a")
|
156
|
+
#
|
157
|
+
# # ordered by group name
|
158
|
+
# grouping = Grouping.new(table, :by => "a", :order => :name)
|
159
159
|
#
|
160
|
+
# # ordered by group size
|
161
|
+
# grouping = Grouping.new(table, :by => "a",
|
162
|
+
# :order => lambda { |g| g.size } )
|
160
163
|
def initialize(data={},options={})
|
161
164
|
if data.kind_of?(Hash)
|
162
|
-
@grouped_by = data[:by]
|
165
|
+
@grouped_by = data[:by]
|
166
|
+
@order = data[:order]
|
163
167
|
@data = {}
|
164
168
|
else
|
165
|
-
@grouped_by = options[:by]
|
169
|
+
@grouped_by = options[:by]
|
170
|
+
@order = options[:order]
|
166
171
|
cols = Array(options[:by]).dup
|
167
172
|
@data = data.to_group.send(:grouped_data, cols.shift)
|
168
173
|
cols.each do |col|
|
@@ -192,9 +197,35 @@ module Ruport::Data
|
|
192
197
|
|
193
198
|
# Iterates through the Grouping, yielding each group name and Group object
|
194
199
|
#
|
195
|
-
def each
|
196
|
-
@
|
197
|
-
|
200
|
+
def each
|
201
|
+
if @order.respond_to?(:call)
|
202
|
+
@data.sort_by { |n,g| @order[g] }.each { |n,g| yield(n,g) }
|
203
|
+
elsif @order == :name
|
204
|
+
@data.sort_by { |n,g| n }.each { |name,group| yield(name,group) }
|
205
|
+
else
|
206
|
+
@data.each { |name,group| yield(name,group) }
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
|
211
|
+
# Returns a new grouping with the specified sort order.
|
212
|
+
# You can sort by Group name or an arbitrary block
|
213
|
+
#
|
214
|
+
# by_name = grouping.sort_grouping_by(:name)
|
215
|
+
# by_size = grouping.sort_grouping_by { |g| g.size }
|
216
|
+
def sort_grouping_by(type=nil,&block)
|
217
|
+
a = Grouping.new(:by => @grouped_by, :order => type || block)
|
218
|
+
each { |n,g| a << g }
|
219
|
+
return a
|
220
|
+
end
|
221
|
+
|
222
|
+
# Applies the specified sort order to an existing Grouping object.
|
223
|
+
#
|
224
|
+
# grouping.sort_grouping_by!(:name)
|
225
|
+
# grouping.sort_grouping_by! { |g| g.size }
|
226
|
+
def sort_grouping_by!(type=nil,&block)
|
227
|
+
@order = type || block
|
228
|
+
end
|
198
229
|
|
199
230
|
# Used to add extra data to the Grouping. <tt>group</tt> should be a Group.
|
200
231
|
#
|
@@ -217,7 +248,7 @@ module Ruport::Data
|
|
217
248
|
@data.merge!({ group.name => group })
|
218
249
|
end
|
219
250
|
|
220
|
-
alias_method :append, :<<
|
251
|
+
alias_method :append, :<<
|
221
252
|
|
222
253
|
# Provides access to the subgroups of a particular group in the Grouping.
|
223
254
|
# Supply the name of a group and it returns a Grouping created from the
|
@@ -259,7 +290,7 @@ module Ruport::Data
|
|
259
290
|
s.merge(r[0] => r[1].call(group))
|
260
291
|
end
|
261
292
|
end
|
262
|
-
t.reorder(cols)
|
293
|
+
t.data.reorder(cols)
|
263
294
|
}
|
264
295
|
end
|
265
296
|
|
@@ -277,6 +308,37 @@ module Ruport::Data
|
|
277
308
|
as(:text)
|
278
309
|
end
|
279
310
|
|
311
|
+
# Calculates sums. If a column name or index is given, it will try to
|
312
|
+
# convert each element of that column to an integer or float
|
313
|
+
# and add them together. The sum is calculated across all groups in
|
314
|
+
# the grouping.
|
315
|
+
#
|
316
|
+
# If a block is given, it yields each Record in each Group so that you can
|
317
|
+
# do your own calculation.
|
318
|
+
#
|
319
|
+
# Example:
|
320
|
+
#
|
321
|
+
# table = [[1,2,3],[3,4,5],[5,6,7]].to_table(%w[col1 col2 col3])
|
322
|
+
# grouping = Grouping(table, :by => "col1")
|
323
|
+
# grouping.sigma("col2") #=> 12
|
324
|
+
# grouping.sigma(0) #=> 12
|
325
|
+
# grouping.sigma { |r| r.col2 + r.col3 } #=> 27
|
326
|
+
# grouping.sigma { |r| r.col2 + 1 } #=> 15
|
327
|
+
#
|
328
|
+
def sigma(column=nil)
|
329
|
+
inject(0) do |s, (group_name, group)|
|
330
|
+
if column
|
331
|
+
s + group.sigma(column)
|
332
|
+
else
|
333
|
+
s + group.sigma do |r|
|
334
|
+
yield(r)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
alias_method :sum, :sigma
|
341
|
+
|
280
342
|
include Ruport::Renderer::Hooks
|
281
343
|
renders_as_grouping
|
282
344
|
|
@@ -293,7 +355,7 @@ module Ruport::Data
|
|
293
355
|
#
|
294
356
|
# two = one.dup
|
295
357
|
#
|
296
|
-
def initialize_copy(from)
|
358
|
+
def initialize_copy(from) #:nodoc:
|
297
359
|
@grouped_by = from.grouped_by
|
298
360
|
@data = from.data.inject({}) { |h,d| h.merge!({ d[0] => d[1].dup }) }
|
299
361
|
end
|
data/lib/ruport/data/record.rb
CHANGED
data/lib/ruport/data/table.rb
CHANGED
@@ -22,7 +22,7 @@ module Ruport::Data
|
|
22
22
|
# Once your data is in a Table object, it can be manipulated
|
23
23
|
# to suit your needs, then used to build a report.
|
24
24
|
#
|
25
|
-
class Table
|
25
|
+
class Table
|
26
26
|
|
27
27
|
# === Overview
|
28
28
|
#
|
@@ -51,7 +51,7 @@ module Ruport::Data
|
|
51
51
|
#
|
52
52
|
# table = Table.parse("a,b,c\n1,2,3\n4,5,6\n")
|
53
53
|
#
|
54
|
-
def parse(string, options={},&block)
|
54
|
+
def parse(string, options={},&block)
|
55
55
|
get_table_from_csv(:parse,string,options,&block)
|
56
56
|
end
|
57
57
|
|
@@ -66,35 +66,33 @@ module Ruport::Data
|
|
66
66
|
# if people want to use FCSV's header support, let them
|
67
67
|
adjust_options_for_fcsv_headers(options)
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
loaded_data << row
|
69
|
+
table = self.new(options) do |feeder|
|
70
|
+
first_line = true
|
71
|
+
FasterCSV.send(msg,param,options[:csv_options]) do |row|
|
72
|
+
if first_line
|
73
|
+
adjust_for_headers(feeder.data,row,options)
|
74
|
+
first_line = false
|
75
|
+
next if options[:has_names]
|
76
|
+
end
|
77
|
+
|
78
|
+
if block
|
79
|
+
handle_csv_row_proc(feeder,row,options,block)
|
80
|
+
else
|
81
|
+
feeder << row
|
82
|
+
end
|
84
83
|
end
|
85
|
-
|
86
84
|
end
|
87
|
-
|
88
|
-
return
|
85
|
+
|
86
|
+
return table
|
89
87
|
end
|
90
88
|
|
91
|
-
def handle_csv_row_proc(
|
89
|
+
def handle_csv_row_proc(feeder,row,options,block)
|
92
90
|
if options[:records]
|
93
91
|
rc = options[:record_class] || Record
|
94
|
-
row = rc.new(row, :attributes => data.column_names)
|
92
|
+
row = rc.new(row, :attributes => feeder.data.column_names)
|
95
93
|
end
|
96
94
|
|
97
|
-
block[
|
95
|
+
block[feeder,row]
|
98
96
|
end
|
99
97
|
|
100
98
|
def adjust_options_for_fcsv_headers(options)
|
@@ -127,6 +125,15 @@ module Ruport::Data
|
|
127
125
|
# records in this Table.
|
128
126
|
# <b><tt>:column_names</tt></b>:: An Array containing the column names
|
129
127
|
# for this Table.
|
128
|
+
# <b><tt>:filters</tt></b>:: A proc or array of procs that set up
|
129
|
+
# conditions to filter the data being
|
130
|
+
# added to the table.
|
131
|
+
# <b><tt>:transforms</tt></b>:: A proc or array of procs that perform
|
132
|
+
# transformations on the data being added
|
133
|
+
# to the table.
|
134
|
+
# <b><tt>:record_class</tt></b>:: Specify the class of the table's
|
135
|
+
# records.
|
136
|
+
#
|
130
137
|
# Example:
|
131
138
|
#
|
132
139
|
# table = Table.new :data => [[1,2,3], [3,4,5]],
|
@@ -136,20 +143,30 @@ module Ruport::Data
|
|
136
143
|
@column_names = options[:column_names] ? options[:column_names].dup : []
|
137
144
|
@record_class = options[:record_class] &&
|
138
145
|
options[:record_class].name || "Ruport::Data::Record"
|
139
|
-
@data = []
|
146
|
+
@data = []
|
147
|
+
|
148
|
+
feeder = Feeder.new(self)
|
149
|
+
|
150
|
+
Array(options[:filters]).each { |f| feeder.filter(&f) }
|
151
|
+
Array(options[:transforms]).each { |t| feeder.transform(&t) }
|
152
|
+
|
140
153
|
if options[:data]
|
141
|
-
|
142
|
-
|
143
|
-
if @column_names.empty? or
|
144
|
-
|
145
|
-
|
154
|
+
options[:data].each do |e|
|
155
|
+
if e.kind_of?(Record)
|
156
|
+
e = if @column_names.empty? or
|
157
|
+
e.attributes.all? { |a| a.kind_of?(Numeric) }
|
158
|
+
e.to_a
|
146
159
|
else
|
147
|
-
|
160
|
+
e.to_hash.values_at(*@column_names)
|
148
161
|
end
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
162
|
+
end
|
163
|
+
r = recordize(e)
|
164
|
+
|
165
|
+
feeder << r
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
yield(feeder) if block_given?
|
153
170
|
end
|
154
171
|
|
155
172
|
# This Table's column names
|
@@ -221,17 +238,8 @@ module Ruport::Data
|
|
221
238
|
# data << Record.new [5,6], :attributes => %w[a b]
|
222
239
|
#
|
223
240
|
def <<(row)
|
224
|
-
|
225
|
-
|
226
|
-
append_array(row)
|
227
|
-
when Hash
|
228
|
-
append_hash(row)
|
229
|
-
when record_class
|
230
|
-
append_record(row)
|
231
|
-
else
|
232
|
-
append_hash(row) rescue append_array(row)
|
233
|
-
end
|
234
|
-
return self
|
241
|
+
@data << recordize(row)
|
242
|
+
return self
|
235
243
|
end
|
236
244
|
|
237
245
|
# Returns the record class constant being used by the table.
|
@@ -323,7 +331,7 @@ module Ruport::Data
|
|
323
331
|
# # new column built via a block, added at the end of the table
|
324
332
|
# data.add_column("new_col4") { |r| r.a + r.b }
|
325
333
|
#
|
326
|
-
def add_column(name,options={})
|
334
|
+
def add_column(name,options={})
|
327
335
|
if pos = options[:position]
|
328
336
|
column_names.insert(pos,name)
|
329
337
|
elsif pos = options[:after]
|
@@ -352,7 +360,7 @@ module Ruport::Data
|
|
352
360
|
#
|
353
361
|
def add_columns(names,options={})
|
354
362
|
raise "Greg isn't smart enough to figure this out.\n"+
|
355
|
-
"Send ideas in at http://list.rubyreports.org" if block_given?
|
363
|
+
"Send ideas in at http://list.rubyreports.org" if block_given?
|
356
364
|
need_reverse = !!(options[:after] || options[:position])
|
357
365
|
names = names.reverse if need_reverse
|
358
366
|
names.each { |n| add_column(n,options) }
|
@@ -366,8 +374,8 @@ module Ruport::Data
|
|
366
374
|
# table.remove_column(0) #=> removes the first column
|
367
375
|
# table.remove_column("apple") #=> removes column named apple
|
368
376
|
#
|
369
|
-
def remove_column(col)
|
370
|
-
col = column_names[col] if col.kind_of? Fixnum
|
377
|
+
def remove_column(col)
|
378
|
+
col = column_names[col] if col.kind_of? Fixnum
|
371
379
|
column_names.delete(col)
|
372
380
|
each { |r| r.send(:delete,col) }
|
373
381
|
end
|
@@ -522,12 +530,12 @@ module Ruport::Data
|
|
522
530
|
# sub_table = table.sub_table { |r| r.c > 10 }
|
523
531
|
# sub_table == [[9,10,11,12]].to_table(%w[a b c d]) #=> true
|
524
532
|
#
|
525
|
-
def sub_table(cor=column_names,range=nil,&block)
|
526
|
-
if range
|
533
|
+
def sub_table(cor=column_names,range=nil,&block)
|
534
|
+
if range
|
527
535
|
self.class.new(:column_names => cor,:data => data[range])
|
528
|
-
elsif cor.kind_of?(Range)
|
529
|
-
self.class.new(:column_names => column_names,:data => data[cor])
|
530
|
-
elsif block
|
536
|
+
elsif cor.kind_of?(Range)
|
537
|
+
self.class.new(:column_names => column_names,:data => data[cor])
|
538
|
+
elsif block
|
531
539
|
self.class.new( :column_names => cor, :data => data.select(&block))
|
532
540
|
else
|
533
541
|
self.class.new( :column_names => cor, :data => data)
|
@@ -590,7 +598,7 @@ module Ruport::Data
|
|
590
598
|
r.get(column) =~ /\./ ? r.get(column).to_f : r.get(column).to_i
|
591
599
|
end
|
592
600
|
else
|
593
|
-
s + yield(r)
|
601
|
+
s + yield(r)
|
594
602
|
end
|
595
603
|
}
|
596
604
|
end
|
@@ -598,9 +606,11 @@ module Ruport::Data
|
|
598
606
|
alias_method :sum, :sigma
|
599
607
|
|
600
608
|
# Returns a sorted table. If col_names is specified,
|
601
|
-
# the block is ignored and the table is sorted by the named columns.
|
602
|
-
#
|
603
|
-
#
|
609
|
+
# the block is ignored and the table is sorted by the named columns.
|
610
|
+
#
|
611
|
+
# The second argument specifies sorting options. Currently only
|
612
|
+
# :order is supported. Default order is ascending, to sort decending
|
613
|
+
# use :order => :descending
|
604
614
|
#
|
605
615
|
# Example:
|
606
616
|
#
|
@@ -609,26 +619,42 @@ module Ruport::Data
|
|
609
619
|
# # returns a new table sorted by col1
|
610
620
|
# table.sort_rows_by {|r| r["col1"]}
|
611
621
|
#
|
622
|
+
# # returns a new table sorted by col1, in descending order
|
623
|
+
# table.sort_rows_by(nil, :order => :descending) {|r| r["col1"]}
|
624
|
+
#
|
612
625
|
# # returns a new table sorted by col2
|
613
|
-
# table.sort_rows_by
|
626
|
+
# table.sort_rows_by(["col2"])
|
627
|
+
#
|
628
|
+
# # returns a new table sorted by col2, descending order
|
629
|
+
# table.sort_rows_by("col2", :order => :descending)
|
614
630
|
#
|
615
631
|
# # returns a new table sorted by col1, then col2
|
616
|
-
# table.sort_rows_by
|
632
|
+
# table.sort_rows_by(["col1", "col2"])
|
633
|
+
#
|
634
|
+
# # returns a new table sorted by col1, then col2, in descending order
|
635
|
+
# table.sort_rows_by(["col1", "col2"], :order => descending)
|
617
636
|
#
|
618
|
-
def sort_rows_by(col_names=nil, &block)
|
637
|
+
def sort_rows_by(col_names=nil, options={}, &block)
|
619
638
|
# stabilizer is needed because of
|
620
639
|
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/170565
|
621
640
|
stabilizer = 0
|
641
|
+
|
642
|
+
nil_rows, sortable = partition do |r|
|
643
|
+
Array(col_names).any? { |c| r[c].nil? }
|
644
|
+
end
|
622
645
|
|
623
646
|
data_array =
|
624
647
|
if col_names
|
625
|
-
sort_by do |r|
|
648
|
+
sortable.sort_by do |r|
|
626
649
|
stabilizer += 1
|
627
650
|
[Array(col_names).map {|col| r[col]}, stabilizer]
|
628
651
|
end
|
629
652
|
else
|
630
|
-
sort_by(&block)
|
631
|
-
end
|
653
|
+
sortable.sort_by(&block)
|
654
|
+
end
|
655
|
+
|
656
|
+
data_array += nil_rows
|
657
|
+
data_array.reverse! if options[:order] == :descending
|
632
658
|
|
633
659
|
table = self.class.new( :data => data_array,
|
634
660
|
:column_names => @column_names,
|
@@ -640,8 +666,8 @@ module Ruport::Data
|
|
640
666
|
# Same as Table#sort_rows_by, but self modifying.
|
641
667
|
# See <tt>sort_rows_by</tt> for documentation.
|
642
668
|
#
|
643
|
-
def sort_rows_by!(col_names=nil,&block)
|
644
|
-
table = sort_rows_by(col_names,&block)
|
669
|
+
def sort_rows_by!(col_names=nil,options={},&block)
|
670
|
+
table = sort_rows_by(col_names,options,&block)
|
645
671
|
@data = table.data
|
646
672
|
end
|
647
673
|
|
@@ -665,7 +691,7 @@ module Ruport::Data
|
|
665
691
|
end
|
666
692
|
}
|
667
693
|
end
|
668
|
-
|
694
|
+
|
669
695
|
# Create a copy of the Table. Records will be copied as well.
|
670
696
|
#
|
671
697
|
# Example:
|
@@ -721,24 +747,39 @@ module Ruport::Data
|
|
721
747
|
super
|
722
748
|
end
|
723
749
|
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
750
|
+
def feed_element(row)
|
751
|
+
recordize(row)
|
752
|
+
end
|
753
|
+
|
754
|
+
private
|
729
755
|
|
730
|
-
|
731
|
-
|
756
|
+
def recordize(row)
|
757
|
+
case row
|
758
|
+
when Array
|
759
|
+
normalize_array(row)
|
760
|
+
when Hash
|
761
|
+
normalize_hash(row)
|
762
|
+
when record_class
|
763
|
+
recordize(normalize_record(row))
|
764
|
+
else
|
765
|
+
normalize_hash(row) rescue normalize_array(row)
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
def normalize_hash(hash_obj)
|
732
770
|
hash_obj = hash_obj.to_hash
|
733
771
|
raise ArgumentError unless @column_names
|
734
|
-
|
735
|
-
end
|
772
|
+
record_class.new(hash_obj, :attributes => @column_names)
|
773
|
+
end
|
736
774
|
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
775
|
+
def normalize_record(record)
|
776
|
+
record.send(column_names.empty? ? :to_a : :to_hash)
|
777
|
+
end
|
778
|
+
|
779
|
+
def normalize_array(array)
|
780
|
+
attributes = @column_names.empty? ? nil : @column_names
|
781
|
+
record_class.new(array.to_ary, :attributes => attributes)
|
782
|
+
end
|
742
783
|
end
|
743
784
|
end
|
744
785
|
|
@@ -765,7 +806,7 @@ module Kernel
|
|
765
806
|
case(args[0])
|
766
807
|
when Array
|
767
808
|
opts = args[1] || {}
|
768
|
-
Ruport::Data::Table.new(f={:column_names => args[0]}.merge(opts))
|
809
|
+
Ruport::Data::Table.new(f={:column_names => args[0]}.merge(opts),&block)
|
769
810
|
when /\.csv/
|
770
811
|
return Ruport::Data::Table.load(*args,&block)
|
771
812
|
when Hash
|
@@ -774,13 +815,12 @@ module Kernel
|
|
774
815
|
elsif string = args[0].delete(:string)
|
775
816
|
return Ruport::Data::Table.parse(string,args[0],&block)
|
776
817
|
else
|
777
|
-
return Ruport::Data::Table.new(args[0])
|
818
|
+
return Ruport::Data::Table.new(args[0],&block)
|
778
819
|
end
|
779
820
|
else
|
780
|
-
Ruport::Data::Table.new(:data => [], :column_names => args)
|
821
|
+
Ruport::Data::Table.new(:data => [], :column_names => args,&block)
|
781
822
|
end
|
782
823
|
|
783
|
-
block[table] if block
|
784
824
|
return table
|
785
825
|
end
|
786
826
|
end
|
@@ -793,8 +833,8 @@ class Array
|
|
793
833
|
# Example:
|
794
834
|
# [[1,2],[3,4]].to_table(%w[a b])
|
795
835
|
#
|
796
|
-
def to_table(column_names=nil)
|
797
|
-
Ruport::Data::Table.new({:data => self, :column_names => column_names})
|
836
|
+
def to_table(column_names=nil,&b)
|
837
|
+
Ruport::Data::Table.new({:data => self, :column_names => column_names},&b)
|
798
838
|
end
|
799
839
|
|
800
840
|
end
|