ruport 0.4.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS CHANGED
@@ -1,14 +1,9 @@
1
1
  Developers:
2
2
  ---------------------------------------------------
3
- {Gregory Brown}[mailto:gregory.t.brown@gmail.com]:
4
3
 
5
- Original Author and Ruport::Report hacker.
4
+ {Gregory Brown}[mailto:gregory.t.brown@gmail.com]
6
5
 
7
- {Robert Canieso}[mailto:rcanieso@gmail.com]:
8
-
9
- Currently lurking. Soon to be tester / developer
10
-
11
- Contributors / People we've stole from:
6
+ Contributors / People we've (legally) stole from:
12
7
  ---------------------------------------------------
13
8
 
14
9
  James Edward Gray II:
data/CHANGELOG CHANGED
@@ -1,7 +1,24 @@
1
- The current version of Ruby Reports is 0.4.0
1
+ The current version of Ruby Reports is 0.4.2
2
+
3
+ changes since 0.4.0:
4
+
5
+ - Brand new formatting system.
6
+ See: http://ruport.infogami.com/Formatting_System_HOWTO
7
+
8
+ - DataSet#<< now returns self, e.g.
9
+ some_data << [1,2,3] << [4,5,6]
10
+
11
+ - Removed fascist opt_require feature and Ruport::Base
12
+
13
+ - Fixed bug in DataRow constructor which destroyed arrays.
14
+
15
+ - Examples now included in gems
2
16
 
3
17
  changes since 0.3.8:
4
18
 
19
+
20
+ - added DataRow#to_h
21
+
5
22
  - Ruport::Format.register_filter now passes the content it will modify via a
6
23
  block. e.g.
7
24
 
@@ -9,7 +26,7 @@ changes since 0.3.8:
9
26
 
10
27
  - Modified the license terms of Ruport so that it uses specifically the GPLv2.
11
28
  Further versions of Ruport may not be distributed under later versions of the
12
- GPL without expressed permission.
29
+ GPL without explicit permission.
13
30
 
14
31
  - DataSet#[]= now passes rvals to DataRow constructor with fields from the
15
32
  DataSet it is called on.
data/LICENSE CHANGED
@@ -7,7 +7,7 @@ or the {Ruby software license}[http://www.ruby-lang.org/en/LICENSE.txt].
7
7
  Please email Greg[mailto:gregory.t.brown_AT_gmail.com] with any questions.
8
8
 
9
9
  *Note: This license refers specifically to GPLv2.
10
- Distributing under later versions of the GPL require explicit permission from
10
+ Distributing under other versions of the GPL require explicit permission from
11
11
  Gregory Brown. Though we will most likely adopt the GPLv3 when the final draft
12
12
  is published, we want to be able to make that decision for ourselves.
13
13
 
data/README CHANGED
@@ -1,6 +1,11 @@
1
1
  # ------------------------------------------------------------------------
2
2
  # -------------------------------------------------------------------------
3
3
  #
4
+ # WARNING: THIS DOCUMENT IS FREQUENTLY OUT OF DATE.
5
+ #
6
+ # The most up to date information can be found at:
7
+ # http://reporting.stonecode.org
8
+ #
4
9
  # Contents:
5
10
  #
6
11
  # - What Ruport Is.
@@ -21,12 +26,12 @@
21
26
  #
22
27
  # Optional Dependencies:
23
28
  #
24
- # Ruport has a number of optional dependencies:
29
+ # Ruport has a number of dependencies:
25
30
  #
26
31
  # Ruby/DBI and appropriate dbds: Makes Query useable
27
32
  # (must be installed manually)
28
33
  #
29
- # FasterCSV: Silently enables fast CSV parsing
34
+ # FasterCSV: Enables fast CSV parsing
30
35
  # (available via rubygems)
31
36
  #
32
37
  # RedCloth: Enables textile/markdown filtering
@@ -35,25 +40,14 @@
35
40
  # PDF::Writer: Enables printable documents via render_pdf (Experimental)
36
41
  # (available via rubygems)
37
42
  #
38
- # The recommended method of installing ruport is RubyGems. It has been
39
- # split into two packages, one that installs all of the dependencies
40
- # by default, and one which does not install them.
41
- #
42
- # None of the dependencies are mandatory, so you can still use Ruport
43
- # without them, as long as you don't need their functionality.
43
+ # Note that by installing any of the dependencies, either via gems or manually,
44
+ # their functionality will automatically be enabled.
44
45
  #
45
46
  # To install ruport via rubygems with all it's dependencies (except DBI):
46
47
  #
47
48
  # sudo gem install ruport
48
49
  #
49
- # To install ruport via rubygems with no dependencies:
50
- #
51
- # sudo gem install ruport-lean
52
- #
53
- # Note that by installing any of the dependencies, either via gems or manually,
54
- # their functionality will automatically be enabled in ruport-lean.
55
- #
56
- # To install ruport manually:
50
+ # To install ruport manually via setup.rb:
57
51
  #
58
52
  # sudo ruby setup.rb
59
53
  #
@@ -103,8 +97,6 @@
103
97
  # documentation, as well as encouraging design discussions and also am quite
104
98
  # curious about what people use or want to use ruport for.
105
99
  #
106
- # Ruby Reports (Ruport) is a report generation and formatting toolset.
107
- #
108
100
  # I will announce Ruport releases on RubyTalk, on the Ruport mailing list, on
109
101
  # Freshmeat, RAA, and the new_haven.rb mailing list. If you would like to
110
102
  # keep an eye out for releases, please monitor one of those places.
@@ -115,16 +107,8 @@
115
107
  # - The latest stable API documentation is available at:
116
108
  # http://ruport.rubyforge.org/docs
117
109
  #
118
- # - If you'd like to get some news on Ruport, you can check out my blog.
119
- # (http://stonecode.org/blog)
120
- #
121
110
  # There also will be some tutorials on stonecode.org
122
111
  #
123
- # From time to time I will release example packages on RubyForge. Keep an eye
124
- # out for these on ruport's project page and please note that unless otherwise
125
- # noted, these examples are meant ONLY for the versions which they correspond
126
- # to. (i.e. ruport-example-0.2.9 will NOT work with Ruport 0.3.8)
127
- #
128
112
  # If you are interested in developing Ruport, please *never* study code in
129
113
  # official releases. As this software is in it's early stages, it's essential
130
114
  # to keep an eye on the subversion repository. If you let me know you are
@@ -133,7 +117,7 @@
133
117
  #
134
118
  # - Grabbing the code from the svn trunk is simple:
135
119
  #
136
- # svn checkout svn://rubyforge.org//var/svn/ruport
120
+ # svn co svn://rubyforge.org//var/svn/ruport/trunk/
137
121
  #
138
122
  # Those who would like to become regular contributors will be given write
139
123
  # access. Also, anyone interested in the internal design and project
@@ -164,8 +148,7 @@
164
148
  # methods to help you write a Reporting application
165
149
  #
166
150
  # Format provides support for building filters and specialized formatting
167
- # systems. Format::Builder can be used to add additional formats which can be
168
- # used by DataSet#as, and the Format class can add filters to Report#render
151
+ # systems.
169
152
  #
170
153
  # Query currently provides a high level interface to DBI. Soon it will support
171
154
  # a mixin wrapper called Fetchable which will enable you to wrap whatever data
data/Rakefile CHANGED
@@ -2,8 +2,13 @@ require "rake/rdoctask"
2
2
  require "rake/testtask"
3
3
  require "rake/gempackagetask"
4
4
 
5
- require "rubygems"
5
+ begin
6
+ require "rubygems"
7
+ rescue LoadError
8
+ nil
9
+ end
6
10
 
11
+ #Set to true to disable dependency resolution
7
12
  LEAN=false
8
13
 
9
14
  task :default => [:test]
@@ -16,14 +21,13 @@ end
16
21
 
17
22
  spec = Gem::Specification.new do |spec|
18
23
  spec.name = LEAN ? "ruport-lean" : "ruport"
19
- spec.version = "0.4.0"
24
+ spec.version = "0.4.2"
20
25
  spec.platform = Gem::Platform::RUBY
21
26
  spec.summary = "A generalized Ruby report generation and templating engine."
22
-
23
- spec.files = spec.files = FileList[
24
- 'lib/**/*.rb', 'bin/*', '[A-Z]*','test/**/*'].to_a.delete_if { |item|
25
- item.include?("CVS") } + ["Rakefile"]
26
- spec.require_path = "lib"
27
+ spec.files = Dir.glob("{examples,lib,test}/**/*.rb") +
28
+ ["Rakefile", "setup.rb"]
29
+
30
+ spec.require_path = "lib"
27
31
 
28
32
  spec.test_file = "test/ts_all.rb"
29
33
 
data/TODO CHANGED
@@ -2,9 +2,27 @@ TODO: (Wiped clean for a fresh start as of 2006.02.20)
2
2
 
3
3
  Immediate Goals:
4
4
 
5
+ Bugs:
6
+
7
+ - The engine doesn't have a good way to give you cloned copies of the
8
+ Plugins meaningfully
9
+
5
10
  Features:
6
11
 
7
- - Make DataSet an XSet
12
+ - event system
13
+
14
+ - Add in a way to load partial datasets
15
+
16
+ - allow DataSet creation without field names.
17
+
18
+ - Builder should have a no-fields option
19
+
20
+ - Composite key selection
21
+
22
+ - Value modification predicate.
23
+ DataRow#set_value_if("my_value") { # my_condition }
24
+
25
+ - Column based default values
8
26
 
9
27
  - Integrate Ruport::Parser into Report#parse and Format#parser
10
28
 
@@ -0,0 +1,10 @@
1
+ require "ruport"
2
+ include Ruport
3
+
4
+
5
+ class Format::Plugin::FieldlessCSVPlugin < Format::Plugin::CSVPlugin
6
+ rendering_options :show_field_names => false
7
+ plugin_name :fieldless_csv
8
+ register_on :table_engine
9
+ end
10
+
@@ -0,0 +1,44 @@
1
+ require "ruport"
2
+
3
+ include Ruport
4
+
5
+ class LinePlotter < Format::Engine
6
+
7
+ Line = Struct.new(:x1,:y1,:x2,:y2)
8
+
9
+ renderer do
10
+ active_plugin.data = get_lines
11
+ active_plugin.render_plot
12
+ end
13
+
14
+ def self.get_lines
15
+ data.map { |r| Line.new(r[0][0],r[0][1],r[1][0],r[1][1]) }
16
+ end
17
+
18
+ alias_engine LinePlotter, :line_plotting_engine
19
+ Format.build_interface_for LinePlotter, :plot
20
+ end
21
+
22
+ class SVG < Format::Plugin
23
+
24
+ renderer :plot do
25
+ h = '<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">'+
26
+ '<g stroke="black" stroke-width="1">'
27
+
28
+ data.inject(h) { |s,r|
29
+ s << "<line x1=\"#{r.x1}\" y1=\"#{r.y1}\"" <<
30
+ " x2=\"#{r.x2}\" y2=\"#{r.y2}\" />"
31
+ } << "</g></svg>"
32
+ end
33
+
34
+ register_on :line_plotting_engine
35
+ end
36
+
37
+ lines = [ [ [0,0], [0,100] ],
38
+ [ [0,100], [100,100] ],
39
+ [ [100,100], [100,0] ],
40
+ [ [100,0], [0,0] ] ]
41
+
42
+ a = Format.plot :plugin => :svg,
43
+ :data => lines
44
+ puts a
@@ -0,0 +1,21 @@
1
+ require "rubygems"
2
+ require "ruport"
3
+
4
+ include Ruport
5
+
6
+ class Format::Plugin::Text < Ruport::Format::Plugin
7
+ renderer :table do
8
+ data.inject(rendered_field_names) { |s,r|
9
+ s << r.to_a.join("()") << "\n"
10
+ }
11
+ end
12
+
13
+ format_field_names do
14
+ data.fields.join("---") << "\n"
15
+ end
16
+
17
+ register_on :table_engine
18
+ end
19
+
20
+ puts Format.table({ :data => [[1,2],[3,4]].to_ds(%w[a b]),
21
+ :plugin => :text })
data/examples/pdf.rb ADDED
@@ -0,0 +1,36 @@
1
+ require "rubygems"
2
+ require "ruport"
3
+
4
+ # needs a DSL, but heres a sort of Raw support here.
5
+ # will improve when linked into the new plugin system
6
+
7
+ element = Ruport::Format::Element.new :e,
8
+ :content => "Hello Ruport PDF rendering!",
9
+ :top => 2, :left => 4, :right => 4
10
+
11
+ element2 = Ruport::Format::Element.new :e2,
12
+ :content => File.read("examples/long.txt"),
13
+ :top => 20, :left => 2, :right => 2
14
+
15
+ section = Ruport::Format::Section.new :s
16
+ section << element
17
+
18
+ section2 = Ruport::Format::Section.new :s2
19
+ section2 << element2
20
+
21
+ page = Ruport::Format::Section.new :p
22
+ page << section
23
+
24
+ page2 = Ruport::Format::Page.new :p2
25
+ page2 << section2
26
+
27
+ document = Ruport::Format::Document.new :d
28
+
29
+ document << page
30
+ document << page2
31
+
32
+
33
+ pdf_builder = Ruport::Format::Builder.new(document)
34
+ pdf_builder.format = :pdf_document
35
+
36
+ puts pdf_builder.render
data/lib/ruport.rb CHANGED
@@ -1,4 +1,3 @@
1
- begin; require "rubygems"; rescue LoadError; nil; end
2
1
  # ruport.rb : Ruby Reports toplevel module
3
2
  #
4
3
  # Author: Gregory T. Brown (gregory.t.brown at gmail dot com)
@@ -12,7 +11,10 @@ begin; require "rubygems"; rescue LoadError; nil; end
12
11
  #
13
12
 
14
13
  module Ruport
15
- VERSION = "Ruby Reports Version 0.4.0"
14
+
15
+ begin; require 'rubygems'; rescue LoadError; nil end
16
+
17
+ VERSION = "Ruby Reports Version 0.4.2"
16
18
 
17
19
  # Ruports logging and error interface.
18
20
  # Can generate warnings or raise fatal errors
@@ -54,6 +56,6 @@ module Ruport
54
56
  end
55
57
 
56
58
 
57
- %w[base config report format query data_row data_set].each { |lib|
59
+ %w[config report format query data_row data_set].each { |lib|
58
60
  require "ruport/#{lib}"
59
61
  }
@@ -55,6 +55,7 @@ module Ruport
55
55
 
56
56
  #checks to ensure data is convertable
57
57
  verify data
58
+ data = data.dup
58
59
 
59
60
  @fields = fields.dup
60
61
  @tags = (options[:tags] || {}).dup
@@ -84,7 +84,7 @@ module Ruport
84
84
  def clone
85
85
  DataSet.new(@fields,@data)
86
86
  end
87
-
87
+
88
88
  #Allows ordinal access to rows
89
89
  #
90
90
  # my_data[2] -> Ruport::DataRow
@@ -105,7 +105,7 @@ module Ruport
105
105
  # data << [ 1, 2, 3 ]
106
106
  # data << { :some_field_name => 3, :other => 2, :another => 1 }
107
107
  def << ( stuff, filler=@default )
108
- @data << DataRow.new(stuff,@fields,:filler => filler)
108
+ @data << DataRow.new(stuff,@fields,:filler => filler); self;
109
109
  end
110
110
 
111
111
  # checks if one dataset equals another
data/lib/ruport/format.rb CHANGED
@@ -8,7 +8,6 @@
8
8
  # your choice of the GNU General Public License or the Ruby License.
9
9
  #
10
10
  # See LICENSE and COPYING for details
11
- %w[builder open_node document].each { |lib| require "ruport/format/#{lib}" }
12
11
  begin; require "faster_csv"; rescue LoadError; require "csv"; end
13
12
  module Ruport
14
13
 
@@ -60,13 +59,42 @@ module Ruport
60
59
  #
61
60
  # This part of Ruport is under active development. Please do feel free to
62
61
  # submit feature requests or suggestions.
63
- class Format < Ruport::Base
62
+ class Format
63
+
64
+ def Format.build_interface_for(engine,name)
65
+ (class << self; self; end).send(:define_method, name,
66
+ lambda { |options| simple_interface(engine, options) })
67
+ (class << self; self; end).send(:define_method, "#{name}_object",
68
+ lambda { |options|
69
+ options[:auto_render] = false; simple_interface(engine,options) })
70
+ end
71
+
72
+ %w[builder open_node document engine plugin].each { |lib|
73
+ require "ruport/format/#{lib}"
74
+ }
75
+
76
+ class << self
77
+
78
+ def simple_interface(engine, options={})
79
+ my_engine = engine.dup
80
+
81
+ my_engine.send(:plugin=,options[:plugin])
82
+ options = my_engine.active_plugin.rendering_options.merge(options)
83
+
84
+ options[:auto_render] = true unless options.has_key? :auto_render
85
+
86
+ options.each do |k,v|
87
+ my_engine.send("#{k}=",v) if my_engine.respond_to? k
88
+ end
89
+
90
+ options[:auto_render] ? my_engine.render : my_engine
91
+ end
92
+
93
+ end
64
94
 
65
95
  @@filters = Hash.new
66
96
 
67
- opt_require "redcloth", :filter_red_cloth
68
-
69
- # To hook up a Format object to your current class, you need to pass it a
97
+ # To hook up a Format object to your current class, you need to pass it a
70
98
  # binding. This way, when filters are being processed, they will be
71
99
  # evaluated in the context of the object they are being called from, rather
72
100
  # than within an instance of Format.
@@ -90,6 +118,7 @@ module Ruport
90
118
  # Processes the RedCloth text in <tt>@content</tt> in the context
91
119
  # of the object that Format is bound to.
92
120
  def filter_red_cloth
121
+ require "redcloth"
93
122
  RedCloth.new(@content).to_html
94
123
  end
95
124