reportbuilder 1.0.0 → 1.1.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.
data/History.txt CHANGED
@@ -1,3 +1,5 @@
1
+ === 1.1.0 / 2009-03-23
2
+ * Added rtf support
1
3
  === 1.0.0 / 2009-03-22
2
4
  Change of API:
3
5
  * Deleted "add_" before methods
data/Manifest.txt CHANGED
@@ -6,18 +6,24 @@ bin/reportbuilder
6
6
  data/reportbuilder.css
7
7
  data/reportbuilder.js
8
8
  data/sheep.jpg
9
+ examples/generic_interface.rb
10
+ examples/images.rb
11
+ examples/rtf.rb
12
+ examples/test.rtf
13
+ examples/using_a_block.rb
9
14
  lib/reportbuilder.rb
10
15
  lib/reportbuilder/generator.rb
11
16
  lib/reportbuilder/generator/html.rb
17
+ lib/reportbuilder/generator/rtf.rb
12
18
  lib/reportbuilder/generator/text.rb
13
19
  lib/reportbuilder/image.rb
14
20
  lib/reportbuilder/section.rb
15
21
  lib/reportbuilder/table.rb
16
22
  lib/reportbuilder/table/htmlgenerator.rb
23
+ lib/reportbuilder/table/rtfgenerator.rb
17
24
  lib/reportbuilder/table/textgenerator.rb
18
25
  test/test_html.rb
19
26
  test/test_image.rb
20
27
  test/test_reportbuilder.rb
21
28
  test/test_section.rb
22
29
  test/test_table.rb
23
-
data/README.txt CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- Report Abstract Interface. Creates text and html output, based on a common framework.
7
+ Report Abstract Interface. Creates text, html and rtf output, based on a common framework.
8
8
 
9
9
  == FEATURES
10
10
 
@@ -27,6 +27,7 @@ Report Abstract Interface. Creates text and html output, based on a common frame
27
27
  rb.add("Another text") # used directly
28
28
  rb.name="Text output"
29
29
  puts rb.to_text
30
+ rb.save_rtf("test.rtf") # You could save files, too
30
31
 
31
32
  * Using a block, you can control directly the generator
32
33
 
data/Rakefile CHANGED
@@ -11,7 +11,8 @@ Hoe.spec 'reportbuilder' do
11
11
  self.rubyforge_name = 'ruby-statsample'
12
12
  self.developer('Claudio Bustos', 'clbustos_at_gmail.com')
13
13
  self.url = "http://rubyforge.org/projects/ruby-statsample/"
14
- self.extra_dev_deps << ["hpricot", "~>0.8"]
14
+ self.extra_deps << ["rtf","~>0.1"]
15
+ self.extra_dev_deps << ["hpricot", "~>0.8"]
15
16
  end
16
17
 
17
18
  # vim: syntax=ruby
