Changeset 1268

Show
Ignore:
Timestamp:
02/09/08 10:44:05 (9 months ago)
Author:
brian
Message:

Change formatter build_foo to build_foo(data), removing data accessor
from formatter, and putting it in the renderer instead.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ruport/branches/brian/exp-stage-data/lib/ruport/formatter.rb

    r1262 r1268  
    3636  #      # Implements ReverseRenderer's :reversed_header hook 
    3737  #      # but can be used by any renderer    
    38   #      def build_reversed_header    
     38  #      def build_reversed_header(data) 
    3939  #         output << "#{options.header_text}\n" 
    4040  #         output << "The reversed text will follow\n" 
     
    4343  #      # Implements ReverseRenderer's :reversed_body hook 
    4444  #      # but can be used by any renderer 
    45   #      def build_reversed_body 
     45  #      def build_reversed_body(data) 
    4646  #         output << data.reverse << "\n" 
    4747  #      end          
     
    6767      # Iterates through <tt>data</tt> and passes 
    6868      # 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) 
    7073        data.each do |r| 
    7174          render_row(r,options,&block) 
     
    112115      # followed by a newline. 
    113116      # 
    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|                      
    116119          render_group(group, options, &block) 
    117120          output << "\n" 
     
    136139    include RenderingTools 
    137140    
    138     # Set by the <tt>:data</tt> attribute from Renderer#render 
    139     attr_reader :data               
    140      
    141141    # Set automatically by Renderer#render(format) or Renderer#render_format 
    142142    attr_accessor :format                                                     
     
    167167    #      renders :txt, :for => ReverseRenderer 
    168168    #       
    169     #      build :reversed_header do 
     169    #      build :reversed_header do |data| 
    170170    #         output << "#{options.header_text}\n" 
    171171    #         output << "The reversed text will follow\n" 
    172172    #      end 
    173173    #  
    174     #      build :reversed_body do 
     174    #      build :reversed_body do |data| 
    175175    #         output << data.reverse << "\n" 
    176176    #      end 
     
    201201      @options ||= Renderer::Options.new 
    202202    end  
    203  
    204     # Sets the data object, making a local copy using #dup. This may have 
    205     # a significant overhead for large tables, so formatters which don't 
    206     # modify the data object may wish to override this. 
    207     def data=(val) 
    208       @data = val.dup 
    209     end 
    210203 
    211204    # Clears the output. 
  • ruport/branches/brian/exp-stage-data/lib/ruport/formatter/csv.rb

    r1260 r1268  
    6565    # This method does not do anything if options.show_table_headers is false 
    6666    # or the Data::Table has no column names. 
    67     def build_table_header 
     67    def build_table_header(data) 
    6868      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) 
    7170      end 
    7271    end 
    7372 
    7473    # Calls the row renderer for each row in the Data::Table 
    75     def build_table_body 
     74    def build_table_body(data) 
    7675      fcsv = csv_writer 
    7776      data.each { |row| fcsv << row } 
     
    7978 
    8079    # Produces CSV output for a data row. 
    81     def build_row 
     80    def build_row(data) 
    8281      csv_writer << data 
    8382    end 
     
    8584    # Renders the header for a group using the group name. 
    8685    #  
    87     def build_group_header 
     86    def build_group_header(data) 
    8887      csv_writer << [data.name.to_s] << [] 
    8988    end 
     
    9190    # Renders the group body - uses the table renderer to generate the output. 
    9291    # 
    93     def build_group_body 
     92    def build_group_body(data) 
    9493      render_table data, options.to_hash 
    9594    end 
     
    9897    # column names. 
    9998    # 
    100     def build_grouping_header 
     99    def build_grouping_header(data) 
    101100      unless options.style == :inline 
    102         csv_writer << [data.grouped_by] + grouping_columns 
     101        csv_writer << [data.grouped_by] + grouping_columns(data) 
    103102      end 
    104103    end 
    105104    
    106105    # Determines the proper style to use and renders the Grouping. 
    107     def build_grouping_body 
     106    def build_grouping_body(data) 
    108107      case options.style 
    109108      when :inline 
    110         render_inline_grouping(options) 
     109        render_inline_grouping(data,options) 
    111110      when :justified, :raw 
    112         render_justified_or_raw_grouping 
     111        render_justified_or_raw_grouping(data) 
    113112      else 
    114113        raise NotImplementedError, "Unknown style" 
     
    118117    private 
    119118     
    120     def grouping_columns 
     119    def grouping_columns(data) 
    121120      data.data.to_a[0][1].column_names 
    122121    end 
    123122     
    124     def render_justified_or_raw_grouping 
     123    def render_justified_or_raw_grouping(data) 
    125124      data.each do |_,group| 
    126125        prefix = [group.name.to_s] 
  • ruport/branches/brian/exp-stage-data/lib/ruport/formatter/html.rb

    r1226 r1268  
    4040    # This method does not do anything if options.show_table_headers is false 
    4141    # or the Data::Table has no column names. 
    42     def build_table_header 
     42    def build_table_header(data) 
    4343      output << "\t<table>\n" 
    4444      unless data.column_names.empty? || !options.show_table_headers 
     
    4949    end 
    5050     
    51     # Uses the Row renderer to build up the table body. 
     51    # Uses build_row to build up the table body. 
    5252    # Replaces nil and empty strings with "&nbsp;"  
    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? ? "&nbsp;" : e } 
     53    def build_table_body(data) 
     54      data.each do |row| 
     55        build_row(row.map { |e| e.to_s.empty? ? "&nbsp;" : e }) 
    5756      end 
    5857    end 
    5958 
    6059    # Simply closes the table tag.  
    61     def build_table_footer 
     60    def build_table_footer(data) 
    6261      output << "\t</table>" 
    6362    end 
    6463   
    6564    # Renders individual rows for the table. 
    66     def build_row 
     65    def build_row(data) 
    6766      output << 
    6867        "\t\t<tr>\n\t\t\t<td>" + 
     
    7372    # Renders the header for a group using the group name. 
    7473    # 
    75     def build_group_header 
     74    def build_group_header(data) 
    7675      output << "\t<p>#{data.name}</p>\n" 
    7776    end 
     
    8079    # Table renderer. 
    8180    # 
    82     def build_group_body 
     81    def build_group_body(data) 
    8382      render_table data, options.to_hash 
    8483    end 
     
    8786    # renders them using the group renderer. 
    8887    # 
    89     def build_grouping_body 
     88    def build_grouping_body(data) 
    9089      case options.style 
    9190      when :inline 
    92         render_inline_grouping(options) 
     91        render_inline_grouping(data,options) 
    9392      when :justified 
    94         render_justified_grouping 
     93        render_justified_grouping(data) 
    9594      end 
    9695    end 
     
    122121    private 
    123122     
    124     def render_justified_grouping 
     123    def render_justified_grouping(data) 
    125124      output << "\t<table>\n\t\t<tr>\n\t\t\t<th>" + 
    126125        "#{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>") +  
    128127        "</th>\n\t\t</tr>\n" 
    129128      data.each do |name, group|                      
     
    142141    end 
    143142     
    144     def grouping_columns 
     143    def grouping_columns(data) 
    145144      data.data.to_a[0][1].column_names 
    146145    end 
  • ruport/branches/brian/exp-stage-data/lib/ruport/formatter/pdf.rb

    r1236 r1268  
    9494    # Calls the draw_table method. 
    9595    # 
    96     def build_table_body 
     96    def build_table_body(data) 
    9797      draw_table(data) 
    9898    end 
     
    101101    # <tt>pdf_writer</tt> object. 
    102102    # 
    103     def finalize_table 
     103    def finalize_table(data) 
    104104      render_pdf unless options.skip_finalize_table 
    105105    end 
    106106     
    107107    # Generates a header with the group name for Renderer::Group. 
    108     def build_group_header 
     108    def build_group_header(data) 
    109109      pad(10) { add_text data.name.to_s, :justification => :center } 
    110110    end 
    111111     
    112112    # Renders the group as a table for Renderer::Group. 
    113     def build_group_body 
     113    def build_group_body(data) 
    114114      render_table data, options.to_hash.merge(:formatter => pdf_writer) 
    115115    end 
     
    117117    # Determines which style to use and renders the main body for 
    118118    # Renderer::Grouping. 
    119     def build_grouping_body  
     119    def build_grouping_body(data) 
    120120      case options.style 
    121121      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, 
    123123            :skip_finalize_table => true)) 
    124124      when :justified, :separated 
    125         render_justified_or_separated_grouping 
     125        render_justified_or_separated_grouping(data) 
    126126      when :offset 
    127         render_offset_grouping 
     127        render_offset_grouping(data) 
    128128      else 
    129129        raise NotImplementedError, "Unknown style" 
     
    132132    
    133133    # Calls <tt>render_pdf</tt>. 
    134     def finalize_grouping 
     134    def finalize_grouping(data) 
    135135      render_pdf 
    136136    end 
     
    432432    end 
    433433     
    434     def grouping_columns 
     434    def grouping_columns(data) 
    435435      data.data.to_a[0][1].column_names.dup.unshift(data.grouped_by) 
    436436    end 
    437437     
    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) 
    444444      data.each do |name,group| 
    445445        group.each_with_index do |r,i| 
     
    455455    end 
    456456     
    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) 
    459459      data.each do |name,group| 
    460460        table << ["<b>#{name}</b>"] 
  • ruport/branches/brian/exp-stage-data/lib/ruport/formatter/text.rb

    r1251 r1268  
    6060    # calculate_max_col_widths. 
    6161    # 
    62     def prepare_table 
     62    def prepare_table(data) 
    6363      raise Ruport::FormatterError, "Can't output table without " + 
    6464        "data or column names." if data.empty? && data.column_names.empty? 
    65       calculate_max_col_widths 
     65      calculate_max_col_widths(data) 
    6666    end 
    6767 
     
    7171    # Calls fit_to_width to truncate the table heading if necessary. 
    7272    # 
    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) 
    7575 
    7676      c = data.column_names.enum_for(:each_with_index).map { |f,i| 
     
    7878      } 
    7979 
    80       output << fit_to_width("#{hr}| #{c.join(' | ')} |\n") 
     80      output << fit_to_width("#{hr(data)}| #{c.join(' | ')} |\n") 
    8181    end 
    8282 
     
    8989    # Uses fit_to_width to truncate the table if necessary. 
    9090    # 
    91     def build_table_body 
    92       output << fit_to_width(hr
     91    def build_table_body(data) 
     92      output << fit_to_width(hr(data)
    9393      return if data.empty? 
    9494 
    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)) 
    107100    end 
    108101     
     
    115108    # Uses fit_to_width to truncate the row if necessary. 
    116109    # 
    117     def build_row 
     110    def build_row(data) 
    118111      max_col_widths_for_row(data) unless options.max_col_width 
    119112 
     
    132125    # Renders the header for a group using the group name. 
    133126    # 
    134     def build_group_header 
     127    def build_group_header(data) 
    135128      output << "#{data.name}:\n\n" 
    136129    end 
     
    139132    # Table renderer. 
    140133    # 
    141     def build_group_body 
     134    def build_group_body(data) 
    142135      render_table data, options 
    143136    end 
     
    146139    # renders them using the group renderer. 
    147140    # 
    148     def build_grouping_body 
    149       render_inline_grouping(options) 
     141    def build_grouping_body(data) 
     142      render_inline_grouping(data, options) 
    150143    end 
    151144     
     
    153146    # is false/nil.  Returns true otherwise. 
    154147    # 
    155     def should_render_column_names? 
     148    def should_render_column_names?(data) 
    156149      not data.column_names.empty? || !options.show_table_headers 
    157150    end 
     
    161154    # 
    162155    #   "+------------------+" 
    163     def hr 
     156    def hr(data) 
    164157      ref = data.column_names.empty? ? data[0].to_a : data.column_names 
    165158      len = options.max_col_width.inject(ref.length * 3) {|s,e|s+e} 
     
    186179 
    187180    # Determines the text widths for each column. 
    188     def calculate_max_col_widths 
     181    def calculate_max_col_widths(data) 
    189182      # allow override 
    190183      return if options.max_col_width 
  • ruport/branches/brian/exp-stage-data/lib/ruport/renderer.rb

    r1262 r1268  
    395395  end 
    396396   
     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 
    397411  # The name of format being used. 
    398412  attr_accessor :format   
     
    401415  attr_writer :formatter   
    402416   
    403   # The +data+ that has been passed to the active formatter. 
    404   def data 
    405     formatter.data 
    406   end 
    407  
    408   # Sets +data+ attribute on the active formatter. 
    409   def data=(val) 
    410     formatter.data = val 
    411   end 
    412  
    413417  # Renderer::Options object which is shared with the current formatter. 
    414418  def options 
     
    483487    unless self.class.stages.nil? 
    484488      self.class.stages.each do |stage| 
    485         maybe("build_#{stage}"
     489        maybe("build_#{stage}", data
    486490      end 
    487491    end 
     
    489493 
    490494  def prepare(name) 
    491     maybe "prepare_#{name}" 
     495    maybe "prepare_#{name}", data 
    492496  end 
    493497 
    494498  def finalize(name) 
    495     maybe "finalize_#{name}" 
     499    maybe "finalize_#{name}", data 
    496500  end       
    497501   
    498   def maybe(something
    499     formatter.send something if formatter.respond_to? something 
     502  def maybe(something, *args
     503    formatter.__send__(something, *args) if formatter.respond_to? something 
    500504  end     
    501505 
  • ruport/branches/brian/exp-stage-data/test/renderer_test.rb

    r1262 r1268  
    2222 
    2323  def run 
     24    data = self.data 
    2425    formatter do 
    25       build_header 
    26       build_body 
    27       build_footer 
     26      build_header(data) 
     27      build_body(data) 
     28      build_footer(data) 
    2829    end 
    2930  end 
     
    4344  renders :text, :for => OldSchoolRenderer 
    4445   
    45   def prepare_document 
     46  def prepare_document(data) 
    4647    output << "p" 
    4748  end 
    4849 
    49   def build_header 
     50  def build_header(data) 
    5051    output << "header\n" 
    5152  end 
    5253 
    53   def build_body 
     54  def build_body(data) 
    5455    output << "body\n" 
    5556  end 
    5657 
    57   def build_footer 
     58  def build_footer(data) 
    5859    output << "footer\n" 
    5960  end 
    6061 
    61   def finalize_document 
     62  def finalize_document(data) 
    6263    output << "f" 
    6364  end 
     
    6768class Destructive < Ruport::Formatter 
    6869 
    69   def prepare_document; end 
    70  
    71   def build_header; end 
    72  
    73   def build_body 
     70  def prepare_document(data); end 
     71 
     72  def build_header(data); end 
     73 
     74  def build_body(data) 
    7475    output << "You sent #{data}" 
    7576    data.replace("RUBBISH") 
    7677  end 
    7778 
    78   def build_footer; end 
    79  
    80   def finalize_document; end 
     79  def build_footer(data); end 
     80 
     81  def finalize_document(data); end 
    8182end 
    8283 
     
    192193    end 
    193194 
    194     assert_equal "body\n", rend.formatter { build_body }.output 
     195    assert_equal "body\n", rend.formatter { build_body(rend.data) }.output 
    195196 
    196197    rend.formatter.clear_output 
     
    430431     renders [:html,:text], :for => VanillaRenderer 
    431432 
    432      def build_header 
     433     def build_header(data) 
    433434       a = 10 
    434435 
     
    437438     end 
    438439 
    439      def build_body 
     440     def build_body(data) 
    440441       html { output << "<pre>\n" } 
    441442       output << options.body_text 
     
    481482    renders :terb, :for  => VanillaRenderer 
    482483     
    483     def build_body     
     484    def build_body(data) 
    484485       # demonstrate local binding 
    485486       @foo = "bar"                          
     
    556557    renders :text, :for => RendererWithSetup 
    557558     
    558     def build_bar 
     559    def build_bar(data) 
    559560      output << options.foo 
    560561    end