ruport 0.6.1 → 0.7.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.
Files changed (83) hide show
  1. data/AUTHORS +6 -0
  2. data/Rakefile +4 -4
  3. data/TODO +3 -2
  4. data/bin/rope +2 -103
  5. data/examples/pdf_complex_report.rb +53 -0
  6. data/lib/ruport/config.rb +7 -7
  7. data/lib/ruport/data/collection.rb +8 -7
  8. data/lib/ruport/data/groupable.rb +3 -2
  9. data/lib/ruport/data/record.rb +13 -16
  10. data/lib/ruport/data/table.rb +89 -18
  11. data/lib/ruport/format/csv.rb +29 -0
  12. data/lib/ruport/format/html.rb +40 -0
  13. data/lib/ruport/format/latex.rb +50 -0
  14. data/lib/ruport/format/pdf.rb +78 -0
  15. data/lib/ruport/format/plugin.rb +20 -65
  16. data/lib/ruport/format/svg.rb +39 -0
  17. data/lib/ruport/format/text.rb +77 -0
  18. data/lib/ruport/format/xml.rb +32 -0
  19. data/lib/ruport/format.rb +1 -159
  20. data/lib/ruport/generator.rb +158 -0
  21. data/lib/ruport/layout/component.rb +7 -0
  22. data/lib/ruport/layout.rb +1 -0
  23. data/lib/ruport/query.rb +3 -3
  24. data/lib/ruport/renderer/graph.rb +48 -0
  25. data/lib/ruport/renderer/table.rb +132 -0
  26. data/lib/ruport/renderer.rb +193 -0
  27. data/lib/ruport/report/graph.rb +2 -2
  28. data/lib/ruport/report.rb +94 -96
  29. data/lib/ruport/system_extensions.rb +3 -6
  30. data/lib/ruport.rb +6 -4
  31. data/test/samples/dates.csv +1409 -0
  32. data/test/samples/foo.rtxt +3 -0
  33. data/test/test_collection.rb +0 -14
  34. data/test/test_config.rb +6 -6
  35. data/test/test_graph_renderer.rb +97 -0
  36. data/test/test_groupable.rb +1 -0
  37. data/test/test_query.rb +325 -324
  38. data/test/test_record.rb +3 -2
  39. data/test/test_renderer.rb +74 -0
  40. data/test/test_report.rb +29 -26
  41. data/test/test_table.rb +54 -29
  42. data/test/test_table_renderer.rb +93 -0
  43. data/test/test_text_table.rb +61 -0
  44. data/test/unit.log +24 -0
  45. metadata +41 -63
  46. data/CHANGELOG +0 -587
  47. data/examples/basic_grouping.rb +0 -19
  48. data/examples/fieldless_table.rb +0 -13
  49. data/examples/latex_table.rb +0 -17
  50. data/examples/line_graph.rb +0 -22
  51. data/examples/line_graph_report.rb +0 -23
  52. data/examples/line_plotter.rb +0 -46
  53. data/examples/long.txt +0 -24
  54. data/examples/new_plugin.rb +0 -24
  55. data/examples/report.rb +0 -35
  56. data/examples/sample_invoice_report.rb +0 -32
  57. data/examples/simple_mail.rb +0 -15
  58. data/examples/simple_table_interface.rb +0 -20
  59. data/examples/sql_erb.rb +0 -20
  60. data/examples/template.rb +0 -15
  61. data/examples/text_processors.rb +0 -13
  62. data/lib/ruport/format/engine/document.rb +0 -28
  63. data/lib/ruport/format/engine/graph.rb +0 -18
  64. data/lib/ruport/format/engine/invoice.rb +0 -23
  65. data/lib/ruport/format/engine/table.rb +0 -54
  66. data/lib/ruport/format/engine.rb +0 -108
  67. data/lib/ruport/format/plugin/csv_plugin.rb +0 -26
  68. data/lib/ruport/format/plugin/html_plugin.rb +0 -32
  69. data/lib/ruport/format/plugin/latex_plugin.rb +0 -50
  70. data/lib/ruport/format/plugin/pdf_plugin.rb +0 -126
  71. data/lib/ruport/format/plugin/svg_plugin.rb +0 -61
  72. data/lib/ruport/format/plugin/text_plugin.rb +0 -77
  73. data/lib/ruport/meta_tools.rb +0 -66
  74. data/lib/ruport/report/invoice.rb +0 -29
  75. data/test/_test_groupable.rb +0 -0
  76. data/test/test_format.rb +0 -39
  77. data/test/test_format_engine.rb +0 -264
  78. data/test/test_graph.rb +0 -93
  79. data/test/test_invoice.rb +0 -32
  80. data/test/test_latex.rb +0 -20
  81. data/test/test_meta_tools.rb +0 -14
  82. data/test/test_plugin.rb +0 -277
  83. data/test/ts_all.rb +0 -21
