reportbuilder 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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