Created
February 3, 2009 17:44
-
-
Save bradediger/57638 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Madriska | |
module Prawn | |
module ColumnLayout | |
# doc.columns %w[70 50% * *] do | |
# doc.column { doc.text "70pt wide" } | |
# doc.column { doc.text "50% of container" } | |
# doc.column { doc.text "Split the remainder" } | |
# doc.column { doc.text "Split the remainder" } | |
# end | |
def columns(column_spec) | |
@columns = distribute_columns(column_spec, bounds.width) | |
@column_x = 0 | |
@column_lowest_y = @y | |
yield | |
@columns = nil | |
@y = @column_lowest_y | |
end | |
def column(&block) | |
width = @columns.shift | |
mask(:y) do | |
bounding_box([@column_x, cursor], :width => width) do | |
block.call | |
@column_lowest_y = [@column_lowest_y, bounds.absolute_bottom].min | |
end | |
end | |
@column_x += width | |
end | |
protected | |
# Distributes the total +width+ given among the array of +columns+. | |
# Syntax is similar to HTML frame specifications; each column can be: | |
# | |
# * Fixed width, such as "200" | |
# * Percentage width, such as "30%" | |
# * Elastic width, indicated by "*". These will stretch to fill the | |
# available space, with all elastic columns having equal width. | |
# | |
# Examples: | |
# | |
# distribute_columns %w[* * * *], 100 # => [25.0, 25.0, 25.0, 25.0] | |
# distribute_columns %w[32% * 19], 133 # => [42.56, 71.44, 19.0] | |
# distribute_columns %w[* 30% *], 800 # => [280.0, 240.0, 280.0] | |
# | |
def distribute_columns(columns, width) | |
raise ArgumentError, "Array expected" unless columns.is_a?(Array) | |
# Calculate floating-point widths of fixed columns | |
fixed_columns = columns.map do |c| | |
case c | |
when /%$/: (c.to_f / 100) * width | |
when "*": nil # elastic column; patched up below | |
else c.to_f | |
end | |
end | |
# Distribute remaining elastic width among elastic columns | |
fixed_width = fixed_columns.compact.inject(0.0){|s,x| s+x} | |
num_elastic_columns = fixed_columns.select{|c| c.nil?}.length | |
elastic_column_width = (width - fixed_width).to_f / num_elastic_columns | |
# Patch elastic width into each elastic column | |
fixed_columns.map{|x| x || elastic_column_width} | |
end | |
end | |
end | |
end | |
require 'prawn' | |
Prawn::Document.send :include, Madriska::Prawn::ColumnLayout |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment