Array
Represents a selection of cells to be styled. Operations on a CellProxy can be chained, and cell properties can be set one-for-all on the proxy.
To set vertical borders only:
table.cells.borders = [:left, :right]
To highlight a rectangular area of the table:
table.rows(1..3).columns(2..4).background_color = 'ff0000'
Retrieves a cell based on its 0-based row and column. Returns an individual Cell, not a Cells collection.
table.cells[0, 0].content # => "First cell content"
# File lib/prawn/table/cells.rb, line 101 def [](row, col) return nil if empty? index_cells unless defined?(@indexed) && @indexed row_array, col_array = @rows[@first_row + row] || [], @columns[@first_column + col] || [] if row_array.length < col_array.length row_array.find { |c| c.column == @first_column + col } else col_array.find { |c| c.row == @first_row + row } end end
Returns the number of columns in the list.
# File lib/prawn/table/cells.rb, line 82 def column_count index_cells unless defined?(@indexed) && @indexed @column_count end
Limits selection to the given column or columns. col_spec can be anything that responds to the === operator selecting a set of 0-based column numbers; most commonly a number or a range.
table.column(0) # selects first column table.columns(3..4) # selects columns four and five
# File lib/prawn/table/cells.rb, line 71 def columns(col_spec) index_cells unless defined?(@indexed) && @indexed col_spec = transform_spec(col_spec, @first_column, @column_count) Cells.new(@columns[col_spec] ||= select { |c| col_spec.respond_to?(:include?) ? col_spec.include?(c.column) : col_spec === c.column }) end
Allows you to filter the given cells by arbitrary properties.
table.column(4).filter { |cell| cell.content =~ /Yes/ }. background_color = '00ff00'
# File lib/prawn/table/cells.rb, line 92 def filter(&block) Cells.new(select(&block)) end
Returns the total height of all rows in the selected set.
# File lib/prawn/table/cells.rb, line 180 def height aggregate_cell_values(:row, :height_ignoring_span, :max) end
Returns maximum width that can contain cells in the set.
# File lib/prawn/table/cells.rb, line 174 def max_width aggregate_cell_values(:column, :max_width_ignoring_span, :max) end
Supports setting arbitrary properties on a group of cells.
table.cells.row(3..6).background_color = 'cc0000'
# File lib/prawn/table/cells.rb, line 188 def method_missing(id, *args, &block) if id.to_s =~ /=\z/ each { |c| c.send(id, *args, &block) if c.respond_to?(id) } else super end end
Returns minimum width required to contain cells in the set.
# File lib/prawn/table/cells.rb, line 168 def min_width aggregate_cell_values(:column, :avg_spanned_min_width, :max) end
Returns the number of rows in the list.
# File lib/prawn/table/cells.rb, line 59 def row_count index_cells unless defined?(@indexed) && @indexed @row_count end
Limits selection to the given row or rows. row_spec can be anything that responds to the === operator selecting a set of 0-based row numbers; most commonly a number or a range.
table.row(0) # selects first row table.rows(3..4) # selects rows four and five
# File lib/prawn/table/cells.rb, line 48 def rows(row_spec) index_cells unless defined?(@indexed) && @indexed row_spec = transform_spec(row_spec, @first_row, @row_count) Cells.new(@rows[row_spec] ||= select { |c| row_spec.respond_to?(:include?) ? row_spec.include?(c.row) : row_spec === c.row }) end
Supports setting multiple properties at once.
table.cells.style(:padding => 0, :border_width => 2)
is the same as:
table.cells.padding = 0 table.cells.border_width = 2
You can also pass a block, which will be called for each cell in turn. This allows you to set more complicated properties:
table.cells.style { |cell| cell.border_width += 12 }
# File lib/prawn/table/cells.rb, line 145 def style(options={}, &block) each do |cell| next if cell.is_a?(Cell::SpanDummy) cell.style(options, &block) end end
Returns the total width of all columns in the selected set.
# File lib/prawn/table/cells.rb, line 154 def width widths = {} each do |cell| per_cell_width = cell.width_ignoring_span.to_f / cell.colspan cell.colspan.times do |n| widths[cell.column+n] = [widths[cell.column+n], per_cell_width]. compact.max end end widths.values.inject(0, &:+) end
Sum up a min/max value over rows or columns in the cells selected. Takes the min/max (per aggregate) of the result of sending meth to each cell, grouped by row_or_column.
# File lib/prawn/table/cells.rb, line 229 def aggregate_cell_values(row_or_column, meth, aggregate) values = {} #calculate values for all cells that do not span accross multiple cells #this ensures that we don't have a problem if the first line includes #a cell that spans across multiple cells each do |cell| #don't take spanned cells if cell.colspan == 1 and cell.class != Prawn::Table::Cell::SpanDummy index = cell.send(row_or_column) values[index] = [values[index], cell.send(meth)].compact.send(aggregate) end end #if there are only colspanned or rowspanned cells in a table spanned_width_needs_fixing = true each do |cell| index = cell.send(row_or_column) if cell.colspan > 1 #calculate current (old) return value before we do anything old_sum = 0 cell.colspan.times { |i| old_sum += values[index+i] unless values[index+i].nil? } #calculate future return value new_sum = cell.send(meth) * cell.colspan #due to float rounding errors we need to ignore a small difference in the new #and the old sum the same had to be done in #the column_width_calculator#natural_width spanned_width_needs_fixing = ((new_sum - old_sum) > Prawn::FLOAT_PRECISION) if spanned_width_needs_fixing #not entirely sure why we need this line, but with it the tests pass values[index] = [values[index], cell.send(meth)].compact.send(aggregate) #overwrite the old values with the new ones, but only if all entries existed entries_exist = true cell.colspan.times { |i| entries_exist = false if values[index+i].nil? } cell.colspan.times { |i| values[index+i] = cell.send(meth) if entries_exist } end else if spanned_width_needs_fixing && cell.class == Prawn::Table::Cell::SpanDummy values[index] = [values[index], cell.send(meth)].compact.send(aggregate) end end end values.values.inject(0, &:+) end
Defers indexing until rows() or columns() is actually called on the Cells object. Without this, we would needlessly index the leaf nodes of the object graph, the ones that are only there to be iterated over.
Make sure to call this before using @rows or @columns.
# File lib/prawn/table/cells.rb, line 204 def index_cells @rows = {} @columns = {} each do |cell| @rows[cell.row] ||= [] @rows[cell.row] << cell @columns[cell.column] ||= [] @columns[cell.column] << cell end @first_row = @rows.keys.min @first_column = @columns.keys.min @row_count = @rows.size @column_count = @columns.size @indexed = true end
Transforms spec, a column / row specification, into an object that can be compared against a row or column number using ===. Normalizes negative indices to be positive, given a total size of total. The first row/column is indicated by first; this value is considered row or column 0.
# File lib/prawn/table/cells.rb, line 288 def transform_spec(spec, first, total) case spec when Range transform_spec(spec.begin, first, total) .. transform_spec(spec.end, first, total) when Integer spec < 0 ? (first + total + spec) : first + spec when Enumerable spec.map { |x| first + x } else # pass through raise "Don't understand spec #{spec.inspect}" end end
Generated with the Darkfish Rdoc Generator 2.