ruport 1.7.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +38 -0
- data/HACKING +1 -17
- data/{README.rdoc → README.md} +30 -38
- data/Rakefile +0 -10
- data/examples/row_renderer.rb +1 -1
- data/examples/simple_pdf_lines.rb +1 -1
- data/examples/trac_ticket_status.rb +1 -1
- data/lib/ruport/controller.rb +1 -1
- data/lib/ruport/data/grouping.rb +7 -7
- data/lib/ruport/data/record.rb +4 -4
- data/lib/ruport/data/table.rb +9 -9
- data/lib/ruport/formatter/csv.rb +1 -1
- data/lib/ruport/formatter/markdown.rb +105 -0
- data/lib/ruport/formatter/prawn_pdf.rb +96 -9
- data/lib/ruport/formatter/text.rb +1 -1
- data/lib/ruport/formatter.rb +1 -2
- data/lib/ruport/version.rb +1 -1
- data/lib/ruport.rb +7 -11
- data/test/controller_test.rb +107 -109
- data/test/csv_formatter_test.rb +21 -21
- data/test/data_feeder_test.rb +39 -39
- data/test/expected_outputs/prawn_pdf_formatter/pdf_basic.pdf.test +265 -0
- data/test/grouping_test.rb +74 -74
- data/test/helpers.rb +16 -5
- data/test/html_formatter_test.rb +22 -22
- data/test/markdown_formatter_test.rb +142 -0
- data/test/prawn_pdf_formatter_test.rb +108 -0
- data/test/record_test.rb +82 -82
- data/test/table_pivot_test.rb +9 -2
- data/test/table_test.rb +33 -40
- data/test/template_test.rb +12 -12
- data/test/text_formatter_test.rb +34 -34
- data/util/bench/data/table/bench_column_manip.rb +0 -1
- data/util/bench/data/table/bench_dup.rb +0 -1
- data/util/bench/data/table/bench_init.rb +0 -1
- data/util/bench/data/table/bench_manip.rb +0 -1
- data/util/bench/formatter/bench_csv.rb +0 -1
- data/util/bench/formatter/bench_html.rb +0 -1
- data/util/bench/formatter/bench_pdf.rb +0 -1
- data/util/bench/formatter/bench_text.rb +0 -1
- metadata +30 -29
- data/lib/ruport/formatter/pdf.rb +0 -589
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b8b980ae054fa6d3d42e224431277d3deb471aa2e7132ea144bdb63bff3b3642
|
4
|
+
data.tar.gz: 9b5784e616ce0cbce9e218995cb7c3b36eb625cc18a75eea8642092713a391c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ecded8ff524e85d5c9a5bb6312b7bb50cdd5fa0f74540059c4c41c50d9b4cd3c679d6c176dc0a19564eca53590b77374ef00fe2a9afd9a742f0e35b0b88c79c
|
7
|
+
data.tar.gz: 5045f9a47bee0f414ff26222784ce782f2d01329f7f8448196ba6c91974e160fdfcb1d9fdc95318db4246fc67f0f16804e1a965b2856758bc66431b5c17502c9
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased] - undecided
|
8
|
+
|
9
|
+
## [1.8.0] - 2022-09-20
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Markdown formatter [#54](https://github.com/ruport/ruport/pull/54)
|
14
|
+
- Ruby 3.0 support
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
- Reduced allocations to improve performance [#34](https://github.com/ruport/ruport/pull/34)
|
19
|
+
- Update Prawn version to 2.4.0 [#44](https://github.com/ruport/ruport/pull/44) [#57](https://github.com/ruport/ruport/pull/57) [#64](https://github.com/ruport/ruport/pull/64)
|
20
|
+
|
21
|
+
## [1.7.1] - 2017-05-02
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
- Improved errors when missing gems.
|
26
|
+
- Added ruby 1.9 support
|
27
|
+
- Removed dependency on `fastercsv` gem
|
28
|
+
|
29
|
+
## [1.7.0] - 2011-01-06
|
30
|
+
|
31
|
+
## [1.6.3] - 2009-12-12
|
32
|
+
|
33
|
+
|
34
|
+
[Unreleased]: https://github.com/ruport/ruport/compare/v1.8.0...HEAD
|
35
|
+
[1.8.0]: https://github.com/ruport/ruport/compare/v1.7.1...v1.8.0
|
36
|
+
[1.7.1]: https://github.com/ruport/ruport/compare/v1.7.0...v1.7.1
|
37
|
+
[1.7.0]: https://github.com/ruport/ruport/compare/v1.6.3...v1.7.0
|
38
|
+
[1.6.3]: https://github.com/ruport/ruport/compare/v1.6.2...v1.6.3
|
data/HACKING
CHANGED
@@ -23,23 +23,7 @@ contributions to our project. Here are a few different ways you can help.
|
|
23
23
|
If any of these things sound appealing to you, there are a few things
|
24
24
|
you should do:
|
25
25
|
|
26
|
-
1)
|
27
|
-
|
28
|
-
2) Post and introduce yourself, letting us know what you'd like to work on OR
|
29
|
-
Find sandal or mikem836 on #ruport
|
30
|
-
|
31
|
-
3) Please read the MakingChangeRequests, ReportingDefects, and
|
32
|
-
SubmittingPatches Trac wiki pages, as appropriate.
|
33
|
-
|
34
|
-
- http://stonecode.svnrepository.com/ruport/trac.cgi/wiki/MakingChangeRequests
|
35
|
-
|
36
|
-
- http://stonecode.svnrepository.com/ruport/trac.cgi/wiki/ReportingDefects
|
37
|
-
|
38
|
-
- http://stonecode.svnrepository.com/ruport/trac.cgi/wiki/SubmittingPatches
|
39
|
-
|
40
|
-
4) Please pull the latest code from SVN trunk:
|
41
|
-
http://stonecode.svnrepository.com/svn/ruport/ruport/trunk
|
42
|
-
|
26
|
+
1) Head over to https://github.com/ruport/ruport
|
43
27
|
|
44
28
|
This should hopefully be enough to get you on the right track. We welcome your
|
45
29
|
questions and ideas, so don't be afraid to contact us.
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
[![Build Status][BS img]](https://travis-ci.org/ruport/ruport)
|
2
|
+
[![Coverage Status][CS img]](https://coveralls.io/r/ruport/ruport)
|
3
|
+
|
4
|
+
## What Ruport Is
|
2
5
|
|
3
6
|
Ruby Reports (Ruport) is an extensible reporting system.
|
4
7
|
|
@@ -20,9 +23,9 @@ of helper functions that will let you build complex reports while maintaining
|
|
20
23
|
a DRY and consistent interface.
|
21
24
|
|
22
25
|
To get a quick feel for what you can accomplish with Ruport, take a look at
|
23
|
-
a few simple examples provided on our web site
|
26
|
+
a few simple examples provided on our web site:
|
24
27
|
|
25
|
-
|
28
|
+
https://ruport.github.io/examples.html
|
26
29
|
|
27
30
|
Since Ruport's core support is intentionally minimalistic, you may be looking
|
28
31
|
for some higher level support for specific needs such as graphing, invoices,
|
@@ -30,71 +33,57 @@ report mailing support, etc. For this, you may wish to take a look at the
|
|
30
33
|
ruport-util package, which contains some generally useful tools and libraries
|
31
34
|
to extend Ruport's capabilities.
|
32
35
|
|
33
|
-
|
36
|
+
## Installation
|
34
37
|
|
35
38
|
To install ruport via rubygems:
|
36
39
|
|
37
|
-
|
40
|
+
```sh
|
41
|
+
$ sudo gem install ruport
|
42
|
+
```
|
38
43
|
|
39
44
|
Check to see if it installed properly:
|
40
45
|
|
41
|
-
|
46
|
+
```sh
|
47
|
+
$ ruby -e "require 'ruport'; puts Ruport::VERSION"
|
48
|
+
```
|
42
49
|
|
43
50
|
If you get an error, please let us know on our mailing list.
|
44
51
|
|
45
|
-
|
52
|
+
### Dependencies
|
46
53
|
|
47
|
-
|
54
|
+
#### Formatting
|
48
55
|
|
49
56
|
Ruport relies on PDF::Writer for its formatting support.
|
50
57
|
If you want to make use of textile helpers, you'll also need RedCloth.
|
51
58
|
|
52
|
-
|
59
|
+
#### Database interaction
|
53
60
|
|
54
|
-
If you wish to use Ruport to report against a
|
55
|
-
|
56
|
-
ActiveRecord and the acts_as_reportable gem.
|
61
|
+
If you wish to use Ruport to report against a Rails project, you'll need
|
62
|
+
ActiveRecord and the `acts_as_reportable` gem.
|
57
63
|
|
58
64
|
If you want to use Ruport::Query for raw SQL support, you'll need to
|
59
|
-
install ruport-util
|
65
|
+
install `ruport-util`, `RubyDBI` and whatever database drivers you might
|
66
|
+
need.
|
60
67
|
|
61
|
-
|
68
|
+
## Resources
|
62
69
|
|
63
70
|
Our developers have published a free-content book about all things
|
64
71
|
Ruport, including complete coverage of acts_as_reportable and some of
|
65
72
|
ruport-util's features. This book serves as the definitive guide to
|
66
73
|
Ruport, so all users should become acquainted with it:
|
67
74
|
|
68
|
-
|
69
|
-
|
70
|
-
The next best way to get help and make suggestions is the Ruport mailing list.
|
71
|
-
This software is on the move, so the list is the most reliable way of getting
|
72
|
-
up to date information.
|
73
|
-
|
74
|
-
- You can sign up and/or view the archives here:
|
75
|
-
http://groups.google.com/group/ruby-reports
|
75
|
+
https://ruport.github.io
|
76
76
|
|
77
77
|
If you are looking to dig a little deeper, there are a couple more resources
|
78
78
|
that may be helpful to you.
|
79
79
|
|
80
|
-
-
|
81
|
-
|
82
|
-
|
83
|
-
- Our issues tracker is at http://github.com/ruport/ruport/issues
|
80
|
+
- The latest stable API documentation is available at: http://rubydoc.info/gems/ruport/frames
|
81
|
+
- The code repository is on GitHub: https://github.com/ruport/ruport
|
82
|
+
- Our issues tracker is at https://github.com/ruport/ruport/issues
|
84
83
|
|
85
|
-
|
84
|
+
## Hacking
|
86
85
|
|
87
|
-
If you'd like to contribute code to Ruport,
|
88
|
-
mailing list, and let us know what you'd like to do!
|
89
|
-
|
90
|
-
http://groups.google.com/group/ruport-dev
|
91
|
-
|
92
|
-
The main Git repository is on GitHub:
|
93
|
-
http://github.com/ruport/ruport
|
94
|
-
|
95
|
-
It also may be worthwhile to join this list if you plan on running edge
|
96
|
-
versions of Ruport, as this is where we make announcements about major
|
97
|
-
breakage in trunk.
|
86
|
+
If you'd like to contribute code to Ruport, fork the repository and open a PR!
|
98
87
|
|
99
88
|
We are very responsive to contributors, and review every patch we receive
|
100
89
|
fairly quickly. Most contributors who successfully get a patch or two applied
|
@@ -103,3 +92,6 @@ development team. Since we view every user as potential contributor, this
|
|
103
92
|
approach works well for us.
|
104
93
|
|
105
94
|
So if you want to help out with Ruport, we'll happy accept your efforts!
|
95
|
+
|
96
|
+
[BS img]: https://travis-ci.org/ruport/ruport.svg?branch=master
|
97
|
+
[CS img]: https://coveralls.io/repos/ruport/ruport/badge.png?branch=master
|
data/Rakefile
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "bundler/setup"
|
3
3
|
|
4
|
-
require "rdoc/task"
|
5
4
|
require "rake/testtask"
|
6
5
|
require 'bundler/gem_tasks'
|
7
6
|
|
@@ -17,15 +16,6 @@ Rake::TestTask.new do |test|
|
|
17
16
|
test.verbose = true
|
18
17
|
end
|
19
18
|
|
20
|
-
RDoc::Task.new do |rdoc|
|
21
|
-
rdoc.rdoc_files.include( "README.rdoc",
|
22
|
-
"AUTHORS", "COPYING",
|
23
|
-
"LICENSE", "lib/" )
|
24
|
-
rdoc.main = "README.rdoc"
|
25
|
-
rdoc.rdoc_dir = "doc/html"
|
26
|
-
rdoc.title = "Ruport Documentation"
|
27
|
-
end
|
28
|
-
|
29
19
|
task :run_benchmarks do
|
30
20
|
files = FileList["util/bench/**/**/*.rb"]
|
31
21
|
files.sort!
|
data/examples/row_renderer.rb
CHANGED
@@ -41,7 +41,7 @@ class TracSummaryReport
|
|
41
41
|
Grouping(table,:by => :date)
|
42
42
|
end
|
43
43
|
|
44
|
-
def renderable_data(
|
44
|
+
def renderable_data(_format)
|
45
45
|
summary = feed_data.summary :date,
|
46
46
|
:opened => lambda { |g| g.sigma { |r| r.opened } },
|
47
47
|
:closed => lambda { |g| g.sigma { |r| r.closed } },
|
data/lib/ruport/controller.rb
CHANGED
@@ -216,7 +216,7 @@ class Ruport::Controller
|
|
216
216
|
def built_in_formats
|
217
217
|
{ :html => Ruport::Formatter::HTML,
|
218
218
|
:csv => Ruport::Formatter::CSV,
|
219
|
-
:pdf => Ruport::Formatter::
|
219
|
+
:pdf => Ruport::Formatter::PrawnPDF,
|
220
220
|
:prawn_pdf => Ruport::Formatter::PrawnPDF,
|
221
221
|
:text => Ruport::Formatter::Text }
|
222
222
|
end
|
data/lib/ruport/data/grouping.rb
CHANGED
@@ -99,7 +99,7 @@ module Ruport::Data
|
|
99
99
|
if @subgroups.empty?
|
100
100
|
@subgroups = grouped_data(group_column)
|
101
101
|
else
|
102
|
-
@subgroups.each {|
|
102
|
+
@subgroups.each {|_name,group|
|
103
103
|
group.send(:create_subgroups, group_column)
|
104
104
|
}
|
105
105
|
end
|
@@ -172,7 +172,7 @@ module Ruport::Data
|
|
172
172
|
cols = Array(options[:by]).dup
|
173
173
|
@data = data.to_group.send(:grouped_data, cols.shift)
|
174
174
|
cols.each do |col|
|
175
|
-
@data.each do |
|
175
|
+
@data.each do |_name,group|
|
176
176
|
group.send(:create_subgroups, col)
|
177
177
|
end
|
178
178
|
end
|
@@ -200,9 +200,9 @@ module Ruport::Data
|
|
200
200
|
#
|
201
201
|
def each
|
202
202
|
if @order.respond_to?(:call)
|
203
|
-
@data.sort_by { |
|
203
|
+
@data.sort_by { |_n,g| @order[g] }.each { |n,g| yield(n,g) }
|
204
204
|
elsif @order == :name
|
205
|
-
@data.sort_by { |n,
|
205
|
+
@data.sort_by { |n,_g| n }.each { |name,group| yield(name,group) }
|
206
206
|
else
|
207
207
|
@data.each { |name,group| yield(name,group) }
|
208
208
|
end
|
@@ -216,7 +216,7 @@ module Ruport::Data
|
|
216
216
|
# by_size = grouping.sort_grouping_by { |g| g.size }
|
217
217
|
def sort_grouping_by(type=nil,&block)
|
218
218
|
a = Grouping.new(:by => @grouped_by, :order => type || block)
|
219
|
-
each { |
|
219
|
+
each { |_n,g| a << g }
|
220
220
|
return a
|
221
221
|
end
|
222
222
|
|
@@ -285,7 +285,7 @@ module Ruport::Data
|
|
285
285
|
else
|
286
286
|
cols = procs.keys + [field]
|
287
287
|
end
|
288
|
-
|
288
|
+
Table.new(:column_names => cols) { |t|
|
289
289
|
each do |name,group|
|
290
290
|
t << procs.inject({field => name}) do |s,r|
|
291
291
|
s.merge(r[0] => r[1].call(group))
|
@@ -327,7 +327,7 @@ module Ruport::Data
|
|
327
327
|
# grouping.sigma { |r| r.col2 + 1 } #=> 15
|
328
328
|
#
|
329
329
|
def sigma(column=nil)
|
330
|
-
inject(0) do |s, (
|
330
|
+
inject(0) do |s, (_group_name, group)|
|
331
331
|
if column
|
332
332
|
s + group.sigma(column)
|
333
333
|
else
|
data/lib/ruport/data/record.rb
CHANGED
@@ -55,10 +55,10 @@ module Ruport::Data
|
|
55
55
|
case(data)
|
56
56
|
when Array
|
57
57
|
@attributes = options[:attributes] || (0...data.length).to_a
|
58
|
-
@data = @attributes.
|
58
|
+
@data = @attributes.each_with_object({}) { |a, h| h[a.freeze] = data.shift }
|
59
59
|
when Hash
|
60
|
-
@data = data
|
61
|
-
@attributes = options[:attributes] || data.keys
|
60
|
+
@data = data
|
61
|
+
@attributes = options[:attributes] || @data.keys
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -140,7 +140,7 @@ module Ruport::Data
|
|
140
140
|
case name
|
141
141
|
when String,Symbol
|
142
142
|
self[name] || send(name)
|
143
|
-
when
|
143
|
+
when Integer
|
144
144
|
self[name]
|
145
145
|
else
|
146
146
|
raise ArgumentError, "Whatchu Talkin' Bout, Willis?"
|
data/lib/ruport/data/table.rb
CHANGED
@@ -50,7 +50,7 @@ module Ruport::Data
|
|
50
50
|
ordering = self.class.row_order_to_group_order(@pivot_order)
|
51
51
|
pivot_column_grouping.sort_grouping_by!(ordering) if ordering
|
52
52
|
|
53
|
-
@row = pivot_column_grouping.map { |name,
|
53
|
+
@row = pivot_column_grouping.map { |name,_grouping| name }
|
54
54
|
end
|
55
55
|
|
56
56
|
# Column in the first column in the pivoted table (without the group column)
|
@@ -71,10 +71,10 @@ module Ruport::Data
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def values
|
74
|
-
@values ||= Hash.new do |
|
74
|
+
@values ||= Hash.new do |row_values, column_entry|
|
75
75
|
rows_group = rows_groups[column_entry]
|
76
76
|
|
77
|
-
|
77
|
+
row_values[column_entry] =
|
78
78
|
row.inject({}) do |values, row_entry|
|
79
79
|
matching_rows = rows_group.rows_with(@pivot_column => row_entry)
|
80
80
|
values[row_entry] = perform_operation(matching_rows)
|
@@ -132,7 +132,7 @@ module Ruport::Data
|
|
132
132
|
rows && rows.inject(0) { |sum,row| sum+row[summary_column] }
|
133
133
|
end
|
134
134
|
|
135
|
-
def count(rows,
|
135
|
+
def count(rows, _summary_column)
|
136
136
|
rows && rows.length
|
137
137
|
end
|
138
138
|
|
@@ -259,7 +259,7 @@ module Ruport::Data
|
|
259
259
|
table = self.new(options) do |feeder|
|
260
260
|
first_line = true
|
261
261
|
|
262
|
-
::CSV.send(msg,param,options[:csv_options]) do |row|
|
262
|
+
::CSV.send(msg,param, **options[:csv_options]) do |row|
|
263
263
|
if first_line
|
264
264
|
adjust_for_headers(feeder.data,row,options)
|
265
265
|
first_line = false
|
@@ -560,8 +560,8 @@ module Ruport::Data
|
|
560
560
|
# data.add_columns ['new_column_1','new_column_2'], :default => 1
|
561
561
|
#
|
562
562
|
def add_columns(names,options={})
|
563
|
-
raise "Greg isn't smart enough to figure this out.\n"
|
564
|
-
"Send ideas in at
|
563
|
+
raise "Greg isn't smart enough to figure this out.\n" \
|
564
|
+
"Send ideas in at github" if block_given?
|
565
565
|
need_reverse = !!(options[:after] || options[:position])
|
566
566
|
names = names.reverse if need_reverse
|
567
567
|
names.each { |n| add_column(n,options) }
|
@@ -576,7 +576,7 @@ module Ruport::Data
|
|
576
576
|
# table.remove_column("apple") #=> removes column named apple
|
577
577
|
#
|
578
578
|
def remove_column(col)
|
579
|
-
col = column_names[col] if col.kind_of?
|
579
|
+
col = column_names[col] if col.kind_of? Integer
|
580
580
|
column_names.delete(col)
|
581
581
|
each { |r| r.send(:delete,col) }
|
582
582
|
end
|
@@ -666,7 +666,7 @@ module Ruport::Data
|
|
666
666
|
# +-----------+
|
667
667
|
#
|
668
668
|
def swap_column(a,b)
|
669
|
-
if [a,b].all? { |r| r.kind_of?
|
669
|
+
if [a,b].all? { |r| r.kind_of? Integer }
|
670
670
|
col_a,col_b = column_names[a],column_names[b]
|
671
671
|
column_names[a] = col_b
|
672
672
|
column_names[b] = col_a
|
data/lib/ruport/formatter/csv.rb
CHANGED
@@ -55,7 +55,7 @@ module Ruport
|
|
55
55
|
#
|
56
56
|
def csv_writer
|
57
57
|
@csv_writer ||= options.formatter ||
|
58
|
-
::CSV.instance(output, options.format_options || {})
|
58
|
+
::CSV.instance(output, **(options.format_options || {}))
|
59
59
|
end
|
60
60
|
|
61
61
|
# Generates table header by turning column_names into a CSV row.
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruport
|
4
|
+
# This class produces Markdown table output from Ruport::Table data.
|
5
|
+
#
|
6
|
+
# === Rendering Options
|
7
|
+
# <tt>:alignment:</tt> Default alignment for all columns.
|
8
|
+
# Allowed values are :left, :center and :right. Default is :left.
|
9
|
+
#
|
10
|
+
# <tt>:column_alignments:</tt> Alignments for specific columns.
|
11
|
+
# You can configure alignments by using
|
12
|
+
# Hash (key: column name, value: alignment)
|
13
|
+
class Formatter::MarkDown < Formatter
|
14
|
+
renders :markdown, for: [Controller::Table]
|
15
|
+
|
16
|
+
# Hook for setting available options using a template.
|
17
|
+
def apply_template
|
18
|
+
apply_table_format_template(template.table)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Uses the column names from the given Data::Table to generate
|
22
|
+
# a table header.
|
23
|
+
# If no column names are given, first row will be
|
24
|
+
# treated as table header.
|
25
|
+
def build_table_header
|
26
|
+
names = column_names(data)
|
27
|
+
build_md_row(output, names)
|
28
|
+
build_md_row(output, alignment_strings(names))
|
29
|
+
end
|
30
|
+
|
31
|
+
# Generates body of Markdown table data.
|
32
|
+
# Following characters will be replaced as escape.
|
33
|
+
#
|
34
|
+
# * | -> |
|
35
|
+
# * newline code(\\n) -> \<br>
|
36
|
+
def build_table_body
|
37
|
+
body =
|
38
|
+
if data.column_names && !data.column_names.empty?
|
39
|
+
data
|
40
|
+
else
|
41
|
+
data[1..-1]
|
42
|
+
end
|
43
|
+
body.each { |row| build_md_row(output, row) }
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def column_names(data)
|
49
|
+
if data.column_names && !data.column_names.empty?
|
50
|
+
data.column_names
|
51
|
+
else
|
52
|
+
data[0]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_md_row(output, row)
|
57
|
+
output << "|"
|
58
|
+
output << row.to_a.map { |cell| escape(cell.to_s.dup) }.join('|')
|
59
|
+
output << "|\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
def escape(cell)
|
63
|
+
cell.gsub!("|", "|")
|
64
|
+
cell.gsub!("\n", "<br>")
|
65
|
+
cell
|
66
|
+
end
|
67
|
+
|
68
|
+
def alignment_strings(column_names)
|
69
|
+
column_names.map(&method(:alignment_string))
|
70
|
+
end
|
71
|
+
|
72
|
+
def alignment_string(column_name)
|
73
|
+
case column_alignment(column_name)
|
74
|
+
when :right
|
75
|
+
"--:"
|
76
|
+
when :center
|
77
|
+
":-:"
|
78
|
+
else
|
79
|
+
":--"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def column_alignment(column_name)
|
84
|
+
if options.column_alignments && options.column_alignments.key?(column_name)
|
85
|
+
options.column_alignments[column_name]
|
86
|
+
elsif options.alignment
|
87
|
+
options.alignment
|
88
|
+
else
|
89
|
+
:left
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def apply_table_format_template(template)
|
94
|
+
template = (template || {}).merge(options.table_format || {})
|
95
|
+
options.alignment ||= template[:alignment]
|
96
|
+
options.column_alignments =
|
97
|
+
merget_column_alignments(options, template)
|
98
|
+
end
|
99
|
+
|
100
|
+
def merget_column_alignments(options, template)
|
101
|
+
(template[:column_alignments] || {})
|
102
|
+
.merge(options.column_alignments || {})
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -4,7 +4,7 @@ module Ruport
|
|
4
4
|
renders :prawn_pdf, :for =>[Controller::Row, Controller::Table,
|
5
5
|
Controller::Group, Controller::Grouping]
|
6
6
|
|
7
|
-
|
7
|
+
attr_writer :pdf
|
8
8
|
|
9
9
|
def method_missing(id,*args, &block)
|
10
10
|
pdf.send(id,*args, &block)
|
@@ -12,7 +12,7 @@ module Ruport
|
|
12
12
|
|
13
13
|
def initialize
|
14
14
|
require 'prawn'
|
15
|
-
require 'prawn/
|
15
|
+
require 'prawn/table'
|
16
16
|
end
|
17
17
|
|
18
18
|
def pdf
|
@@ -20,7 +20,7 @@ module Ruport
|
|
20
20
|
::Prawn::Document.new(options[:pdf_format] || {} ))
|
21
21
|
end
|
22
22
|
|
23
|
-
def draw_table(table, format_opts={})
|
23
|
+
def draw_table(table, format_opts={}, &block)
|
24
24
|
m = "PDF Formatter requires column_names to be defined"
|
25
25
|
raise FormatterError, m if table.column_names.empty?
|
26
26
|
|
@@ -33,10 +33,10 @@ module Ruport
|
|
33
33
|
if options[:table_format]
|
34
34
|
opt = options[:table_format]
|
35
35
|
else
|
36
|
-
opt =
|
36
|
+
opt = format_opts
|
37
37
|
end
|
38
38
|
|
39
|
-
pdf.table(table_array,opt)
|
39
|
+
pdf.table(table_array, opt, &block)
|
40
40
|
|
41
41
|
end
|
42
42
|
|
@@ -48,15 +48,15 @@ module Ruport
|
|
48
48
|
output << pdf.render
|
49
49
|
end
|
50
50
|
|
51
|
-
def build_table_body
|
52
|
-
draw_table(data)
|
51
|
+
def build_table_body(&block)
|
52
|
+
draw_table(data, &block)
|
53
53
|
end
|
54
54
|
|
55
55
|
def build_group_body
|
56
56
|
render_table data, options.to_hash.merge(:formatter => pdf)
|
57
57
|
end
|
58
58
|
|
59
|
-
def build_grouping_body
|
59
|
+
def build_grouping_body(&block)
|
60
60
|
data.each do |name,group|
|
61
61
|
|
62
62
|
# Group heading
|
@@ -65,8 +65,95 @@ module Ruport
|
|
65
65
|
|
66
66
|
# Table
|
67
67
|
move_down(10)
|
68
|
-
draw_table group
|
68
|
+
draw_table group, &block
|
69
69
|
end
|
70
70
|
end
|
71
|
+
|
72
|
+
# Hook for setting available options using a template. See the template
|
73
|
+
# documentation for the available options and their format.
|
74
|
+
def apply_template
|
75
|
+
apply_page_format_template(template.page)
|
76
|
+
apply_text_format_template(template.text)
|
77
|
+
apply_table_format_template(template.table)
|
78
|
+
apply_column_format_template(template.column)
|
79
|
+
apply_heading_format_template(template.heading)
|
80
|
+
apply_grouping_format_template(template.grouping)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def apply_page_format_template(t)
|
86
|
+
options.pdf_format ||= {}
|
87
|
+
t = (t || {}).merge(options.page_format || {})
|
88
|
+
options.pdf_format[:page_size] ||= t[:size]
|
89
|
+
options.pdf_format[:page_layout] ||= t[:layout]
|
90
|
+
end
|
91
|
+
|
92
|
+
def apply_text_format_template(t)
|
93
|
+
t = (t || {}).merge(options.text_format || {})
|
94
|
+
options.text_format = t unless t.empty?
|
95
|
+
end
|
96
|
+
|
97
|
+
def apply_table_format_template(t)
|
98
|
+
t = (t || {}).merge(options.table_format || {})
|
99
|
+
options.table_format = t unless t.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
def apply_column_format_template(t)
|
103
|
+
t = (t || {}).merge(options.column_format || {})
|
104
|
+
column_opts = {}
|
105
|
+
column_opts.merge!(:justification => t[:alignment]) if t[:alignment]
|
106
|
+
column_opts.merge!(:width => t[:width]) if t[:width]
|
107
|
+
unless column_opts.empty?
|
108
|
+
if options.table_format
|
109
|
+
if options.table_format[:column_options]
|
110
|
+
options.table_format[:column_options] =
|
111
|
+
column_opts.merge(options.table_format[:column_options])
|
112
|
+
else
|
113
|
+
options.table_format.merge!(:column_options => column_opts)
|
114
|
+
end
|
115
|
+
else
|
116
|
+
options.table_format = { :column_options => column_opts }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def apply_heading_format_template(t)
|
122
|
+
t = (t || {}).merge(options.heading_format || {})
|
123
|
+
heading_opts = {}
|
124
|
+
heading_opts.merge!(:justification => t[:alignment]) if t[:alignment]
|
125
|
+
heading_opts.merge!(:bold => t[:bold]) unless t[:bold].nil?
|
126
|
+
heading_opts.merge!(:title => t[:title]) if t[:title]
|
127
|
+
unless heading_opts.empty?
|
128
|
+
if options.table_format
|
129
|
+
if options.table_format[:column_options]
|
130
|
+
if options.table_format[:column_options][:heading]
|
131
|
+
options.table_format[:column_options][:heading] =
|
132
|
+
heading_opts.merge(
|
133
|
+
options.table_format[:column_options][:heading]
|
134
|
+
)
|
135
|
+
else
|
136
|
+
options.table_format[:column_options].merge!(
|
137
|
+
:heading => heading_opts
|
138
|
+
)
|
139
|
+
end
|
140
|
+
else
|
141
|
+
options.table_format.merge!(
|
142
|
+
:column_options => { :heading => heading_opts }
|
143
|
+
)
|
144
|
+
end
|
145
|
+
else
|
146
|
+
options.table_format = {
|
147
|
+
:column_options => { :heading => heading_opts }
|
148
|
+
}
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def apply_grouping_format_template(t)
|
154
|
+
t = (t || {}).merge(options.grouping_format || {})
|
155
|
+
options.style ||= t[:style]
|
156
|
+
end
|
157
|
+
|
71
158
|
end
|
72
159
|
end
|