@@ -0,0 +1,17 @@
1
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
2
+ require "reportbuilder"
3
+ rb=ReportBuilder.new
4
+ rb.add(2) # Int#to_s used
5
+ section=ReportBuilder::Section.new(:name=>"Section 1")
6
+ table=ReportBuilder::Table.new(:name=>"Table", :header=>%w{id name})
7
+ table.row([1,"John"])
8
+ table.hr
9
+ table.row([2,"Peter"])
10
+
11
+ section.add(table) # Section is a container for other methods
12
+ rb.add(section) # table have a #report_building method
13
+ rb.add("Another text") # used directly
14
+ rb.name="Text output"
15
+ puts rb.to_text
16
+ rb.name="Html output"
17
+ puts rb.to_html
@@ -0,0 +1,8 @@
1
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
2
+ require "reportbuilder"
3
+ rb=ReportBuilder.new do
4
+ image("../data/sheep.jpg")
5
+ end
6
+ rb.name="Text output"
7
+ puts rb.to_text
8
+
data/examples/rtf.rb ADDED
@@ -0,0 +1,32 @@
1
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
2
+ require "reportbuilder"
3
+ rb=ReportBuilder.new do
4
+ text("First Paragraph")
5
+ section(:name=>"Section 1") do
6
+ section(:name=>"Section 1.1") do
7
+ text("Paragraph inside section 1.1")
8
+ end
9
+ table(:name=>"Table", :header=>%w{id name}) do
10
+ row([1,"John"])
11
+ row([2,"Peter"])
12
+ hr
13
+ row([3,"John"])
14
+ row([4,"Peter"])
15
+
16
+ end
17
+ end
18
+ preformatted <<-EOL
19
+ def test_generate
20
+ html=ReportBuilder.generate(:format=>:html, :name=>@title, :directory=>@tmpdir) do
21
+ text("hola")
22
+ end
23
+ doc=Hpricot(html)
24
+ assert_equal(@title, doc.search("head/title").inner_html)
25
+ assert_equal(@title, doc.search("body/h1").inner_html)
26
+ assert_equal("hola", doc.search("body/p").inner_html)
27
+ end
28
+ EOL
29
+ text("Last paragraph")
30
+ end
31
+ rb.name="RTF output"
32
+ puts rb.to_rtf
data/examples/test.rtf ADDED
@@ -0,0 +1,103 @@
1
+ {\rtf1\ansi\deff0\deflang2057\plain\fs24\fet1
2
+ {\fonttbl
3
+ {\f0\froman Times New Roman;}
4
+ {\f1\fmodern Courier;}
5
+ }
6
+ {\info
7
+ {\createim\yr2010\mo3\dy23\hr13\min11}
8
+ }
9
+ \paperw11907\paperh16840\margl1800\margr1800\margt1440\margb1440
10
+ {\pard
11
+ First Paragraph
12
+ \par}
13
+ {\pard\qc
14
+ {\b\f0\fs34
15
+ Section 1
16
+ }
17
+ \par}
18
+ {\pard\qc
19
+ {\b\f0\fs32
20
+ Section 1.1
21
+ }
22
+ \par}
23
+ {\pard
24
+ Paragraph inside section 1.1
25
+ \par}
26
+ \trowd\tgraph100
27
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx400
28
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx1400
29
+ \pard\intbl
30
+ id
31
+ \cell
32
+ \pard\intbl
33
+ name
34
+ \cell
35
+ \row
36
+ \trowd\tgraph100
37
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx400
38
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx1400
39
+ \pard\intbl
40
+ 1
41
+ \cell
42
+ \pard\intbl
43
+ John
44
+ \cell
45
+ \row
46
+ \trowd\tgraph100
47
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx400
48
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx1400
49
+ \pard\intbl
50
+ 2
51
+ \cell
52
+ \pard\intbl
53
+ Peter
54
+ \cell
55
+ \row
56
+ \trowd\tgraph100
57
+ \clbrdrt\brdrw25\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx400
58
+ \clbrdrt\brdrw25\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx1400
59
+ \pard\intbl
60
+ 3
61
+ \cell
62
+ \pard\intbl
63
+ John
64
+ \cell
65
+ \row
66
+ \trowd\tgraph100
67
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx400
68
+ \clbrdrt\brdrw3\brdrs\clbrdrl\brdrw3\brdrs\clbrdrb\brdrw3\brdrs\clbrdrr\brdrw3\brdrs\cellx1400
69
+ \pard\intbl
70
+ 4
71
+ \cell
72
+ \pard\intbl
73
+ Peter
74
+ \cell
75
+ \row
76
+ {\pard\ql
77
+ {\f1\fs20
78
+ def test_generate
79
+ {\line}
80
+ html=ReportBuilder.generate(:format=>:html, :name=>@title, :directory=>@tmpdir) do
81
+ {\line}
82
+ text("hola")
83
+ {\line}
84
+ end
85
+ {\line}
86
+ doc=Hpricot(html)
87
+ {\line}
88
+ assert_equal(@title, doc.search("head/title").inner_html)
89
+ {\line}
90
+ assert_equal(@title, doc.search("body/h1").inner_html)
91
+ {\line}
92
+ assert_equal("hola", doc.search("body/p").inner_html)
93
+ {\line}
94
+
95
+ {\line}
96
+ end
97
+ {\line}
98
+ }
99
+ \par}
100
+ {\pard
101
+ Last paragraph
102
+ \par}
103
+ }
@@ -0,0 +1,18 @@
1
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
2
+ require "reportbuilder"
3
+ rb=ReportBuilder.new do
4
+ text("2")
5
+ section(:name=>"Section 1") do
6
+ table(:name=>"Table", :header=>%w{id name}) do
7
+ row([1,"John"])
8
+ hr
9
+ row([2,"Peter"])
10
+ end
11
+ end
12
+ preformatted("Another Text")
13
+ end
14
+ rb.name="Text output"
15
+ puts rb.to_text
16
+ rb.name="Html output"
17
+ puts rb.to_html
18
+
data/lib/reportbuilder.rb CHANGED
@@ -51,7 +51,7 @@ class ReportBuilder
51
51
  # Doesn't print a title if set to true
