Class: Arrolio::Table::Grid
- Inherits:
-
Object
- Object
- Arrolio::Table::Grid
- Defined in:
- lib/arrolio/table/grid.rb
Overview
Occupancy grid over a Content::Table, honoring colspan and rowspan. Answers the two questions every table consumer asks: which column does each cell actually occupy, and which rows are welded together by a vertical span (and therefore cannot be split apart across pages).
Built once per layout pass and shared by AutoLayout (natural widths), TableFlowable (row heights, cell placement), and splitting (atomic row groups).
Defined Under Namespace
Classes: Placement
Instance Attribute Summary collapse
-
#column_count ⇒ Object
readonly
Returns the value of attribute column_count.
-
#placements ⇒ Object
readonly
Returns the value of attribute placements.
-
#row_count ⇒ Object
readonly
Returns the value of attribute row_count.
Class Method Summary collapse
Instance Method Summary collapse
-
#atomic_row_groups ⇒ Object
Rows welded together by rowspan cells, as arrays of row indexes in ascending order.
-
#initialize(placements:, row_count:, column_count:) ⇒ Grid
constructor
A new instance of Grid.
- #placements_starting_in(row_index) ⇒ Object
Constructor Details
#initialize(placements:, row_count:, column_count:) ⇒ Grid
Returns a new instance of Grid.
57 58 59 60 61 62 63 64 65 |
# File 'lib/arrolio/table/grid.rb', line 57 def initialize(placements:, row_count:, column_count:) @placements = placements.freeze @row_count = row_count @column_count = column_count @by_row = Array.new(row_count) { [] } @placements.each { |p| @by_row[p.row_index] << p } @by_row.each(&:freeze) freeze end |
Instance Attribute Details
#column_count ⇒ Object (readonly)
Returns the value of attribute column_count.
29 30 31 |
# File 'lib/arrolio/table/grid.rb', line 29 def column_count @column_count end |
#placements ⇒ Object (readonly)
Returns the value of attribute placements.
29 30 31 |
# File 'lib/arrolio/table/grid.rb', line 29 def placements @placements end |
#row_count ⇒ Object (readonly)
Returns the value of attribute row_count.
29 30 31 |
# File 'lib/arrolio/table/grid.rb', line 29 def row_count @row_count end |
Class Method Details
.build(table) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/arrolio/table/grid.rb', line 31 def self.build(table) rows = table.rows occupied = {} placements = [] rows.each_with_index do |row, row_index| column_index = 0 row.cells.each do |cell| column_index += 1 while occupied[[row_index, column_index]] colspan = cell.colspan.to_i rowspan = cell.rowspan.to_i placements << Placement.new( cell: cell, row_index: row_index, column_index: column_index, colspan: colspan, rowspan: rowspan ) rowspan.times do |r| colspan.times do |c| occupied[[row_index + r, column_index + c]] = true end end column_index += colspan end end new(placements: placements, row_count: rows.length, column_count: occupied.keys.map(&:last).max.to_i + 1) end |
Instance Method Details
#atomic_row_groups ⇒ Object
Rows welded together by rowspan cells, as arrays of row indexes in ascending order. Rows not covered by any span come back as single-element groups. Splitting the table across pages must happen between groups, never inside one.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/arrolio/table/grid.rb', line 75 def atomic_row_groups groups = [] group = [] welded = welded_rows (0...@row_count).each do |row_index| group << row_index next if welded.include?(row_index + 1) groups << group.freeze group = [] end groups << group.freeze unless group.empty? groups.freeze end |
#placements_starting_in(row_index) ⇒ Object
67 68 69 |
# File 'lib/arrolio/table/grid.rb', line 67 def placements_starting_in(row_index) @by_row[row_index] || [] end |