ruport 1.6.3 → 1.8.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.
- checksums.yaml +7 -0
- data/AUTHORS +11 -0
- data/CHANGELOG.md +38 -0
- data/HACKING +1 -17
- data/README.md +97 -0
- data/Rakefile +9 -50
- data/examples/add_row_table.rb +46 -0
- data/examples/data/wine.csv +255 -0
- data/examples/pdf_grouping.rb +39 -0
- data/examples/pdf_table.rb +28 -0
- data/examples/pdf_table_from_csv.rb +26 -0
- data/examples/pdf_table_prawn.rb +30 -0
- data/examples/pdf_table_simple.rb +13 -0
- 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 +17 -21
- data/lib/ruport/data/feeder.rb +2 -2
- data/lib/ruport/data/grouping.rb +8 -8
- data/lib/ruport/data/record.rb +4 -4
- data/lib/ruport/data/table.rb +318 -206
- data/lib/ruport/formatter/csv.rb +6 -7
- data/lib/ruport/formatter/html.rb +13 -11
- data/lib/ruport/formatter/markdown.rb +105 -0
- data/lib/ruport/formatter/prawn_pdf.rb +159 -0
- data/lib/ruport/formatter/template.rb +1 -1
- data/lib/ruport/formatter/text.rb +1 -1
- data/lib/ruport/formatter.rb +54 -54
- data/lib/ruport/version.rb +1 -1
- data/lib/ruport.rb +7 -23
- data/test/controller_test.rb +201 -225
- data/test/csv_formatter_test.rb +36 -36
- data/test/data_feeder_test.rb +64 -64
- data/test/expected_outputs/prawn_pdf_formatter/pdf_basic.pdf.test +265 -0
- data/test/grouping_test.rb +103 -102
- data/test/helpers.rb +29 -10
- data/test/html_formatter_test.rb +46 -46
- data/test/markdown_formatter_test.rb +142 -0
- data/test/prawn_pdf_formatter_test.rb +108 -0
- data/test/record_test.rb +91 -91
- data/test/samples/sales.csv +21 -0
- data/test/table_pivot_test.rb +77 -26
- data/test/table_test.rb +376 -354
- data/test/template_test.rb +13 -13
- data/test/text_formatter_test.rb +52 -52
- 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 +1 -2
- 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 +131 -82
- data/README +0 -114
- data/lib/ruport/formatter/pdf.rb +0 -591
- data/test/pdf_formatter_test.rb +0 -354
data/lib/ruport/formatter/csv.rb
CHANGED
@@ -14,16 +14,15 @@
|
|
14
14
|
module Ruport
|
15
15
|
|
16
16
|
# This formatter implements the CSV format for Ruport's Row, Table, Group
|
17
|
-
# and Grouping controllers.
|
18
|
-
# James Edward Gray II's FasterCSV.
|
17
|
+
# and Grouping controllers.
|
19
18
|
#
|
20
19
|
# === Rendering Options
|
21
20
|
#
|
22
21
|
# <tt>:style</tt> Used for grouping (:inline,:justified,:raw)
|
23
22
|
#
|
24
|
-
# <tt>:format_options</tt> A hash of
|
23
|
+
# <tt>:format_options</tt> A hash of CSV options
|
25
24
|
#
|
26
|
-
# <tt>:formatter</tt> An existing
|
25
|
+
# <tt>:formatter</tt> An existing CSV object to write to
|
27
26
|
#
|
28
27
|
# <tt>:show_table_headers</tt> True by default
|
29
28
|
#
|
@@ -35,7 +34,7 @@ module Ruport
|
|
35
34
|
Controller::Group, Controller::Grouping ]
|
36
35
|
|
37
36
|
def initialize
|
38
|
-
require "
|
37
|
+
require "csv"
|
39
38
|
end
|
40
39
|
|
41
40
|
attr_writer :csv_writer
|
@@ -49,14 +48,14 @@ module Ruport
|
|
49
48
|
options.format_options ||= template.format_options
|
50
49
|
end
|
51
50
|
|
52
|
-
# Returns the current
|
51
|
+
# Returns the current CSV object or creates a new one if it has not
|
53
52
|
# been set yet. Note that FCSV(sig) has a cache and returns the *same*
|
54
53
|
# FCSV object if writing to the same underlying output with the same
|
55
54
|
# options.
|
56
55
|
#
|
57
56
|
def csv_writer
|
58
57
|
@csv_writer ||= options.formatter ||
|
59
|
-
|
58
|
+
::CSV.instance(output, **(options.format_options || {}))
|
60
59
|
end
|
61
60
|
|
62
61
|
# Generates table header by turning column_names into a CSV row.
|
@@ -40,12 +40,7 @@ module Ruport
|
|
40
40
|
# This method does not do anything if options.show_table_headers is false
|
41
41
|
# or the Data::Table has no column names.
|
42
42
|
def build_table_header
|
43
|
-
output <<
|
44
|
-
unless data.column_names.empty? || !options.show_table_headers
|
45
|
-
output << "\t\t<tr>\n\t\t\t<th>" +
|
46
|
-
data.column_names.join("</th>\n\t\t\t<th>") +
|
47
|
-
"</th>\n\t\t</tr>\n"
|
48
|
-
end
|
43
|
+
output << build_header(options.show_table_headers ? data.column_names : nil)
|
49
44
|
end
|
50
45
|
|
51
46
|
# Uses the Row controller to build up the table body.
|
@@ -119,12 +114,19 @@ module Ruport
|
|
119
114
|
end
|
120
115
|
|
121
116
|
private
|
122
|
-
|
117
|
+
|
118
|
+
def build_header(columns)
|
119
|
+
if !columns || columns.empty?
|
120
|
+
"\t<table>\n"
|
121
|
+
else
|
122
|
+
"\t<table>\n\t\t<thead>\n\t\t<tr>\n\t\t\t<th>" +
|
123
|
+
columns.join("</th>\n\t\t\t<th>") +
|
124
|
+
"</th>\n\t\t</tr>\n\t\t</thead>\n"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
123
128
|
def render_justified_grouping
|
124
|
-
output <<
|
125
|
-
"#{data.grouped_by}</th>\n\t\t\t<th>" +
|
126
|
-
grouping_columns.join("</th>\n\t\t\t<th>") +
|
127
|
-
"</th>\n\t\t</tr>\n"
|
129
|
+
output << build_header(options.show_group_headers ? ([data.grouped_by] + grouping_columns) : nil)
|
128
130
|
data.each do |name, group|
|
129
131
|
group.each_with_index do |row, i|
|
130
132
|
output << "\t\t<tr>\n\t\t\t"
|
@@ -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
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module Ruport
|
2
|
+
class Formatter::PrawnPDF < Formatter
|
3
|
+
|
4
|
+
renders :prawn_pdf, :for =>[Controller::Row, Controller::Table,
|
5
|
+
Controller::Group, Controller::Grouping]
|
6
|
+
|
7
|
+
attr_writer :pdf
|
8
|
+
|
9
|
+
def method_missing(id,*args, &block)
|
10
|
+
pdf.send(id,*args, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
require 'prawn'
|
15
|
+
require 'prawn/table'
|
16
|
+
end
|
17
|
+
|
18
|
+
def pdf
|
19
|
+
@pdf ||= (options.formatter ||
|
20
|
+
::Prawn::Document.new(options[:pdf_format] || {} ))
|
21
|
+
end
|
22
|
+
|
23
|
+
def draw_table(table, format_opts={}, &block)
|
24
|
+
m = "PDF Formatter requires column_names to be defined"
|
25
|
+
raise FormatterError, m if table.column_names.empty?
|
26
|
+
|
27
|
+
table.rename_columns { |c| c.to_s }
|
28
|
+
|
29
|
+
table_array = [table.column_names]
|
30
|
+
table_array += table_to_array(table)
|
31
|
+
table_array.map { |array| array.map! { |elem| elem.class != String ? elem.to_s : elem }}
|
32
|
+
|
33
|
+
if options[:table_format]
|
34
|
+
opt = options[:table_format]
|
35
|
+
else
|
36
|
+
opt = format_opts
|
37
|
+
end
|
38
|
+
|
39
|
+
pdf.table(table_array, opt, &block)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def table_to_array(tbl)
|
44
|
+
tbl.map { |row| row.to_a}
|
45
|
+
end
|
46
|
+
|
47
|
+
def finalize
|
48
|
+
output << pdf.render
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_table_body(&block)
|
52
|
+
draw_table(data, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_group_body
|
56
|
+
render_table data, options.to_hash.merge(:formatter => pdf)
|
57
|
+
end
|
58
|
+
|
59
|
+
def build_grouping_body(&block)
|
60
|
+
data.each do |name,group|
|
61
|
+
|
62
|
+
# Group heading
|
63
|
+
move_down(20)
|
64
|
+
text name, :style => :bold, :size => 15
|
65
|
+
|
66
|
+
# Table
|
67
|
+
move_down(10)
|
68
|
+
draw_table group, &block
|
69
|
+
end
|
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
|
+
|
158
|
+
end
|
159
|
+
end
|
@@ -140,7 +140,7 @@ class Ruport::Formatter::TemplateNotDefined < StandardError; end
|
|
140
140
|
#
|
141
141
|
# format_options All options Corresponding values
|
142
142
|
# available to
|
143
|
-
#
|
143
|
+
# ::CSV.new
|
144
144
|
#
|
145
145
|
class Ruport::Formatter::Template < Ruport::Controller::Options
|
146
146
|
|
@@ -110,7 +110,7 @@ module Ruport
|
|
110
110
|
def build_row(data = self.data)
|
111
111
|
max_col_widths_for_row(data) unless options.max_col_width
|
112
112
|
|
113
|
-
data.enum_for(:each_with_index).inject(line=[]) { |
|
113
|
+
data.enum_for(:each_with_index).inject(line=[]) { |_s,e|
|
114
114
|
field,index = e
|
115
115
|
if options.alignment.eql? :center
|
116
116
|
line << field.to_s.center(options.max_col_width[index])
|
data/lib/ruport/formatter.rb
CHANGED
@@ -1,73 +1,73 @@
|
|
1
|
-
# Ruport : Extensible Reporting System
|
1
|
+
# Ruport : Extensible Reporting System
|
2
2
|
#
|
3
3
|
# formatter.rb provides a generalized base class for creating ruport formatters.
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Created By Gregory Brown
|
6
|
-
# Copyright (C) December 2006, All Rights Reserved.
|
6
|
+
# Copyright (C) December 2006, All Rights Reserved.
|
7
7
|
#
|
8
8
|
# This is free software distributed under the same terms as Ruby 1.8
|
9
9
|
# See LICENSE and COPYING for details.
|
10
|
-
module Ruport
|
10
|
+
module Ruport
|
11
11
|
# Formatter is the base class for Ruport's format implementations.
|
12
12
|
#
|
13
13
|
# Typically, a Formatter will implement one or more output types,
|
14
|
-
# and be registered with one or more Controller classes.
|
14
|
+
# and be registered with one or more Controller classes.
|
15
15
|
#
|
16
16
|
# This class provides all the necessary base functionality to make
|
17
17
|
# use of Ruport's rendering system, including option handling, data
|
18
18
|
# access, and basic output wrapping.
|
19
19
|
#
|
20
20
|
# The following example should provide a general idea of how formatters
|
21
|
-
# work, but see the built in formatters for reference implementations.
|
22
|
-
#
|
21
|
+
# work, but see the built in formatters for reference implementations.
|
22
|
+
#
|
23
23
|
# A simple Controller definition is included to help show the example in
|
24
24
|
# context, but you can also build your own custom interface to formatter
|
25
25
|
# if you wish.
|
26
26
|
#
|
27
27
|
# class ReverseController < Ruport::Controller
|
28
|
-
# stage :reversed_header, :reversed_body
|
28
|
+
# stage :reversed_header, :reversed_body
|
29
29
|
# end
|
30
|
-
#
|
31
|
-
# class ReversedText < Ruport::Formatter
|
32
|
-
#
|
30
|
+
#
|
31
|
+
# class ReversedText < Ruport::Formatter
|
32
|
+
#
|
33
33
|
# # Hooks formatter up to controller
|
34
|
-
# renders :txt, :for => ReverseController
|
35
|
-
#
|
34
|
+
# renders :txt, :for => ReverseController
|
35
|
+
#
|
36
36
|
# # Implements ReverseController's :reversed_header hook
|
37
|
-
# # but can be used by any controller
|
38
|
-
# def build_reversed_header
|
37
|
+
# # but can be used by any controller
|
38
|
+
# def build_reversed_header
|
39
39
|
# output << "#{options.header_text}\n"
|
40
40
|
# output << "The reversed text will follow\n"
|
41
|
-
# end
|
42
|
-
#
|
41
|
+
# end
|
42
|
+
#
|
43
43
|
# # Implements ReverseController's :reversed_body hook
|
44
44
|
# # but can be used by any controller
|
45
45
|
# def build_reversed_body
|
46
46
|
# output << data.reverse << "\n"
|
47
|
-
# end
|
47
|
+
# end
|
48
48
|
#
|
49
|
-
# end
|
49
|
+
# end
|
50
50
|
#
|
51
51
|
# puts ReverseController.render_txt(:data => "apple",
|
52
52
|
# :header_text => "Hello Mike, Hello Joe!")
|
53
|
-
#
|
53
|
+
#
|
54
54
|
# -----
|
55
|
-
# OUTPUT:
|
56
|
-
#
|
55
|
+
# OUTPUT:
|
56
|
+
#
|
57
57
|
# Hello Mike, Hello Joe!
|
58
58
|
# The reversed text will follow
|
59
59
|
# elppa
|
60
|
-
#
|
60
|
+
#
|
61
61
|
class Formatter
|
62
|
-
|
62
|
+
|
63
63
|
# Provides shortcuts so that you can use Ruport's default rendering
|
64
|
-
# capabilities within your custom formatters
|
64
|
+
# capabilities within your custom formatters
|
65
65
|
#
|
66
66
|
module RenderingTools
|
67
67
|
# Uses Controller::Row to render the Row object with the
|
68
68
|
# given options.
|
69
69
|
#
|
70
|
-
# Sets the <tt>:io</tt> attribute by default to the existing
|
70
|
+
# Sets the <tt>:io</tt> attribute by default to the existing
|
71
71
|
# formatter's <tt>output</tt> object.
|
72
72
|
def render_row(row,options={},&block)
|
73
73
|
render_helper(Controller::Row,row,options,&block)
|
@@ -99,12 +99,12 @@ module Ruport
|
|
99
99
|
def render_grouping(grouping,options={},&block)
|
100
100
|
render_helper(Controller::Grouping,grouping,options,&block)
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
# Iterates through the data in the grouping and renders each group
|
104
104
|
# followed by a newline.
|
105
105
|
#
|
106
106
|
def render_inline_grouping(options={},&block)
|
107
|
-
data.each do |_,group|
|
107
|
+
data.each do |_,group|
|
108
108
|
render_group(group, options, &block)
|
109
109
|
output << "\n"
|
110
110
|
end
|
@@ -113,11 +113,10 @@ module Ruport
|
|
113
113
|
private
|
114
114
|
|
115
115
|
def render_helper(rend_klass, source_data,options={},&block)
|
116
|
-
options = {:data => source_data,
|
116
|
+
options = {:data => source_data,
|
117
117
|
:io => output,
|
118
|
-
:layout => false }.merge(options)
|
119
|
-
|
120
|
-
options[:io] = "" if self.class.kind_of?(Ruport::Formatter::PDF)
|
118
|
+
:layout => false }.merge(options)
|
119
|
+
|
121
120
|
rend_klass.render(format,options) do |rend|
|
122
121
|
block[rend] if block
|
123
122
|
end
|
@@ -126,13 +125,13 @@ module Ruport
|
|
126
125
|
end
|
127
126
|
|
128
127
|
include RenderingTools
|
129
|
-
|
128
|
+
|
130
129
|
# Set by the <tt>:data</tt> attribute from Controller#render
|
131
|
-
attr_reader :data
|
132
|
-
|
130
|
+
attr_reader :data
|
131
|
+
|
133
132
|
# Set automatically by Controller#render(format) or Controller#render_format
|
134
|
-
attr_accessor :format
|
135
|
-
|
133
|
+
attr_accessor :format
|
134
|
+
|
136
135
|
# Set automatically by Controller#render as a Controller::Options object built
|
137
136
|
# by the hash provided.
|
138
137
|
attr_writer :options
|
@@ -145,24 +144,24 @@ module Ruport
|
|
145
144
|
#
|
146
145
|
def self.renders(fmts,options={})
|
147
146
|
Array(fmts).each do |format|
|
148
|
-
Array(options[:for]).each do |o|
|
149
|
-
o.send(:add_format,self,format)
|
147
|
+
Array(options[:for]).each do |o|
|
148
|
+
o.send(:add_format,self,format)
|
150
149
|
formats << format unless formats.include?(format)
|
151
|
-
end
|
150
|
+
end
|
152
151
|
end
|
153
152
|
end
|
154
|
-
|
153
|
+
|
155
154
|
# Allows you to implement stages in your formatter using the
|
156
155
|
# following syntax:
|
157
156
|
#
|
158
|
-
# class ReversedText < Ruport::Formatter
|
157
|
+
# class ReversedText < Ruport::Formatter
|
159
158
|
# renders :txt, :for => ReverseController
|
160
|
-
#
|
159
|
+
#
|
161
160
|
# build :reversed_header do
|
162
161
|
# output << "#{options.header_text}\n"
|
163
162
|
# output << "The reversed text will follow\n"
|
164
163
|
# end
|
165
|
-
#
|
164
|
+
#
|
166
165
|
# build :reversed_body do
|
167
166
|
# output << data.reverse << "\n"
|
168
167
|
# end
|
@@ -171,12 +170,12 @@ module Ruport
|
|
171
170
|
def self.build(stage,&block)
|
172
171
|
define_method "build_#{stage}", &block
|
173
172
|
end
|
174
|
-
|
173
|
+
|
175
174
|
# Gives a list of formats registered for this formatter.
|
176
175
|
def self.formats
|
177
176
|
@formats ||= []
|
178
|
-
end
|
179
|
-
|
177
|
+
end
|
178
|
+
|
180
179
|
# Returns the template currently set for this formatter.
|
181
180
|
def template
|
182
181
|
Template[options.template] rescue nil || Template[:default]
|
@@ -191,7 +190,7 @@ module Ruport
|
|
191
190
|
# Provides a Controller::Options object for storing formatting options.
|
192
191
|
def options
|
193
192
|
@options ||= Controller::Options.new
|
194
|
-
end
|
193
|
+
end
|
195
194
|
|
196
195
|
# Sets the data object, making a local copy using #dup. This may have
|
197
196
|
# a significant overhead for large tables, so formatters which don't
|
@@ -204,24 +203,24 @@ module Ruport
|
|
204
203
|
def clear_output
|
205
204
|
@output.replace("")
|
206
205
|
end
|
207
|
-
|
206
|
+
|
208
207
|
# Saves the output to a file.
|
209
208
|
def save_output(filename)
|
210
209
|
File.open(filename,"w") {|f| f << output }
|
211
210
|
end
|
212
|
-
|
211
|
+
|
213
212
|
# Use to define that your formatter should save in binary format
|
214
213
|
def self.save_as_binary_file
|
215
214
|
define_method :save_output do |filename|
|
216
215
|
File.open(filename,"wb") {|f| f << output }
|
217
216
|
end
|
218
217
|
end
|
219
|
-
|
218
|
+
|
220
219
|
# Evaluates the string using ERB and returns the results.
|
221
220
|
#
|
222
221
|
# If <tt>:binding</tt> is specified, it will evaluate the template
|
223
222
|
# in that context.
|
224
|
-
def erb(string,options={})
|
223
|
+
def erb(string,options={})
|
225
224
|
require "erb"
|
226
225
|
if string =~ /(\.r\w+)|(\.erb)$/
|
227
226
|
ERB.new(File.read(string)).result(options[:binding]||binding)
|
@@ -245,10 +244,11 @@ module Ruport
|
|
245
244
|
end
|
246
245
|
end
|
247
246
|
end
|
248
|
-
end
|
247
|
+
end
|
249
248
|
|
250
249
|
require "ruport/formatter/template"
|
251
250
|
require "ruport/formatter/csv"
|
252
251
|
require "ruport/formatter/html"
|
253
252
|
require "ruport/formatter/text"
|
254
|
-
require "ruport/formatter/
|
253
|
+
require "ruport/formatter/prawn_pdf"
|
254
|
+
require "ruport/formatter/markdown"
|
data/lib/ruport/version.rb
CHANGED
data/lib/ruport.rb
CHANGED
@@ -10,18 +10,6 @@
|
|
10
10
|
# See LICENSE and COPYING for details
|
11
11
|
#
|
12
12
|
|
13
|
-
|
14
|
-
if RUBY_VERSION > "1.9"
|
15
|
-
require "csv"
|
16
|
-
unless defined? FCSV
|
17
|
-
class Object
|
18
|
-
FCSV = CSV
|
19
|
-
alias_method :FCSV, :CSV
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
13
|
module Ruport #:nodoc:#
|
26
14
|
class FormatterError < RuntimeError #:nodoc:
|
27
15
|
end
|
@@ -72,29 +60,26 @@ module Ruport #:nodoc:#
|
|
72
60
|
stdout_handle = m_GetStdHandle.call(0xFFFFFFF5)
|
73
61
|
|
74
62
|
m_GetConsoleScreenBufferInfo.call(stdout_handle, buf)
|
75
|
-
|
76
|
-
left, top, right, bottom, maxx, maxy = buf.unpack(format)
|
63
|
+
_bufx, _bufy, _curx, _cury, _wattr, left, top, right, bottom, _maxx, _maxy = buf.unpack(format)
|
77
64
|
return right - left + 1, bottom - top + 1
|
78
65
|
end
|
79
66
|
rescue LoadError # If we're not on Windows try...
|
80
67
|
# A Unix savvy method to fetch the console columns, and rows.
|
81
68
|
def terminal_size
|
82
69
|
size = if /solaris/ =~ RUBY_PLATFORM
|
83
|
-
output = `stty`
|
70
|
+
output = `stty 2>&1`
|
84
71
|
[output.match('columns = (\d+)')[1].to_i,
|
85
72
|
output.match('rows = (\d+)')[1].to_i]
|
86
73
|
else
|
87
|
-
`stty size`.split.map { |x| x.to_i }.reverse
|
74
|
+
`stty size 2>&1`.split.map { |x| x.to_i }.reverse
|
88
75
|
end
|
89
76
|
return $? == 0 ? size : [80,24]
|
90
77
|
end
|
91
|
-
|
92
|
-
end
|
78
|
+
end
|
93
79
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
80
|
+
def terminal_width
|
81
|
+
terminal_size.first
|
82
|
+
end
|
98
83
|
end
|
99
84
|
|
100
85
|
# quiets warnings for block
|
@@ -111,7 +96,6 @@ module Ruport #:nodoc:#
|
|
111
96
|
end
|
112
97
|
|
113
98
|
require "ruport/version"
|
114
|
-
require "enumerator"
|
115
99
|
require "ruport/controller"
|
116
100
|
require "ruport/data"
|
117
101
|
require "ruport/formatter"
|