52
52
  attr_accessor :no_title
53
53
 
54
- VERSION = '1.0.0'
54
+ VERSION = '1.1.0'
55
55
  # Generates and optionally save the report on one function
56
56
  def self.generate(options=Hash.new, &block)
57
57
  options[:filename]||=nil
@@ -101,6 +101,18 @@ class ReportBuilder
101
101
  gen.parse
102
102
  gen.out
103
103
  end
104
+ # Returns a RTF output
105
+ def to_rtf()
106
+ gen = Generator::Rtf.new(self,@options)
107
+ gen.parse
108
+ gen.out
109
+ end
110
+ # Save a rtf file
111
+ def save_rtf(filename)
112
+ gen = Generator::Rtf.new(self,@options)
113
+ gen.parse
114
+ gen.save(filename)
115
+ end
104
116
  # Save an html file
105
117
  def save_html(file)
106
118
  options=@options.dup
@@ -7,6 +7,8 @@ class ReportBuilder
7
7
  attr_reader :parse_level
8
8
  # Options for Generator. Passed by ReportBuilder class on creation
9
9
  attr_reader :options
10
+ # Entries for Table of Contents
11
+ attr_reader :toc
10
12
  def initialize(builder, options)
11
13
  @builder=builder
12
14
  @parse_level=0
@@ -112,3 +114,5 @@ end
112
114
 
113
115
  require 'reportbuilder/generator/text'
114
116
  require 'reportbuilder/generator/html'
117
+ require 'reportbuilder/generator/rtf'
118
+
@@ -3,7 +3,6 @@ class ReportBuilder
3
3
  class Generator
4
4
  class Html < Generator
5
5
  PREFIX="html"
6
- attr_reader :toc
7
6
  attr_reader :directory
8
7
  def initialize(builder, options)
9
8
  super
@@ -0,0 +1,75 @@
1
+ require 'rtf'
2
+ class ReportBuilder
3
+ class Generator
4
+ class Rtf < Generator
5
+ PREFIX="rtf"
6
+ attr_accessor :rtf
7
+ attr_reader :options
8
+ include RTF
9
+ def initialize(builder, options)
10
+ super
11
+ @font=Font.new(Font::ROMAN, @options[:font])
12
+
13
+ @rtf = Document.new(@font)
14
+ @pre_char = CharacterStyle.new
15
+
16
+ @pre_char.font = Font.new(Font::MODERN, 'Courier')
17
+ @pre_char.font_size=@options[:font_size]
18
+
19
+ @pre_par = ParagraphStyle.new
20
+
21
+ @header_styles=Hash.new {|h,k|
22
+ cs=CharacterStyle.new
23
+ cs.font=@font
24
+ cs.font_size=@options[:font_size]+(8-k)*2
25
+ cs.bold=true
26
+ ps=ParagraphStyle.new
27
+ ps.justification = ParagraphStyle::CENTER_JUSTIFY
28
+ h[k]={:cs=>cs, :ps=>ps}
29
+ }
30
+
31
+ end
32
+ def default_options
33
+
34
+ {
35
+ :font=>'Times New Roman',
36
+ :font_size=>20,
37
+ :table_border_width=>3,
38
+ :table_hr_width=>25
39
+ }
40
+ end
41
+ def text(*args,&block)
42
+ if args.size==1 and args[0].is_a? String and !block
43
+ @rtf.paragraph << args[0]
44
+ else
45
+ @rtf.paragraph(*args,&block)
46
+ end
47
+ end
48
+ def header(level,t)
49
+ @rtf.paragraph(@header_styles[level][:ps]) do |n1|
50
+ n1.apply(@header_styles[level][:cs]) do |n2|
51
+ n2 << t
52
+ end
53
+ end
54
+ end
55
+ def preformatted(t)
56
+ @rtf.paragraph(@pre_par) do |n1|
57
+ n1.apply(@pre_char) do |n2|
58
+ t.split("\n").each do |line|
59
+ n2 << line
60
+ n2.line_break
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+ def out
67
+ @rtf.to_rtf
68
+ end
69
+ def save(filename)
70
+ File.open(filename,'wb') {|file| file.write(@rtf.to_rtf)
71
+ }
72
+ end
73
+ end
74
+ end
75
+ end
@@ -31,14 +31,18 @@ class ReportBuilder::Section
31
31
  generator.parse_cycle(self)
32
32
  end
33
33
 
34
- def report_building_html(generator)
35
- htag="h#{generator.parse_level+1}"
36
- anchor=generator.toc_entry(name)
34
+ def report_building_html(g)
35
+ htag="h#{g.parse_level+1}"
36
+ anchor=g.toc_entry(name)
37
37
  generator.html "<div class='section'><#{htag}>#{name}</#{htag}><a name='#{anchor}'></a>"
38
- generator.parse_cycle(self)
39
- generator.html "</div>"
38
+ g.parse_cycle(self)
39
+ g.html "</div>"
40
+ end
41
+ def report_building_rtf(g)
42
+ level=g.parse_level
43
+ g.header(level,name)
44
+ g.parse_cycle(self)
40
45
  end
41
-
42
46
  def add(element)
43
47
  if element.is_a? ReportBuilder::Section
44
48
  element.parent=self
@@ -56,6 +56,9 @@ class ReportBuilder
56
56
  def row(row)
57
57
  @rows.push(row)
58
58
  end
59
+ def n_columns
60
+ @n_columns||=calculate_widths.size
61
+ end
59
62
  # Adds a horizontal rule
60
63
  # table.add_hr
61
64
  def hr
@@ -67,9 +70,12 @@ class ReportBuilder
67
70
  def rowspan(data,n)
68
71
  Rowspan.new(data,n)
69
72
  end
73
+ # Count the numbers of rows without :hr
74
+ def n_rows_no_hr
75
+ @rows.inject(0) {|ac,v| ac+(v==:hr ? 0 : 1)}
76
+ end
70
77
  # Adds a colspan on a cell
71
78
  # table.add_row(["a",table.colspan("b",2)])
72
-
73
79
  def colspan(data,n)
74
80
  Colspan.new(data,n)
75
81
  end
@@ -97,6 +103,7 @@ class ReportBuilder
97
103
  end
98
104
  }
99
105
  }
106
+ @max_cols
100
107
  end
101
108
  def report_building_text(generator)
102
109
  require 'reportbuilder/table/textgenerator'
@@ -108,7 +115,11 @@ class ReportBuilder
108
115
  table_generator=ReportBuilder::Table::HtmlGenerator.new(generator, self)
109
116
  table_generator.generate
110
117
  end
111
-
118
+ def report_building_rtf(generator)
119
+ require 'reportbuilder/table/rtfgenerator'
120
+ table_generator=ReportBuilder::Table::RtfGenerator.new(generator, self)
121
+ table_generator.generate
122
+ end
112
123
  def total_width # :nodoc:
113
124
  if @max_cols.size>0
114
125
  @max_cols.inject(0){|a,v| a+(v+3)}+1
@@ -0,0 +1,66 @@
1
+ class ReportBuilder
2
+ class Table
3
+ class RtfGenerator < ElementGenerator
4
+ include RTF
5
+ def generate()
6
+ @t=@element
7
+ @rtf=@generator.rtf
8
+ max_cols=@t.calculate_widths
9
+ n_rows=@t.n_rows_no_hr+(@t.header.size>0 ? 1: 0)
10
+ args=[n_rows, @t.n_columns]+max_cols.map{|m| m*@generator.options[:font_size]*10}
11
+ @table=@rtf.table(*args)
12
+ @table.border_width=@generator.options[:table_border_width]
13
+ @rowspans=[]
14
+ if @t.header.size>0
15
+ @t.header.each_with_index do |th,i|
16
+ @table[0][i] << th
17
+ end
18
+ end
19
+ row_i=1
20
+ next_with_hr=false
21
+ @t.rows.each_with_index{|row|
22
+ if row==:hr
23
+ next_with_hr=true
24
+ # Nothing
25
+ else
26
+ parse_row(row,row_i)
27
+ if next_with_hr
28
+ create_hr(row_i)
29
+ next_with_hr=false
30
+ end
31
+ row_i+=1
32
+ end
33
+ }
34
+
35
+ end
36
+ def create_hr(row_i)
37
+ (0...@t.n_columns).each {|i|
38
+ @table[row_i][i].top_border_width=@generator.options[:table_hr_width]
39
+ }
40
+ end
41
+
42
+ def parse_row(row,row_i)
43
+ t=@element
44
+ row_ary=[]
45
+ colspan_i=0
46
+ row.each_index do |i|
47
+ if !@rowspans[i].nil? and @rowspans[i]>0
48
+ @rowspans[i]-=1
49
+ elsif colspan_i>0
50
+ colspan_i-=1
51
+ elsif row[i].is_a? Table::Colspan
52
+ @table[row_i][i] << row[i].data
53
+ colspan_i=row[i].cols-1
54
+ elsif row[i].nil?
55
+ @table[row_i][i] << ""
56
+ elsif row[i].is_a? Table::Rowspan
57
+ @table[row_i][i] << row[i].data
58
+ @rowspans[i]=row[i].rows-1
59
+ else
60
+ @table[row_i][i] << row[i].to_s
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
+ - 1
7
8
  - 0
