Skip to content

Commit

Permalink
Tables flow across multiple pages
Browse files Browse the repository at this point in the history
  • Loading branch information
bradediger committed Jan 22, 2010
1 parent e1c6f39 commit 0388bf6
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 8 deletions.
9 changes: 9 additions & 0 deletions examples/table/multi_page_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# encoding: utf-8
#
require "#{File.dirname(__FILE__)}/../example_helper.rb"

Prawn::Document.generate("multi_page_table.pdf") do

table([%w[Some data in a table]] * 50)

end
49 changes: 41 additions & 8 deletions lib/prawn/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,24 @@ def style(stylable, style_hash={}, &block)
# Draws the table onto the document.
#
def draw
top = @pdf.y
@cells.each { |c| c.draw }
@pdf.y = top - height
# The cell y-positions are based on an infinitely long canvas. The offset
# keeps track of how much we have to add to the original, theoretical
# y-position to get to the actual position on the current page.
offset = 0

bounds = @pdf.bounds.stretchy? ? @pdf.margin_box : @pdf.bounds
@cells.each do |cell|
if (cell.y + offset) - cell.height < bounds.bottom
# start a new page
bounds.move_past_bottom
offset = @pdf.cursor - cell.y
end

cell.y += offset
cell.draw
end

@pdf.move_cursor_to(@cells.last.y - @cells.last.height)
end

protected
Expand Down Expand Up @@ -150,26 +165,34 @@ def natural_width

def column_widths
@column_widths ||= begin
if width < cells.min_width || width > cells.max_width
raise Errors::CannotFit
if width < cells.min_width
raise Errors::CannotFit,
"Table's width was set too small to contain its contents"
end

if width > cells.max_width
raise Errors::CannotFit,
"Table's width was set larger than its contents' maximum width"
end

if width <= natural_width
if width < natural_width
# Shrink the table to fit the requested width.
f = (width - cells.min_width).to_f / (natural_width - cells.min_width)

(0...column_length).map do |c|
min, nat = column(c).min_width, column(c).width
(f * (nat - min)) + min
end
else
elsif width > natural_width
# Expand the table to fit the requested width.
f = (width - cells.width).to_f / (cells.max_width - cells.width)

(0...column_length).map do |c|
nat, max = column(c).width, column(c).max_width
(f * (max - nat)) + nat
end
else
natural_column_widths
end
end
end
Expand All @@ -179,7 +202,15 @@ def row_heights
end

def set_column_widths
column_widths.each_with_index { |w, col_num| column(col_num).width = w }
column_widths.each_with_index do |w, col_num|
# Believe it or not, this unless statement actually prevents a whole
# host of FP rounding errors. Doing "x.width = x.content_width +
# x.padding" (in effect, what this code does if the widths aren't being
# touched) introduces FP errors.
unless column(col_num).width == w
column(col_num).width = w
end
end
end

def set_row_heights
Expand All @@ -195,6 +226,8 @@ def position_cells
ary << (ary.last + x); ary }[0..-2]
x_positions.each_with_index { |x, i| column(i).x = x }

# y-positions assume an infinitely long canvas -- this is corrected for
# in Table#draw, and page breaks are properly inserted.
y_positions = row_heights.inject([@pdf.cursor]) { |ary, y|
ary << (ary.last - y); ary}[0..-2]
y_positions.each_with_index { |y, i| row(i).y = y }
Expand Down
15 changes: 15 additions & 0 deletions spec/table_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,21 @@
end
end

describe "Multi-page tables" do
it "should flow to the next page when hitting the bottom of the bounds" do
Prawn::Document.new { table([["foo"]] * 30) }.page_count.should == 1
Prawn::Document.new { table([["foo"]] * 31) }.page_count.should == 2
end

it "should respect the containing bounds" do
Prawn::Document.new do
bounding_box([0, cursor], :width => bounds.width, :height => 72) do
table([["foo"]] * 4)
end
end.page_count.should == 2
end
end

describe "#style" do
it "should send #style to its first argument, passing the style hash and" +
" block" do
Expand Down

0 comments on commit 0388bf6

Please sign in to comment.