@@ -0,0 +1,48 @@
1
+ # renderer/graph.rb
2
+ # Generalized graphing support for Ruby Reports
3
+ #
4
+ # Written by Gregory Brown, Copright December 2006, All Rights Reserved.
5
+ #
6
+ # This is free software. See LICENSE and COPYING for details.
7
+
8
+ module Ruport
9
+
10
+ # This class implements the basic graphing engine for Ruport.
11
+ #
12
+ # == Supported Format Plugins
13
+ #
14
+ # * Format::XML
15
+ # * Format::SVG
16
+ #
17
+ # == Default layout options
18
+ #
19
+ # * height #=> 350
20
+ # * width #=> 500
21
+ # * style #=> :line
22
+ #
23
+ # == Plugin hooks called (in order)
24
+ #
25
+ # * prepare_graph
26
+ # * build_graph
27
+ # * finalize_graph
28
+ class Renderer::Graph < Renderer
29
+
30
+ include Renderer::Helpers
31
+
32
+ add_formats :svg,:xml
33
+
34
+ layout do |l|
35
+ l.height = 350
36
+ l.width = 500
37
+ l.style = :line
38
+ end
39
+
40
+ def run
41
+ prepare :graph
42
+ build :graph
43
+ finalize :graph
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,132 @@
1
+ # renderer/table.rb : Tabular data renderer for Ruby Reports
2
+ #
3
+ # Written by Gregory Brown, December 2006. Copyright 2006, All Rights Reserved
4
+ # This is Free Software, please see LICENSE and COPYING for details.
5
+
6
+ module Ruport
7
+ #
8
+ # This module provides some additional methods for Renderer::Table that may be
9
+ # helpful when rendering tabular data.
10
+ #
11
+ # These methods assume you are working with Data::Table objects
12
+ module Renderer::TableHelpers
13
+
14
+ # Allows you to modify a column at rendering time based on a block.
15
+ # This will not effect the original data object you provided to the table
16
+ # renderer
17
+ #
18
+ # Example:
19
+ #
20
+ # table.as(:text){ |r| r.rewrite_column("col1") { |a| a[0] + 5 }
21
+ # table.as(:csv) { |r| r.rewrite_column(2) { |a| a.capitalize }
22
+ def rewrite_column(key,&block)
23
+ data.each { |r| r[key] = block[r] }
24
+ end
25
+
26
+ # Gets the number of columns in a table. Useful in formatting plugins.
27
+ def num_cols
28
+ data[0].to_a.length
29
+ end
30
+
31
+ # Allows you to remove duplicates from data tables.
32
+ #
33
+ # By default, it will try to prune the entire table, but you may provide a
34
+ # limit of how many columns in it should work.
35
+ #
36
+ # Examples:
37
+ #
38
+ # irb(main):014:0> puts a
39
+ # +-----------+
40
+ # | a | b | c |
41
+ # +-----------+
42
+ # | 1 | 2 | 3 |
43
+ # | 1 | 2 | 2 |
44
+ # | 1 | 3 | 5 |
45
+ # | 2 | 7 | 9 |
46
+ # | 2 | 8 | 3 |
47
+ # | 2 | 7 | 1 |
48
+ # | 1 | 7 | 9 |
49
+ # +-----------+
50
+ # => nil
51
+ # irb(main):015:0> puts a.as(:text) { |e| e.prune(2) }
52
+ # +-----------+
53
+ # | a | b | c |
54
+ # +-----------+
55
+ # | 1 | 2 | 3 |
56
+ # | | | 2 |
57
+ # | | 3 | 5 |
58
+ # | 2 | 7 | 9 |
59
+ # | | 8 | 3 |
60
+ # | | 7 | 1 |
61
+ # | 1 | 7 | 9 |
62
+ # +-----------+
63
+ # => nil
64
+ # irb(main):016:0> puts a.as(:text) { |e| e.prune(1) }
65
+ # +-----------+
66
+ # | a | b | c |
67
+ # +-----------+
68
+ # | 1 | 2 | 3 |
69
+ # | | 2 | 2 |
70
+ # | | 3 | 5 |
71
+ # | 2 | 7 | 9 |
72
+ # | | 8 | 3 |
73
+ # | | 7 | 1 |
74
+ # | 1 | 7 | 9 |
75
+ # +-----------+
76
+ def prune(limit=data[0].length)
77
+ require "enumerator"
78
+ limit.times do |field|
79
+ last = ""
80
+ data.each_cons(2) { |l,e|
81
+ next if field.nonzero? && e[field-1]
82
+ last = l[field] if l[field]
83
+ e[field] = nil if e[field] == last
84
+ }
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ # This class implements the basic tabular data renderer for Ruport.
91
+ #
92
+ # For a set of methods that might be helpful while working with this class,
93
+ # see the included TableHelpers module
94
+ #
95
+ # == Supported Format Plugins
96
+ #
97
+ # * Format::CSV
98
+ # * Format::Text
99
+ # * Format::HTML
100
+ # * Format::Latex
101
+ # * Format::PDF
102
+ #
103
+ # == Default layout options
104
+ #
105
+ # * <tt>show_table_headers</tt> #=> true
106
+ #
107
+ # == Plugin hooks called (in order)
108
+ #
109
+ # * prepare_table
110
+ # * build_table_header
111
+ # * build_table_body
112
+ # * build_table_footer
113
+ # * finalize_table
114
+ #
115
+ class Renderer::Table < Renderer
116
+ include TableHelpers
117
+ include Renderer::Helpers
118
+
119
+ add_formats :csv, :text, :html, :latex, :pdf
120
+
121
+ layout do |lay|
122
+ lay.show_table_headers = true
123
+ end
124
+
125
+ def run
126
+ prepare :table
127
+ build [:header,:body,:footer], :table
128
+ finalize :table
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,193 @@
1
+ # renderer.rb : General purpose formatted data renderer for Ruby Reports
2
+ #
3
+ # Copyright December 2006, Gregory Brown. All Rights Reserved.
4
+ #
5
+ # This is free software. Please see the LICENSE and COPYING files for details.
6
+
7
+
8
+ # This class implements the core engine for Ruport's formatting system. It is
9
+ # designed to implement the low level tools necessary to build report renderers
10
+ # for different kinds of tasks. See Renderer::Table for a tabular data renderer
11
+ # and Renderer::Graph for graphing support.
12
+ #
13
+ # This class can easily be extended to build custom formatting engines, but if
14
+ # you do not need that, may not be relevant to study for your use of Ruport.
15
+ class Ruport::Renderer
16
+ module Helpers #:nodoc:
17
+ def prepare(name)
18
+ maybe "prepare_#{name}"
19
+ end
20
+
21
+ def build(names,prefix=nil)
22
+ return maybe("build_#{names}") if prefix.nil?
23
+ names.each { |n| maybe "build_#{prefix}_#{n}" }
24
+ end
25
+
26
+ def finalize(name)
27
+ maybe "finalize_#{name}"
28
+ end
29
+
30
+ private
31
+
32
+ def maybe(something)
33
+ plugin.send something if plugin.respond_to? something
34
+ end
35
+ end
36
+ # allows you to register a format with the renderer.
37
+ #
38
+ # example:
39
+ #
40
+ # class MyPlugin < Ruport::Format::Plugin
41
+ #
42
+ # # plugin code ...
43
+ #
44
+ # SomeRenderer.add_format self, :my_plugin
45
+ #
46
+ # end
47
+ def self.add_format(format,name=nil)
48
+ return formats[name] = format if name
49
+
50
+ add_core_format(format)
51
+ end
52
+
53
+
54
+ # reader for formats. Defaults to a hash
55
+ def self.formats
56
+ @formats ||= {}
57
+ end
58
+
59
+ # same as Renderer#layout, but can be used to specify a default layout object
60
+ # for the entire class.
61
+ def self.layout
62
+ @layout ||= Ruport::Layout::Component.new
63
+ yield(@layout) if block_given?
64
+
65
+ return @layout
66
+ end
67
+
68
+ # creates a new instance of the renderer
69
+ # then looks up the formatting plugin and creates a new instance of that as
70
+ # well. If a block is given, the renderer instance is yielded.
71
+ #
72
+ # The run() method is then called on the renderer method.
73
+ #
74
+ # Finally, the value of the plugin's output accessor is returned
75
+ def self.render(format,&block)
76
+ rend = build format, &block
77
+ rend.run
78
+ return rend.plugin.output
79
+ end
80
+
81
+
82
+ # creates a new instance of the renderer and sets it to use the specified
83
+ # formatting plugin (by name). If a block is given, the renderer instance is
84
+ # yielded.
85
+ #
86
+ # Returns the renderer instance.
87
+ def self.build(format)
88
+ rend = self.new
89
+
90
+ rend.send(:use_plugin,format)
91
+ rend.send(:layout=, layout.dup)
92
+ yield(rend) if block_given?
93
+ return rend
94
+ end
95
+
96
+ attr_accessor :format
97
+ attr_reader :data
98
+
99
+ # Generates a layout object and passes it along to the current formatting
100
+ # plugin. If the block form is used, the layout object will be yielded for
101
+ # modification.
102
+ #
103
+ def layout
104
+ @layout ||= Ruport::Layout::Component.new
105
+ yield(@layout) if block_given?
106
+
107
+ plugin.layout = @layout
108
+ end
109
+
110
+ # sets +data+ attribute on both the renderer and any active plugin
111
+ def data=(val)
112
+ @data = val.dup
113
+ plugin.data = @data if plugin
114
+ end
115
+
116
+ # General purpose openstruct which is shared with the current formatting
117
+ # plugin.
118
+ def options
119
+ yield(plugin.options) if block_given?
120
+ plugin.options
121
+ end
122
+
123
+ # when no block is given, returns active plugin
124
+ #
125
+ # when a block is given with a block variable, sets the block variable to the
126
+ # plugin.
127
+ #
128
+ # when a block is given without block variables, instance_evals the block
129
+ # within the context of the plugin
130
+ def plugin(&block)
131
+ if block.nil?
132
+ return @plugin
133
+ elsif block.arity > 0
134
+ yield(@plugin)
135
+ else
136
+ @plugin.instance_eval(&block)
137
+ end
138
+ return @plugin
139
+ end
140
+
141
+ private
142
+
143
+ attr_writer :plugin
144
+
145
+ #internal layout accessor.
146
+ def layout=(lay)
147
+ @layout = lay
148
+ plugin.layout = lay
149
+ end
150
+
151
+ # tries to autoload and register a format which is part of the Ruport::Format
152
+ # module. For internal use only.
153
+ def self.add_core_format(format)
154
+ try_require(format)
155
+
156
+ klass = Ruport::Format.const_get(
157
+ Ruport::Format.constants.find { |c| c =~ /#{format}/i })
158
+
159
+ formats[format] = klass
160
+ end
161
+
162
+ # internal shortcut for format registering
163
+ def self.add_formats(*formats)
164
+ formats.each { |f| add_format f }
165
+ end
166
+
167
+ # Trys to autoload a given format,
168
+ # silently fails
169
+ def self.try_require(format)
170
+ begin
171
+ require "ruport/format/#{format}"
172
+ rescue LoadError
173
+ nil
174
+ end
175
+ end
176
+
177
+ # selects a plugin for use by format name
178
+ def use_plugin(format)
179
+ self.plugin = self.class.formats[format].new
180
+ end
181
+
182
+ # provides a shortcut to render() to allow
183
+ # render(:csv) to become render_csv
184
+ def self.method_missing(id,*args,&block)
185
+ id.to_s =~ /^render_(.*)/
186
+ $1 ? render($1.to_sym,&block) : super
187
+ end
188
+
189
+
190
+ end
191
+
192
+ require "ruport/renderer/table"
193
+ require "ruport/renderer/graph"
@@ -2,12 +2,12 @@ module Ruport
2
2
  class Report
3
3
  module Graph #:nodoc:
4
4
  def build_graph
5
- a = Ruport::Format.graph_object :plugin => :svg
5
+ a = Ruport::Renderer::Graph.build(:svg)
6
6
  yield(a); return a
7
7
  end
8
8
 
9
9
  def render_graph(&block)
10
- build_graph(&block).render
10
+ build_graph(&block).run
11
11
  end
12
12
  end
13
13
  end
data/lib/ruport/report.rb CHANGED
@@ -7,14 +7,14 @@
7
7
 
8
8
  #load the needed standard libraries.
9
9
  %w[erb yaml date logger fileutils].each { |lib| require lib }
10
- %w[invoice graph].each { |lib| require "ruport/report/"+lib }
10
+ %w[graph].each { |lib| require "ruport/report/"+lib }
11
11
  require "forwardable"
12
12
 
13
13
  module Ruport
14
14
 
15
15
  # === Overview
16
16
  #
17
- # The Ruport::Report class povides a high level interface to most of Ruport's
17
+ # The Ruport::Report class provides a high level interface to most of Ruport's
18
18
  # functionality. It is designed to allow you to build and run reports easily.
19
19
  # If your needs are complicated, you will probably need to take a look at the
20
20
  # individual classes of the library, but if they are fairly simple, you may be
@@ -72,7 +72,6 @@ module Ruport
72
72
  class Report
73
73
  extend Forwardable
74
74
 
75
- include Ruport::Data::TableHelper
76
75
  #
77
76
  # When initializing a report, you can provide a default mailer and source by
78
77
  # giving a name of a valid source or mailer you've defined via
@@ -139,26 +138,15 @@ module Ruport
139
138
  options[:source] ||= @source
140
139
  options[:binding] ||= binding
141
140
  q = options[:query_obj] || Query.new(sql, options)
142
- if options[:yield_type].eql?(:by_row)
141
+ if block_given?
143
142
  q.each { |r| yield(r) }
144
143
  elsif options[:as]
145
- Format.table :data => q.result, :plugin => options[:as]
144
+ q.result.as(options[:as])
146
145
  else
147
- block_given? ? yield(q.result) : q.result
146
+ q.result
148
147
  end
149
148
  end
150
149
 
151
- #
152
- # Evaluates <tt>code</tt> from <tt>filename</tt> as pure ruby code for
153
- # files ending in .rb, and as ERb templates for anything else.
154
- #
155
- # This code will be evaluated in the context of the instance on which it
156
- # is called.
157
- #
158
- def eval_template( code, filename=nil )
159
- filename =~ /\.rb/ ? eval(code) : ERB.new(code, 0, "%").result(binding)
160
- end
161
-
162
150
  # Sets the active source to the Ruport::Config source requested by <tt>label</tt>.
163
151
  def use_source(label)
164
152
  @source = label
@@ -169,55 +157,103 @@ module Ruport
169
157
  @mailer = label
170
158
  end
171
159
 
160
+ # Writes the contents of <tt>results</tt> to a file. If a filename is
161
+ # specified, it will use it. Otherwise, it will try to write to the file
162
+ # specified by the <tt>file</tt> attribute.
163
+ #
164
+ def write(my_file=file,my_results=results)
165
+ File.open(my_file,"w") { |f| f << my_results }
166
+ end
167
+
168
+ #
169
+ # Like Report#write, but will append to a file rather than overwrite it if
170
+ # the file already exists.
171
+ #
172
+ def append(my_file=file)
173
+ File.open(my_file,"a") { |f| f << results }
174
+ end
175
+
176
+ # This method passes <tt>self</tt> to Report.run.
172
177
  #
173
- # Provides a nice way to execute templates and filters.
178
+ # Please see the class method for details.
179
+ #
180
+ def run(options={},&block)
181
+ options[:reports] ||= [self]
182
+ self.class.run(options,&block)
183
+ end
184
+
185
+ #
186
+ # Loads a CSV in from a file.
174
187
  #
175
188
  # Example:
176
189
  #
177
- # process_text "_<%= @some_internal_var %>_", :filters => [:erb,:red_cloth]
190
+ # my_table = load_csv "foo.csv" #=> Data::Table
191
+ # my_array = load_csv "foo.csv", :as => :array #=> Array
178
192
  #
179
- # This method automatically passes a binding into the filters, so you are
180
- # free to access data from your Report instance in your templates.
193
+ # See also Ruport::Data::Table.load
181
194
  #
182
- def process_text(string, options)
183
- options[:filters].each do |f|
184
- format = Format.new(binding)
185
- format.content = string
186
- string = format.send("filter_#{f}")
195
+ def load_csv(file,options={})
196
+ case options[:as]
197
+ when :array
198
+ a = []
199
+ Data::Table.load(file,options) { |s,r| a << r } ; a
200
+ else
201
+ Data::Table.load(file,options)
187
202
  end
188
- string
189
203
  end
190
-
204
+
191
205
  #
192
- # This allows you to create filters to be used by process_text.
206
+ # Executes an erb template. If a filename is given which matches the
207
+ # pattern /\.r\w+$/ (eg foo.rhtml, bar.rtxt, etc),
208
+ # it will be loaded and evaluated. Otherwise, the string will be processed
209
+ # directly.
193
210
  #
194
- # The block is evaluated in the context of the instance.
211
+ # Examples:
195
212
  #
196
- # Example:
213
+ # @foo = 'greg'
214
+ # erb "My name is <%= @foo %>" #=> "My name is greg"
197
215
  #
198
- # text_processor(:unix_newlines) { |r| r.gsub(/\r\n/,"\n") }
216
+ # erb "foo.rhtml" #=> contents of evaluated text in foo.rhtml
199
217
  #
200
- def text_processor(label,&block)
201
- Format.register_filter(label, &block)
218
+ def erb(s)
219
+ if s =~ /\.r\w+$/
220
+ ERB.new(File.read(s)).result(binding)
221
+ else
222
+ ERB.new(s).result(binding)
223
+ end
202
224
  end
203
225
 
226
+ # uses RedCloth to turn a string containing textile markup into HTML.
204
227
  #
205
- # Writes the contents of <tt>results</tt> to a file. If a filename is
206
- # specified, it will use it. Otherwise, it will try to write to the file
207
- # specified by the <tt>file</tt> attribute.
228
+ # Example:
208
229
  #
209
- def write(my_file=file,my_results=results)
210
- File.open(my_file,"w") { |f| f << my_results }
230
+ # textile "*bar*" #=> "<p><strong>foo</strong></p>"
231
+ #
232
+ def textile(s)
233
+ require "redcloth"
234
+ RedCloth.new(s).to_html
211
235
  end
212
-
236
+
213
237
  #
214
- # Like Report#write, but will append to a file rather than overwrite it if
215
- # the file already exists.
238
+ # Allows logging and other fun stuff.
239
+ # See also Ruport.log
216
240
  #
217
- def append(my_file=file)
218
- File.open(my_file,"a") { |f| f << results }
241
+ def log(*args); Ruport.log(*args) end
242
+
243
+ #
244
+ # Creates a new Mailer and sets the <tt>to</tt> attribute to the addresses
245
+ # specified. Yields a Mailer object, which can be modified before delivery.
246
+ #
247
+ def send_to(adds)
248
+ m = Mailer.new
249
+ m.to = adds
250
+ yield(m)
251
+ m.send(:select_mailer,@mailer)
252
+ m.deliver :from => m.from, :to => m.to
219
253
  end
220
-
254
+
255
+ def_delegators Ruport::Config, :source, :mailer, :log_file, :log_file=
256
+
221
257
  class << self
222
258
 
223
259
  #
@@ -252,6 +288,11 @@ module Ruport
252
288
  #
253
289
  # Finally, it tries to call cleanup.
254
290
  #
291
+ # This method will return the contents of Report#results, as a single
292
+ # value for single reports, and an array of outputs for multiple reports.
293
+
294
+ private :prepare, :generate, :cleanup
295
+
255
296
  def run(options={})
256
297
  options[:reports] ||= [self.new]
257
298
 
@@ -275,62 +316,19 @@ module Ruport
275
316
  else
276
317
  process.call
277
318
  end
319
+
320
+ outs = options[:reports].map { |r| r.results }
321
+ if outs.length == 1
322
+ outs.last
323
+ else
324
+ outs
325
+ end
326
+
278
327
  end
279
328
 
280
329
  end
281
330
 
282
- #
283
- # This method passes <tt>self</tt> to Report.run.
284
- #
285
- # Please see the class method for details.
286
- #
287
- def run(options={},&block)
288
- options[:reports] ||= [self]
289
- self.class.run(options,&block)
290
- end
291
-
292
- #
293
- # Loads a CSV in from a file.
294
- #
295
- # Example:
296
- #
297
- # my_table = load_csv "foo.csv" #=> Data::Table
298
- # my_array = load_csv "foo.csv", :as => :array #=> Array
299
- #
300
- # See also Ruport::Data::Table.load
301
- #
302
- def load_csv(file,options={})
303
- case options[:as]
304
- when :array
305
- a = []
306
- Data::Table.load(file,options) { |s,r| a << r } ; a
307
- else
308
- Data::Table.load(file,options)
309
- end
310
- end
311
-
312
- #
313
- # Allows logging and other fun stuff.
314
- # See also Ruport.log
315
- #
316
- def log(*args); Ruport.log(*args) end
317
-
318
- #
319
- # Creates a new Mailer and sets the <tt>to</tt> attribute to the addresses
320
- # specified. Yields a Mailer object, which can be modified before delivery.
321
- #
322
- def send_to(adds)
323
- m = Mailer.new
324
- m.to = adds
325
- yield(m)
326
- m.send(:select_mailer,@mailer)
327
- m.deliver :from => m.from, :to => m.to
328
- end
329
-
330
- def_delegators Ruport::Config, :source, :mailer, :log_file, :log_file=
331
-
332
331
  end
333
-
334
332
  end
335
333
 
336
334
 
@@ -24,7 +24,7 @@
24
24
  # This is Free Software. See LICENSE and COPYING for details.
25
25
 
26
26
  module Ruport
27
- module SystemExtensions
27
+ module SystemExtensions #:nodoc:
28
28
  module_function
29
29
 
30
30
  #
@@ -57,7 +57,8 @@ module Ruport
57
57
  rescue LoadError # If we're not on Windows try...
58
58
  # A Unix savvy method to fetch the console columns, and rows.
59
59
  def terminal_size
60
- `stty size`.split.map { |x| x.to_i }.reverse
60
+ size = `stty size 2>/dev/null`.split.map { |x| x.to_i }.reverse
61
+ return $? == 0 ? size : [80,24]
61
62
  end
62
63
 
63
64
  end
@@ -66,9 +67,5 @@ module Ruport
66
67
  terminal_size.first
67
68
  end
68
69
 
69
- def terminal_height
70
- terminal_size.last
71
- end
72
-
73
70
  end
74
71
  end