8
- - 0
9
- version: 1.0.0
9
+ version: 1.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Claudio Bustos
@@ -18,9 +18,22 @@ date: 2010-03-23 00:00:00 -03:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: rubyforge
21
+ name: rtf
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 1
30
+ version: "0.1"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rubyforge
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
24
37
  requirements:
25
38
  - - ">="
26
39
  - !ruby/object:Gem::Version
@@ -30,11 +43,11 @@ dependencies:
30
43
  - 4
31
44
  version: 2.0.4
32
45
  type: :development
33
- version_requirements: *id001
46
+ version_requirements: *id002
34
47
  - !ruby/object:Gem::Dependency
35
48
  name: gemcutter
36
49
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
50
+ requirement: &id003 !ruby/object:Gem::Requirement
38
51
  requirements:
39
52
  - - ">="
40
53
  - !ruby/object:Gem::Version
@@ -44,11 +57,11 @@ dependencies:
44
57
  - 0
45
58
  version: 0.5.0
46
59
  type: :development
47
- version_requirements: *id002
60
+ version_requirements: *id003
48
61
  - !ruby/object:Gem::Dependency
49
62
  name: hpricot
50
63
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
64
+ requirement: &id004 !ruby/object:Gem::Requirement
52
65
  requirements:
53
66
  - - ~>
54
67
  - !ruby/object:Gem::Version
@@ -57,11 +70,11 @@ dependencies:
57
70
  - 8
58
71
  version: "0.8"
59
72
  type: :development
60
- version_requirements: *id003
73
+ version_requirements: *id004
61
74
  - !ruby/object:Gem::Dependency
62
75
  name: hoe
63
76
  prerelease: false
64
- requirement: &id004 !ruby/object:Gem::Requirement
77
+ requirement: &id005 !ruby/object:Gem::Requirement
65
78
  requirements:
66
79
  - - ">="
67
80
  - !ruby/object:Gem::Version
@@ -71,8 +84,8 @@ dependencies:
71
84
  - 1
72
85
  version: 2.5.1
73
86
  type: :development
74
- version_requirements: *id004
75
- description: Report Abstract Interface. Creates text and html output, based on a common framework.
87
+ version_requirements: *id005
88
+ description: Report Abstract Interface. Creates text, html and rtf output, based on a common framework.
76
89
  email:
77
90
  - clbustos_at_gmail.com
78
91
  executables:
@@ -92,14 +105,21 @@ files:
92
105
  - data/reportbuilder.css
93
106
  - data/reportbuilder.js
94
107
  - data/sheep.jpg
108
+ - examples/generic_interface.rb
109
+ - examples/images.rb
110
+ - examples/rtf.rb
111
+ - examples/test.rtf
112
+ - examples/using_a_block.rb
95
113
  - lib/reportbuilder.rb
96
114
  - lib/reportbuilder/generator.rb
97
115
  - lib/reportbuilder/generator/html.rb
116
+ - lib/reportbuilder/generator/rtf.rb
98
117
  - lib/reportbuilder/generator/text.rb
99
118
  - lib/reportbuilder/image.rb
100
119
  - lib/reportbuilder/section.rb
101
120
  - lib/reportbuilder/table.rb
102
121
  - lib/reportbuilder/table/htmlgenerator.rb
122
+ - lib/reportbuilder/table/rtfgenerator.rb
103
123
  - lib/reportbuilder/table/textgenerator.rb
104
124
  - test/test_html.rb
105
125
  - test/test_image.rb