ruport 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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
data/AUTHORS CHANGED
@@ -35,3 +35,9 @@ Daniel Berger:
35
35
  Marshall T. Vandegrift:
36
36
  - Fixed a bug in Record's struct-like accessors (method_missing)
37
37
  - Provided performance enhancements and tests for query.rb
38
+
39
+ Stefan Mahlitz:
40
+ - Table#sort_rows_by
41
+
42
+ llasram@gmail.com
43
+ - Improved alignment for Text Tables.
data/Rakefile CHANGED
@@ -23,10 +23,10 @@ end
23
23
 
24
24
  spec = Gem::Specification.new do |spec|
25
25
  spec.name = LEAN ? "lean-ruport" : "ruport"
26
- spec.version = "0.6.1"
26
+ spec.version = "0.7.0"
27
27
  spec.platform = Gem::Platform::RUBY
28
28
  spec.summary = "A generalized Ruby report generation and templating engine."
29
- spec.files = Dir.glob("{examples,lib,test,bin}/**/**/**/*") +
29
+ spec.files = Dir.glob("{examples,lib,test,bin}/**/**/*") +
30
30
  ["Rakefile", "setup.rb"]
31
31
 
32
32
  spec.require_path = "lib"
@@ -35,7 +35,7 @@ spec = Gem::Specification.new do |spec|
35
35
  spec.bindir = "bin"
36
36
  spec.executables = FileList["rope"]
37
37
  spec.has_rdoc = true
38
- spec.extra_rdoc_files = %w{README LICENSE TODO AUTHORS CHANGELOG}
38
+ spec.extra_rdoc_files = %w{README LICENSE TODO AUTHORS}
39
39
  spec.rdoc_options << '--title' << 'Ruport Documentation' <<
40
40
  '--main' << 'README' << '-q'
41
41
  unless LEAN
@@ -43,7 +43,7 @@ spec = Gem::Specification.new do |spec|
43
43
  spec.add_dependency('RedCloth', '>= 3.0.0')
44
44
  spec.add_dependency('pdf-writer', '>= 1.1.3')
45
45
  spec.add_dependency("mailfactory", ">= 1.2.2")
46
- spec.add_dependency("scruffy", ">= 0.2.2")
46
+ spec.add_dependency('scruffy', '>= 0.2.2')
47
47
  end
48
48
  spec.author = "Gregory Brown"
49
49
  spec.email = " gregory.t.brown@gmail.com"
data/TODO CHANGED
@@ -1,4 +1,5 @@
1
1
  = TODO
2
2
 
3
- Any future plans are available on Ruports Trac website
4
- = http://stonecode.svnrepository.com/ruport/trac.cgi
3
+ - Any future plans are available on Ruport's Trac website
4
+
5
+ http://stonecode.svnrepository.com/ruport/trac.cgi
data/bin/rope CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
-
3
2
  require "fileutils"
3
+ require "ruport/generator"
4
4
  include FileUtils
5
5
 
6
6
  if ARGV.empty?
@@ -9,105 +9,4 @@ if ARGV.empty?
9
9
  end
10
10
  project = ARGV[0]
11
11
 
12
- RAKEFILE = <<END_RAKEFILE
13
- begin; require "rubygems"; rescue LoadError; end
14
- require "rake/testtask"
15
-
16
- task :default => [:test]
17
-
18
- Rake::TestTask.new do |test|
19
- test.libs << "test"
20
- test.pattern = 'test/**/test_*.rb'
21
- test.verbose = true
22
- end
23
- END_RAKEFILE
24
-
25
- CONFIG = <<END_CONFIG
26
- require "ruport"
27
-
28
- # For details, see Ruport::Config documentation
29
- Ruport.configure { |c|
30
- c.source :default, :user => "root",
31
- :dsn => "dbi:mysql:mydb"
32
- c.log_file "log/ruport.log"
33
- }
34
- END_CONFIG
35
-
36
- BUILD = <<'END_BUILD'
37
- def format_class_name(string)
38
- string.downcase.split("_").map { |s| s.capitalize }.join
39
- end
40
-
41
- unless ARGV.length > 1
42
- puts "usage build.rb [command] [options]"
43
- exit
44
- end
45
-
46
- class_name = format_class_name(ARGV[1])
47
-
48
- exit if File.exist? "app/reports/#{ARGV[1]}.rb"
49
- if ARGV[0].eql? "report"
50
- File.open("app/reports.rb", "a") { |f|
51
- f.puts("require \"app/reports/#{ARGV[1]}\"")
52
- }
53
- REP = <<EOR
54
- begin; require "rubygems"; rescue LoadError; end
55
- require "ruport"
56
- require "config/ruport_config"
57
-
58
- class #{class_name} < Ruport::Report
59
-
60
- #optional
61
- prepare { }
62
-
63
- #mandatory
64
- generate { }
65
-
66
- #optional
67
- cleanup { }
68
-
69
- end
70
-
71
- # uncomment the line below to let the report be run directly
72
- #
73
- # if __FILE__ == $0
74
- # #{class_name}.run { |res| puts res.results }
75
- # end
76
- EOR
77
-
78
- TEST = <<EOR
79
- begin; require "rubygems"; rescue LoadError; end
80
- require "ruport"
81
- require "test/unit"
82
- require "app/reports/#{ARGV[1]}"
83
- require "config/ruport_config"
84
-
85
- class Test#{class_name} < Test::Unit::TestCase
86
- def test_flunk
87
- flunk "Write your real tests here or in any test/test_* file"
88
- end
89
- end
90
- EOR
91
- File.open("app/reports/#{ARGV[1]}.rb", "w") { |f| f << REP }
92
- File.open("test/test_#{ARGV[1]}.rb","w") { |f| f << TEST }
93
- end
94
- END_BUILD
95
-
96
- SQL_EXEC = <<'END_SQL'
97
- begin; require "rubygems"; rescue LoadError; end
98
- require "ruport"
99
- require "config/ruport_config"
100
-
101
- puts Ruport::Query.new(ARGF.read).result
102
- END_SQL
103
-
104
- mkdir project
105
- %w[test config output data app app/reports templates sql log util].each do |d|
106
- mkdir "#{project}/#{d}"
107
- end
108
-
109
- touch("#{project}/app/reports.rb")
110
- File.open("#{project}/config/ruport_config.rb","w") { |f| f << CONFIG }
111
- File.open("#{project}/Rakefile","w") { |f| f << RAKEFILE }
112
- File.open("#{project}/util/build.rb","w") { |f| f << BUILD }
113
- File.open("#{project}/util/sql_exec.rb","w") { |f| f << SQL_EXEC }
12
+ Ruport::Generator.build(ARGV[0])
@@ -0,0 +1,53 @@
1
+ require "ruport"
2
+
3
+ module MyStuff
4
+
5
+ class DocumentRenderer < Ruport::Renderer
6
+ include Ruport::Renderer::Helpers
7
+
8
+ def run
9
+ build [:header,:body,:footer],:document
10
+ finalize :document
11
+ end
12
+
13
+ def table=(t)
14
+ options.table = t
15
+ end
16
+
17
+ def header_text=(t)
18
+ options.header_text=(t)
19
+ end
20
+
21
+ def footer_text=(t)
22
+ options.footer_text=(t)
23
+ end
24
+
25
+ end
26
+
27
+ class PDF < Ruport::Format::PDF
28
+ DocumentRenderer.add_format self, :pdf
29
+
30
+ def build_document_header
31
+ add_text options.header_text, :justification => :center
32
+ end
33
+
34
+ def build_document_body
35
+ pad(10) { draw_table }
36
+ end
37
+
38
+ def build_document_footer
39
+ add_text options.footer_text, :justification => :center
40
+ end
41
+
42
+ def finalize_document
43
+ output << pdf_writer.render
44
+ end
45
+
46
+ end
47
+ end
48
+
49
+ puts MyStuff::DocumentRenderer.render_pdf { |e|
50
+ e.data = [[1,2],[3,4]].to_table(%w[apple banana])
51
+ e.header_text = "foo"
52
+ e.footer_text = "bar"
53
+ }
data/lib/ruport/config.rb CHANGED
@@ -161,16 +161,12 @@ module Ruport
161
161
  def logger; @logger; end
162
162
 
163
163
  # Forces all messages marked <tt>:log_only</tt> to print anyway.
164
- def enable_paranoia; @paranoid = true; end
164
+ # def enable_paranoia; @paranoid = true; end
165
165
 
166
166
  # Disables the printing of <tt>:log_only</tt> messages.
167
- def disable_paranoia; @paranoid = false; end
167
+ #def disable_paranoia; @paranoid = false; end
168
168
 
169
- # Sets paranoid status.
170
- def paranoid=(val); @paranoid = val; end
171
-
172
- # Checks to see if paranoia is enabled.
173
- def paranoid?; !!@paranoid; end
169
+ def debug_mode?; !!@debug_mode; end
174
170
 
175
171
  # Verifies that you have provided a DSN for your source.
176
172
  def check_source(settings,label) # :nodoc:
@@ -193,6 +189,10 @@ module Ruport
193
189
  )
194
190
  end
195
191
  end
192
+
193
+ def debug_mode=(something)
194
+ @debug_mode = !!something
195
+ end
196
196
 
197
197
  end
198
198
  end
@@ -18,8 +18,8 @@ module Ruport::Data
18
18
  extend Forwardable
19
19
  include Enumerable
20
20
  include Taggable
21
-
22
- def initialize(data=nil,options={})
21
+
22
+ def initialize(data=nil,options={}) #:nodoc:
23
23
  @data = data.dup if data
24
24
  end
25
25
 
@@ -29,9 +29,10 @@ module Ruport::Data
29
29
  # Example:
30
30
  # my_collection.as(:csv) #=> "1,2,3\n4,5,6"
31
31
  def as(type)
32
- eng = Ruport::Format.table_object :data => self, :plugin => type
33
- yield(eng) if block_given?
34
- eng.render
32
+ Ruport::Renderer::Table.render(type) do |rend|
33
+ rend.data = self
34
+ yield(rend) if block_given?
35
+ end
35
36
  end
36
37
 
37
38
  # Converts a <tt>Collection</tt> object to a <tt>Data::Set</tt>.
@@ -47,8 +48,8 @@ module Ruport::Data
47
48
  # Provides a shortcut for the <tt>as()</tt> method by converting a call to
48
49
  # <tt>as(:format_name)</tt> into a call to <tt>to_format_name</tt>
49
50
  def method_missing(id,*args)
50
- return as($1.to_sym) if id.to_s =~ /^to_(.*)/
51
- super
51
+ return as($1.to_sym) if id.to_s =~ /^to_(.*)/
52
+ super
52
53
  end
53
54
 
54
55
  attr_reader :data
@@ -44,7 +44,9 @@ module Ruport::Data
44
44
  r_tags = map { |r| r.tags }.flatten.uniq
45
45
  tables_hash = Hash.new { |h,k| h[k] = [].to_table(column_names) }
46
46
  each { |row|
47
- row.tags.each { |t| tables_hash[t] << row }
47
+ row.tags.each { |t|
48
+ tables_hash[t].instance_variable_get(:@data) << row
49
+ }
48
50
  }
49
51
  r = Record.new tables_hash, :attributes => r_tags
50
52
  class << r
@@ -74,7 +76,6 @@ module Ruport::Data
74
76
  #
75
77
  def create_tag_group(label,&block)
76
78
  each { |r| block[r] && r.tag(label) }
77
- #select(&block).each { |r| r.tag label }
78
79
  end
79
80
  alias_method :tag_group, :create_tag_group
80
81
 
@@ -55,11 +55,7 @@ module Ruport::Data
55
55
  end
56
56
  else
57
57
  @data = data.dup
58
- @attributes = if options[:attributes]
59
- options[:attributes]
60
- else
61
- []
62
- end
58
+ @attributes = options[:attributes] || []
63
59
  end
64
60
  end
65
61
 
@@ -81,8 +77,9 @@ module Ruport::Data
81
77
  raise "Invalid index" unless index < @data.length
82
78
  @data[index]
83
79
  else
84
- raise "Invalid index" unless attributes.index(index.to_s)
85
- @data[attributes.index(index.to_s)]
80
+ index = index.to_s
81
+ raise "Invalid index" unless attributes.index(index)
82
+ @data[attributes.index(index)]
86
83
  end
87
84
  end
88
85
 
@@ -100,8 +97,9 @@ module Ruport::Data
100
97
  raise "Invalid index" unless index < @data.length
101
98
  @data[index] = value
102
99
  else
103
- raise "Invalid index" unless attributes.index(index.to_s)
104
- @data[attributes.index(index.to_s)] = value
100
+ index = index.to_s
101
+ raise "Invalid index" unless @attributes.index(index)
102
+ @data[attributes.index(index)] = value
105
103
  end
106
104
  end
107
105
 
@@ -110,9 +108,9 @@ module Ruport::Data
110
108
  # <tt>==</tt> evaluates to true. Otherwise, <tt>==</tt> returns false.
111
109
  #
112
110
  def ==(other)
113
- return false if attributes && !other.attributes
114
- return false if other.attributes && !attributes
115
- attributes == other.attributes && @data == other.data
111
+ return false if @attributes && !other.attributes
112
+ return false if other.attributes && !@attributes
113
+ @attributes == other.attributes && @data == other.data
116
114
  end
117
115
 
118
116
  alias_method :eql?, :==
@@ -135,8 +133,7 @@ module Ruport::Data
135
133
  #
136
134
  # a = Data::Record.new([1,2],:attributes => %w[a b])
137
135
  # a.to_h #=> {"a" => 1, "b" => 2}
138
- #
139
- def to_h; Hash[*attributes.zip(data).flatten] end
136
+ def to_h; Hash[*@attributes.zip(data).flatten] end
140
137
 
141
138
  #
142
139
  # Returns a copy of the <tt>attributes</tt> from this Record.
@@ -175,9 +172,9 @@ module Ruport::Data
175
172
  # Same as Record#reorder but modifies its reciever in place.
176
173
  def reorder!(*indices)
177
174
  indices = reorder_data!(*indices)
178
- if attributes
175
+ if @attributes
179
176
  if indices.all? { |e| e.kind_of? Integer }
180
- @attributes = indices.map { |i| attributes[i] }
177
+ @attributes = indices.map { |i| @attributes[i] }
181
178
  else
182
179
  @attributes = indices
183
180
  end
@@ -4,20 +4,6 @@
4
4
  # This is Free Software. For details, see LICENSE and COPYING
5
5
  # Copyright 2006 by respective content owners, all rights reserved.
6
6
 
7
- class Array
8
-
9
- #
10
- # Converts an array to a Ruport::Data::Table object, ready to
11
- # use in your reports.
12
- #
13
- # Example:
14
- # [[1,2],[3,4]].to_table(%w[a b])
15
- #
16
- def to_table(options={})
17
- options = { :column_names => options } if options.kind_of? Array
18
- Ruport::Data::Table.new({:data => self}.merge(options))
19
- end
20
- end
21
7
 
22
8
  module Ruport::Data
23
9
 
@@ -415,13 +401,98 @@ module Ruport::Data
415
401
 
416
402
  alias_method :sum, :sigma
417
403
 
404
+ #
405
+ # Returns a sorted table. If col_names is specified,
406
+ # the block is ignored and the table is sorted by the named columns. All
407
+ # options are used in constructing the new Table (see Array#to_table
408
+ # for details).
409
+ #
410
+ # Example:
411
+ #
412
+ # table = [[4, 3], [2, 5], [7, 1]].to_table(%w[col1 col2 ])
413
+ #
414
+ # # returns a new table sorted by col1
415
+ # table.sort_rows_by {|r| r["col1"]}
416
+ #
417
+ # # returns a new table sorted by col2
418
+ # table.sort_rows_by ["col2"]
419
+ #
420
+ # # returns a new table sorted by col1, then col2
421
+ # table.sort_rows_by ["col1", "col2"]
422
+ #
423
+ def sort_rows_by(col_names=nil, &block)
424
+ # stabilizer is needed because of
425
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/170565
426
+ stabilizer = 0
427
+
428
+ data_array =
429
+ if col_names
430
+ sort_by do |r|
431
+ stabilizer += 1
432
+ [col_names.map {|col| r[col]}, stabilizer]
433
+ end
434
+ else
435
+ sort_by(&block)
436
+ end
437
+
438
+ table =
439
+ data_array.to_table(@column_names)
440
+
441
+ table.tags = self.tags
442
+ return table
443
+ end
444
+
418
445
  end
419
446
 
420
447
  end
421
448
 
422
- module Ruport::Data::TableHelper #:nodoc:
423
- def table(names=[])
424
- t = [].to_table(names)
425
- yield(t) if block_given?; t
449
+
450
+ module Kernel
451
+
452
+ # Shortcut interface for creating Data::Tables
453
+ #
454
+ # Examples:
455
+ #
456
+ # t = Table(%w[a b c]) #=> creates a new empty table w. cols a,b,c
457
+ # t = Table("a","b","c") #=> creates a new empty table w. cols a,b,c
458
+ #
459
+ # # allows building table inside of block, returns table object
460
+ # t = Table(%w[a b c]) { |t| t << [1,2,3] }
461
+ #
462
+ # # allows loading table from CSV
463
+ # # accepts all Data::Table.load options, but block form yields table,
464
+ # # not row!
465
+ #
466
+ # t = Table("foo.csv")
467
+ # t = Table("bar.csv", :has_names => false)
468
+ def Table(*args,&block)
469
+ table=
470
+ case(args[0])
471
+ when Array
472
+ [].to_table(args[0])
473
+ when /\.csv/
474
+ Ruport::Data::Table.load(*args)
475
+ else
476
+ [].to_table(args)
477
+ end
478
+
479
+ block[table] if block
480
+
481
+ return table
482
+ end
483
+ end
484
+
485
+ class Array
486
+
487
+ #
488
+ # Converts an array to a Ruport::Data::Table object, ready to
489
+ # use in your reports.
490
+ #
491
+ # Example:
492
+ # [[1,2],[3,4]].to_table(%w[a b])
493
+ #
494
+ def to_table(column_names=nil)
495
+ Ruport::Data::Table.new({:data => self, :column_names => column_names})
426
496
  end
427
497
  end
498
+
@@ -0,0 +1,29 @@
1
+ module Ruport::Format
2
+
3
+ # This plugin implements the CSV format for tabular data output.
4
+ # See also: Renderer::Table
5
+ class CSV < Plugin
6
+
7
+ # Generates table header by turning column_names into a CSV row.
8
+ # Uses build_csv_row to generate the actual formatted output
9
+ #
10
+ # This method does not do anything if layout.show_table_headers is false or
11
+ # the Data::Table has no column names.
12
+ def build_table_header
13
+ unless data.column_names.empty? || !layout.show_table_headers
14
+ build_csv_row(data.column_names)
15
+ end
16
+ end
17
+
18
+ # Calls build_csv_row for each row in the Data::Table
19
+ def build_table_body
20
+ data.map { |r| build_csv_row(r) }.join("\n")
21
+ end
22
+
23
+ # Produces CSV output for a data row.
24
+ def build_csv_row(row)
25
+ require "fastercsv"
26
+ output << FasterCSV.generate { |csv| csv << row }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ module Ruport::Format
2
+ # Produces HTML output for tabular data.
3
+ #
4
+ # See also Renderer::Table
5
+ class HTML < Plugin
6
+
7
+ # Generates table headers based on the column names of your Data::Table.
8
+ #
9
+ # This method does not do anything if layout.show_table_headers is false or
10
+ # the Data::Table has no column names.
11
+ def build_table_header
12
+ output << "\t<table>\n"
13
+ unless data.column_names.empty? || !layout.show_table_headers
14
+ output << "\t\t<tr>\n\t\t\t<th>" +
15
+ data.column_names.join("</th>\n\t\t\t<th>") +
16
+ "</th>\n\t\t</tr>\n"
17
+ end
18
+ end
19
+
20
+ # Generates the <tr> and <td> tags for each row, calling to_s on each
21
+ # element of the Record. If the Record has been tagged, the tags will be
22
+ # converted into class attributes in the HTML output.
23
+ #
24
+ def build_table_body
25
+ output << data.inject("") do |s,r|
26
+ row = r.map { |e| e.to_s.empty? ? "&nbsp;" : e }
27
+ classstr = r.tags.inject("") {|cs,c| cs + " class='#{c}'" }
28
+ s + "\t\t<tr#{classstr}>\n\t\t\t<td#{classstr}>" +
29
+ row.to_a.join("</td>\n\t\t\t<td#{classstr}>") +
30
+ "</td>\n\t\t</tr>\n"
31
+ end
32
+ end
33
+
34
+ # Simply closes the table tag.
35
+ def build_table_footer
36
+ output << "\t</table>"
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,50 @@
1
+ module Ruport::Format
2
+ class Latex < Plugin
3
+
4
+ attr_accessor :caption
5
+
6
+ def build_table_header
7
+ output << "\\documentclass[11pt]{article}\n" <<
8
+ "\\RequirePackage{lscape,longtable}\n" <<
9
+ "\\begin{document}\n" <<
10
+ "\\begin{longtable}[c]{ "
11
+
12
+ data.column_names.each do
13
+ output << " p{2cm} "
14
+ end
15
+ output << " }\n"
16
+ output << "\\hline\n"
17
+
18
+ #FIXME: this ain't ruby, jh ;)
19
+ counter = 0
20
+
21
+ data.column_names.each do |t|
22
+ output << " & " unless counter == 0
23
+ output << "\\textsc{#{t}}"
24
+ counter += 1
25
+ end
26
+
27
+ output << "\\\\\n"
28
+ output << "\\hline\n"
29
+ output << "\\endhead\n"
30
+ output << "\\endfoot\n"
31
+ output << "\\hline\n"
32
+ end
33
+
34
+ def build_table_body
35
+ data.each do |r|
36
+ output << r.data.join(" & ") + "\\\\\n"
37
+ output << "\\hline\n"
38
+ end
39
+ if caption
40
+ output << "\\caption[#{caption}]{#{caption}}\n"
41
+ end
42
+ output << "\\end{longtable}\n"
43
+ end
44
+
45
+ def build_table_footer
46
+ output << "\\end{document}\n"
47
+ end
48
+
49
+ end
50
+ end