Changeset 1268
- Timestamp:
- 02/09/08 10:44:05 (9 months ago)
- Files:
-
- ruport/branches/brian/exp-stage-data/lib/ruport/formatter.rb (modified) (7 diffs)
- ruport/branches/brian/exp-stage-data/lib/ruport/formatter/csv.rb (modified) (6 diffs)
- ruport/branches/brian/exp-stage-data/lib/ruport/formatter/html.rb (modified) (7 diffs)
- ruport/branches/brian/exp-stage-data/lib/ruport/formatter/pdf.rb (modified) (6 diffs)
- ruport/branches/brian/exp-stage-data/lib/ruport/formatter/text.rb (modified) (11 diffs)
- ruport/branches/brian/exp-stage-data/lib/ruport/renderer.rb (modified) (4 diffs)
- ruport/branches/brian/exp-stage-data/test/renderer_test.rb (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
ruport/branches/brian/exp-stage-data/lib/ruport/formatter.rb
r1262 r1268 36 36 # # Implements ReverseRenderer's :reversed_header hook 37 37 # # but can be used by any renderer 38 # def build_reversed_header 38 # def build_reversed_header(data) 39 39 # output << "#{options.header_text}\n" 40 40 # output << "The reversed text will follow\n" … … 43 43 # # Implements ReverseRenderer's :reversed_body hook 44 44 # # but can be used by any renderer 45 # def build_reversed_body 45 # def build_reversed_body(data) 46 46 # output << data.reverse << "\n" 47 47 # end … … 67 67 # Iterates through <tt>data</tt> and passes 68 68 # each row to render_row with the given options. 69 def render_data_by_row(options={},&block) 69 # This interface is is very inefficient, since new Renderer and 70 # Formatter objects are created for every row, and is deprecated. 71 # Iterate the rows directly within your Formatter instead. 72 def render_data_by_row(data,options={},&block) 70 73 data.each do |r| 71 74 render_row(r,options,&block) … … 112 115 # followed by a newline. 113 116 # 114 def render_inline_grouping( options={},&block)115 data.each do |_,group|117 def render_inline_grouping(grouping,options={},&block) 118 grouping.each do |_,group| 116 119 render_group(group, options, &block) 117 120 output << "\n" … … 136 139 include RenderingTools 137 140 138 # Set by the <tt>:data</tt> attribute from Renderer#render139 attr_reader :data140 141 141 # Set automatically by Renderer#render(format) or Renderer#render_format 142 142 attr_accessor :format … … 167 167 # renders :txt, :for => ReverseRenderer 168 168 # 169 # build :reversed_header do 169 # build :reversed_header do |data| 170 170 # output << "#{options.header_text}\n" 171 171 # output << "The reversed text will follow\n" 172 172 # end 173 173 # 174 # build :reversed_body do 174 # build :reversed_body do |data| 175 175 # output << data.reverse << "\n" 176 176 # end … … 201 201 @options ||= Renderer::Options.new 202 202 end 203 204 # Sets the data object, making a local copy using #dup. This may have205 # a significant overhead for large tables, so formatters which don't206 # modify the data object may wish to override this.207 def data=(val)208 @data = val.dup209 end210 203 211 204 # Clears the output. ruport/branches/brian/exp-stage-data/lib/ruport/formatter/csv.rb
r1260 r1268 65 65 # This method does not do anything if options.show_table_headers is false 66 66 # or the Data::Table has no column names. 67 def build_table_header 67 def build_table_header(data) 68 68 unless data.column_names.empty? || !options.show_table_headers 69 render_row data.column_names, :format_options => options.format_options, 70 :formatter => csv_writer 69 build_row(data.column_names) 71 70 end 72 71 end 73 72 74 73 # Calls the row renderer for each row in the Data::Table 75 def build_table_body 74 def build_table_body(data) 76 75 fcsv = csv_writer 77 76 data.each { |row| fcsv << row } … … 79 78 80 79 # Produces CSV output for a data row. 81 def build_row 80 def build_row(data) 82 81 csv_writer << data 83 82 end … … 85 84 # Renders the header for a group using the group name. 86 85 # 87 def build_group_header 86 def build_group_header(data) 88 87 csv_writer << [data.name.to_s] << [] 89 88 end … … 91 90 # Renders the group body - uses the table renderer to generate the output. 92 91 # 93 def build_group_body 92 def build_group_body(data) 94 93 render_table data, options.to_hash 95 94 end … … 98 97 # column names. 99 98 # 100 def build_grouping_header 99 def build_grouping_header(data) 101 100 unless options.style == :inline 102 csv_writer << [data.grouped_by] + grouping_columns 101 csv_writer << [data.grouped_by] + grouping_columns(data) 103 102 end 104 103 end 105 104 106 105 # Determines the proper style to use and renders the Grouping. 107 def build_grouping_body 106 def build_grouping_body(data) 108 107 case options.style 109 108 when :inline 110 render_inline_grouping( options)109 render_inline_grouping(data,options) 111 110 when :justified, :raw 112 render_justified_or_raw_grouping 111 render_justified_or_raw_grouping(data) 113 112 else 114 113 raise NotImplementedError, "Unknown style" … … 118 117 private 119 118 120 def grouping_columns 119 def grouping_columns(data) 121 120 data.data.to_a[0][1].column_names 122 121 end 123 122 124 def render_justified_or_raw_grouping 123 def render_justified_or_raw_grouping(data) 125 124 data.each do |_,group| 126 125 prefix = [group.name.to_s] ruport/branches/brian/exp-stage-data/lib/ruport/formatter/html.rb
r1226 r1268 40 40 # This method does not do anything if options.show_table_headers is false 41 41 # or the Data::Table has no column names. 42 def build_table_header 42 def build_table_header(data) 43 43 output << "\t<table>\n" 44 44 unless data.column_names.empty? || !options.show_table_headers … … 49 49 end 50 50 51 # Uses the Row rendererto build up the table body.51 # Uses build_row to build up the table body. 52 52 # Replaces nil and empty strings with " " 53 def build_table_body 54 render_data_by_row do |rend| 55 r = rend.data 56 rend.data = r.map { |e| e.to_s.empty? ? " " : e } 53 def build_table_body(data) 54 data.each do |row| 55 build_row(row.map { |e| e.to_s.empty? ? " " : e }) 57 56 end 58 57 end 59 58 60 59 # Simply closes the table tag. 61 def build_table_footer 60 def build_table_footer(data) 62 61 output << "\t</table>" 63 62 end 64 63 65 64 # Renders individual rows for the table. 66 def build_row 65 def build_row(data) 67 66 output << 68 67 "\t\t<tr>\n\t\t\t<td>" + … … 73 72 # Renders the header for a group using the group name. 74 73 # 75 def build_group_header 74 def build_group_header(data) 76 75 output << "\t<p>#{data.name}</p>\n" 77 76 end … … 80 79 # Table renderer. 81 80 # 82 def build_group_body 81 def build_group_body(data) 83 82 render_table data, options.to_hash 84 83 end … … 87 86 # renders them using the group renderer. 88 87 # 89 def build_grouping_body 88 def build_grouping_body(data) 90 89 case options.style 91 90 when :inline 92 render_inline_grouping( options)91 render_inline_grouping(data,options) 93 92 when :justified 94 render_justified_grouping 93 render_justified_grouping(data) 95 94 end 96 95 end … … 122 121 private 123 122 124 def render_justified_grouping 123 def render_justified_grouping(data) 125 124 output << "\t<table>\n\t\t<tr>\n\t\t\t<th>" + 126 125 "#{data.grouped_by}</th>\n\t\t\t<th>" + 127 grouping_columns .join("</th>\n\t\t\t<th>") +126 grouping_columns(data).join("</th>\n\t\t\t<th>") + 128 127 "</th>\n\t\t</tr>\n" 129 128 data.each do |name, group| … … 142 141 end 143 142 144 def grouping_columns 143 def grouping_columns(data) 145 144 data.data.to_a[0][1].column_names 146 145 end ruport/branches/brian/exp-stage-data/lib/ruport/formatter/pdf.rb
r1236 r1268 94 94 # Calls the draw_table method. 95 95 # 96 def build_table_body 96 def build_table_body(data) 97 97 draw_table(data) 98 98 end … … 101 101 # <tt>pdf_writer</tt> object. 102 102 # 103 def finalize_table 103 def finalize_table(data) 104 104 render_pdf unless options.skip_finalize_table 105 105 end 106 106 107 107 # Generates a header with the group name for Renderer::Group. 108 def build_group_header 108 def build_group_header(data) 109 109 pad(10) { add_text data.name.to_s, :justification => :center } 110 110 end 111 111 112 112 # Renders the group as a table for Renderer::Group. 113 def build_group_body 113 def build_group_body(data) 114 114 render_table data, options.to_hash.merge(:formatter => pdf_writer) 115 115 end … … 117 117 # Determines which style to use and renders the main body for 118 118 # Renderer::Grouping. 119 def build_grouping_body 119 def build_grouping_body(data) 120 120 case options.style 121 121 when :inline 122 render_inline_grouping( options.to_hash.merge(:formatter => pdf_writer,122 render_inline_grouping(data,options.to_hash.merge(:formatter => pdf_writer, 123 123 :skip_finalize_table => true)) 124 124 when :justified, :separated 125 render_justified_or_separated_grouping 125 render_justified_or_separated_grouping(data) 126 126 when :offset 127 render_offset_grouping 127 render_offset_grouping(data) 128 128 else 129 129 raise NotImplementedError, "Unknown style" … … 132 132 133 133 # Calls <tt>render_pdf</tt>. 134 def finalize_grouping 134 def finalize_grouping(data) 135 135 render_pdf 136 136 end … … 432 432 end 433 433 434 def grouping_columns 434 def grouping_columns(data) 435 435 data.data.to_a[0][1].column_names.dup.unshift(data.grouped_by) 436 436 end 437 437 438 def table_with_grouped_by_column 439 Ruport::Data::Table.new(:column_names => grouping_columns )440 end 441 442 def render_justified_or_separated_grouping 443 table = table_with_grouped_by_column 438 def table_with_grouped_by_column(data) 439 Ruport::Data::Table.new(:column_names => grouping_columns(data)) 440 end 441 442 def render_justified_or_separated_grouping(data) 443 table = table_with_grouped_by_column(data) 444 444 data.each do |name,group| 445 445 group.each_with_index do |r,i| … … 455 455 end 456 456 457 def render_offset_grouping 458 table = table_with_grouped_by_column 457 def render_offset_grouping(data) 458 table = table_with_grouped_by_column(data) 459 459 data.each do |name,group| 460 460 table << ["<b>#{name}</b>"] ruport/branches/brian/exp-stage-data/lib/ruport/formatter/text.rb
r1251 r1268 60 60 # calculate_max_col_widths. 61 61 # 62 def prepare_table 62 def prepare_table(data) 63 63 raise Ruport::FormatterError, "Can't output table without " + 64 64 "data or column names." if data.empty? && data.column_names.empty? 65 calculate_max_col_widths 65 calculate_max_col_widths(data) 66 66 end 67 67 … … 71 71 # Calls fit_to_width to truncate the table heading if necessary. 72 72 # 73 def build_table_header 74 return unless should_render_column_names? 73 def build_table_header(data) 74 return unless should_render_column_names?(data) 75 75 76 76 c = data.column_names.enum_for(:each_with_index).map { |f,i| … … 78 78 } 79 79 80 output << fit_to_width("#{hr }| #{c.join(' | ')} |\n")80 output << fit_to_width("#{hr(data)}| #{c.join(' | ')} |\n") 81 81 end 82 82 … … 89 89 # Uses fit_to_width to truncate the table if necessary. 90 90 # 91 def build_table_body 92 output << fit_to_width(hr )91 def build_table_body(data) 92 output << fit_to_width(hr(data)) 93 93 return if data.empty? 94 94 95 calculate_max_col_widths unless options.max_col_width 96 97 render_data_by_row do |rend| 98 rend.options do |o| 99 o.max_col_width = options.max_col_width 100 o.alignment = options.alignment 101 o.table_width = options.table_width 102 o.ignore_table_width = options.ignore_table_width 103 end 104 end 105 106 output << fit_to_width(hr) 95 calculate_max_col_widths(data) unless options.max_col_width 96 97 data.each { |row| build_row(row) } 98 99 output << fit_to_width(hr(data)) 107 100 end 108 101 … … 115 108 # Uses fit_to_width to truncate the row if necessary. 116 109 # 117 def build_row 110 def build_row(data) 118 111 max_col_widths_for_row(data) unless options.max_col_width 119 112 … … 132 125 # Renders the header for a group using the group name. 133 126 # 134 def build_group_header 127 def build_group_header(data) 135 128 output << "#{data.name}:\n\n" 136 129 end … … 139 132 # Table renderer. 140 133 # 141 def build_group_body 134 def build_group_body(data) 142 135 render_table data, options 143 136 end … … 146 139 # renders them using the group renderer. 147 140 # 148 def build_grouping_body 149 render_inline_grouping( options)141 def build_grouping_body(data) 142 render_inline_grouping(data, options) 150 143 end 151 144 … … 153 146 # is false/nil. Returns true otherwise. 154 147 # 155 def should_render_column_names? 148 def should_render_column_names?(data) 156 149 not data.column_names.empty? || !options.show_table_headers 157 150 end … … 161 154 # 162 155 # "+------------------+" 163 def hr 156 def hr(data) 164 157 ref = data.column_names.empty? ? data[0].to_a : data.column_names 165 158 len = options.max_col_width.inject(ref.length * 3) {|s,e|s+e} … … 186 179 187 180 # Determines the text widths for each column. 188 def calculate_max_col_widths 181 def calculate_max_col_widths(data) 189 182 # allow override 190 183 return if options.max_col_width ruport/branches/brian/exp-stage-data/lib/ruport/renderer.rb
r1262 r1268 395 395 end 396 396 397 # The +data+ to be rendered. 398 def data 399 @data ||= self 400 end 401 402 def data=(val) 403 @data = val.dup 404 end 405 406 #Maybe consider this alternative: 407 #def data 408 # options.data 409 #end 410 397 411 # The name of format being used. 398 412 attr_accessor :format … … 401 415 attr_writer :formatter 402 416 403 # The +data+ that has been passed to the active formatter.404 def data405 formatter.data406 end407 408 # Sets +data+ attribute on the active formatter.409 def data=(val)410 formatter.data = val411 end412 413 417 # Renderer::Options object which is shared with the current formatter. 414 418 def options … … 483 487 unless self.class.stages.nil? 484 488 self.class.stages.each do |stage| 485 maybe("build_#{stage}" )489 maybe("build_#{stage}", data) 486 490 end 487 491 end … … 489 493 490 494 def prepare(name) 491 maybe "prepare_#{name}" 495 maybe "prepare_#{name}", data 492 496 end 493 497 494 498 def finalize(name) 495 maybe "finalize_#{name}" 499 maybe "finalize_#{name}", data 496 500 end 497 501 498 def maybe(something )499 formatter. send somethingif formatter.respond_to? something502 def maybe(something, *args) 503 formatter.__send__(something, *args) if formatter.respond_to? something 500 504 end 501 505 ruport/branches/brian/exp-stage-data/test/renderer_test.rb
r1262 r1268 22 22 23 23 def run 24 data = self.data 24 25 formatter do 25 build_header 26 build_body 27 build_footer 26 build_header(data) 27 build_body(data) 28 build_footer(data) 28 29 end 29 30 end … … 43 44 renders :text, :for => OldSchoolRenderer 44 45 45 def prepare_document 46 def prepare_document(data) 46 47 output << "p" 47 48 end 48 49 49 def build_header 50 def build_header(data) 50 51 output << "header\n" 51 52 end 52 53 53 def build_body 54 def build_body(data) 54 55 output << "body\n" 55 56 end 56 57 57 def build_footer 58 def build_footer(data) 58 59 output << "footer\n" 59 60 end 60 61 61 def finalize_document 62 def finalize_document(data) 62 63 output << "f" 63 64 end … … 67 68 class Destructive < Ruport::Formatter 68 69 69 def prepare_document ; end70 71 def build_header ; end72 73 def build_body 70 def prepare_document(data); end 71 72 def build_header(data); end 73 74 def build_body(data) 74 75 output << "You sent #{data}" 75 76 data.replace("RUBBISH") 76 77 end 77 78 78 def build_footer ; end79 80 def finalize_document ; end79 def build_footer(data); end 80 81 def finalize_document(data); end 81 82 end 82 83 … … 192 193 end 193 194 194 assert_equal "body\n", rend.formatter { build_body }.output195 assert_equal "body\n", rend.formatter { build_body(rend.data) }.output 195 196 196 197 rend.formatter.clear_output … … 430 431 renders [:html,:text], :for => VanillaRenderer 431 432 432 def build_header 433 def build_header(data) 433 434 a = 10 434 435 … … 437 438 end 438 439 439 def build_body 440 def build_body(data) 440 441 html { output << "<pre>\n" } 441 442 output << options.body_text … … 481 482 renders :terb, :for => VanillaRenderer 482 483 483 def build_body 484 def build_body(data) 484 485 # demonstrate local binding 485 486 @foo = "bar" … … 556 557 renders :text, :for => RendererWithSetup 557 558 558 def build_bar 559 def build_bar(data) 559 560 output << options.foo 560 561 end
