Skip to content

Instantly share code, notes, and snippets.

@bradediger
Created February 3, 2009 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradediger/57638 to your computer and use it in GitHub Desktop.
Save bradediger/57638 to your computer and use it in GitHub Desktop.
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