jyurek-prawn-layout 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Demonstrates various table and cell features.
4
+ #
5
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
6
+
7
+ headers, body = nil, nil
8
+
9
+ dir = File.expand_path(File.dirname(__FILE__))
10
+
11
+ ruby_18 do
12
+ require "fastercsv"
13
+ headers, *body = FasterCSV.read("#{dir}/addressbook.csv")
14
+ end
15
+
16
+ ruby_19 do
17
+ require "csv"
18
+ headers, *body = CSV.read("#{dir}/addressbook.csv",
19
+ :encoding => "utf-8")
20
+ end
21
+
22
+ Prawn::Document.generate("fancy_table.pdf", :page_layout => :landscape) do
23
+
24
+ #font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
25
+
26
+ mask(:y) { table body, :headers => headers,
27
+ :align => :center,
28
+ :border_style => :grid }
29
+
30
+ table [["This is", "A Test" ],
31
+ [ Prawn::Table::Cell.new( :text => "Of tables",
32
+ :background_color => "ffccff" ),
33
+ "Drawn Side"], ["By side", "and stuff" ]],
34
+ :position => 600,
35
+ :headers => ["Col A", "Col B"],
36
+ :border_width => 1,
37
+ :vertical_padding => 5,
38
+ :horizontal_padding => 3,
39
+ :font_size => 10,
40
+ :row_colors => :pdf_writer,
41
+ :column_widths => { 1 => 50 }
42
+
43
+ move_down 150
44
+
45
+ table [%w[1 2 3],%w[4 5 6],%w[7 8 9]],
46
+ :position => :center,
47
+ :border_width => 0,
48
+ :font_size => 40
49
+
50
+ cell [500,300],
51
+ :text => "This free flowing textbox shows how you can use Prawn's "+
52
+ "cells outside of a table with ease. Think of a 'cell' as " +
53
+ "simply a limited purpose bounding box that is meant for laying " +
54
+ "out blocks of text and optionally placing a border around it",
55
+ :width => 225, :padding => 10, :border_width => 2
56
+
57
+ font_size 24
58
+
59
+ cell [50,75],
60
+ :text => "This document demonstrates a number of Prawn's table features",
61
+ :border_style => :no_top, # :all, :no_bottom, :sides
62
+ :horizontal_padding => 5
63
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Generates a couple simple tables, including some UTF-8 text cells.
4
+ # Although this does not show all of the options available to table, the most
5
+ # common are used here. See fancy_table.rb for a more comprehensive example.
6
+ #
7
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
8
+
9
+ Prawn::Document.generate("table.pdf") do
10
+ font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
11
+ table [["ὕαλον ϕαγεῖν", "baaar", "1" ],
12
+ ["This is","a sample", "2" ],
13
+ ["Table", "dont\ncha\nknow?", "3" ],
14
+ [ "It", "Rules", "4" ],
15
+ [ "It", "Rules", "4" ],
16
+ [ "It", "Rules", "4123231" ],
17
+ [ "It", "Rules", "22.5" ],
18
+ [ "It", "Rules", "4" ],
19
+ [ "It", "Rules", "4" ],
20
+ [ "It", "Rules", "4" ],
21
+ [ "It", "Rules", "4" ],
22
+ [ "It", "Rules", "4" ],
23
+ [ "It", "Rules\nwith an iron fist", "x" ],
24
+ [ "It", "Rules", "4" ],
25
+ [ "It", "Rules", "4" ],
26
+ [ "It", "Rules", "4" ],
27
+ [ "It", "Rules", "4" ],
28
+ [ "It", "Rules", "4" ],
29
+ [ "It", "Rules", "4" ],
30
+ [ "It", "Rules", "4" ],
31
+ [ "It", "Rules", "4" ],
32
+ [ "It", "Rules", "4" ]],
33
+
34
+ :font_size => 24,
35
+ :horizontal_padding => 10,
36
+ :vertical_padding => 3,
37
+ :border_width => 2,
38
+ :position => :center,
39
+ :headers => ["Column A","Column B","#"],
40
+ :align => {1 => :center},
41
+ :align_headers => :center
42
+
43
+ text "This should appear in the original font size, just below the table"
44
+ move_down 10
45
+
46
+ table [[ "Wide", "columns", "streeetch"],
47
+ ["are","mighty fine", "streeeeeeeech"]],
48
+ :column_widths => { 0 => 200, 1 => 200 }, :position => 5
49
+
50
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Demonstrates the many controls over alignment and positioning in Prawn
4
+ # tables.
5
+ #
6
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
7
+
8
+ Prawn::Document.generate "table_header_align.pdf" do
9
+ table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
10
+ ['01/12/2008', 'Jane Doe', '3.2', { :text => '75.5', :align => :center }, '241.60'] ] * 20,
11
+ :position => :center,
12
+ :headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
13
+ :column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
14
+ :border_style => :grid,
15
+ :align => { 0 => :right, 1 => :left, 2 => :right, 3 => :right, 4 => :right },
16
+ :align_headers => { 0 => :center, 2 => :left, 3 => :left, 4 => :right }
17
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Demonstrates how to set the table border color with the :border_color
4
+ # attribute.
5
+ #
6
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
7
+
8
+ Prawn::Document.generate "table_border_color.pdf" do
9
+ table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
10
+ ['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 20,
11
+ :position => :center,
12
+ :headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
13
+ :column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
14
+ :border_style => :grid,
15
+ :border_color => "ff0000"
16
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Demonstrates the use of the :col_span option when using Document#table
4
+ #
5
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
6
+
7
+ Prawn::Document.generate "table_colspan.pdf" do
8
+ data = [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
9
+ ['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 5
10
+
11
+ data << [{:text => 'Total', :colspan => 2, :align => :center}, '37.0', '1002.5', '3833']
12
+
13
+ table data,
14
+ :position => :center,
15
+ :headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
16
+ :column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
17
+ :border_style => :grid
18
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Demonstrates explicitly setting the :header_color rather than inferring
4
+ # it from :row_colors in Document#table
5
+ #
6
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
7
+
8
+ Prawn::Document.generate "table_header_color.pdf" do
9
+ table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
10
+ ['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 20,
11
+ :position => :center,
12
+ :headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
13
+ :column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
14
+ :border_style => :grid,
15
+ :header_color => 'f07878',
16
+ :header_text_color => "990000",
17
+ :row_colors => ["FFCCFF","CCFFCC"]
18
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Demonstrates the :underline_header border style for Document#table.
4
+ #
5
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
6
+
7
+ Prawn::Document.generate "table_header_underline.pdf" do
8
+ table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
9
+ ['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 5,
10
+ :position => :center,
11
+ :headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
12
+ :column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
13
+ :border_style => :underline_header
14
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Generates a couple simple tables, including some UTF-8 text cells.
4
+ # Although this does not show all of the options available to table, the most
5
+ # common are used here. See fancy_table.rb for a more comprehensive example.
6
+ #
7
+ require "#{File.dirname(__FILE__)}/../example_helper.rb"
8
+
9
+ Prawn::Document.generate("table_widths.pdf") do
10
+
11
+ data = [
12
+ %w(one two three four),
13
+ %w(five six seven eight),
14
+ %w(nine ten eleven twelve),
15
+ %w(thirteen fourteen fifteen sixteen),
16
+ %w(seventeen eighteen nineteen twenty)
17
+ ]
18
+ headers = ["Column A","Column B","Column C", "Column D"]
19
+
20
+ text "A table with a specified width of the document width (within margins)"
21
+ move_down 10
22
+
23
+ table data,
24
+ :position => :center,
25
+ :headers => headers,
26
+ :width => margin_box.width
27
+
28
+
29
+ move_down 20
30
+ text "A table with a specified width of the document width (within margins) and two fixed width columns"
31
+ move_down 10
32
+
33
+ table data,
34
+ :position => :center,
35
+ :headers => headers,
36
+ :width => margin_box.width,
37
+ :column_widths => {0 => 70, 1 => 70}
38
+
39
+
40
+ move_down 20
41
+ text "A table with a specified width of 300"
42
+ move_down 10
43
+
44
+ table data,
45
+ :position => :center,
46
+ :headers => headers,
47
+ :width => 300
48
+
49
+
50
+ move_down 20
51
+ text "A table with too much data is automatically limited to the document width"
52
+ move_down 10
53
+
54
+ data << ['some text', 'A long piece of text that will make this cell too wide for the page', 'some more text', 'And more text']
55
+
56
+ table data,
57
+ :position => :center,
58
+ :headers => headers
59
+
60
+ end
@@ -0,0 +1,21 @@
1
+ require "prawn/table"
2
+ require "prawn/layout/page"
3
+ require 'prawn/layout/grid'
4
+
5
+ module Prawn
6
+
7
+ module Errors
8
+
9
+ # This error is raised when table data is malformed
10
+ #
11
+ InvalidTableData = Class.new(StandardError)
12
+
13
+ # This error is raised when an empty or nil table is rendered
14
+ #
15
+ EmptyTable = Class.new(StandardError)
16
+ end
17
+
18
+ module Layout
19
+
20
+ end
21
+ end
@@ -0,0 +1,260 @@
1
+ module Prawn
2
+ class Document
3
+
4
+ # Defines the grid system for a particular document. Takes the number of
5
+ # rows and columns and the width to use for the gutter as the
6
+ # keys :rows, :columns, :gutter, :row_gutter, :column_gutter
7
+ #
8
+ def define_grid(options = {})
9
+ @grid = Grid.new(self, options)
10
+ end
11
+
12
+ # A method that can either be used to access a particular grid on the page
13
+ # or work with the grid system directly.
14
+ #
15
+ # @pdf.grid # Get the Grid directly
16
+ # @pdf.grid([0,1]) # Get the box at [0,1]
17
+ # @pdf.grid([0,1], [1,2]) # Get a multi-box spanning from [0,1] to [1,2]
18
+ #
19
+ def grid(*args)
20
+ @boxes ||= {}
21
+ @boxes[args] ||= if args.empty?
22
+ @grid
23
+ else
24
+ g1, g2 = args
25
+ if(g1.class == Array && g2.class == Array &&
26
+ g1.length == 2 && g2.length == 2)
27
+ multi_box(single_box(*g1), single_box(*g2))
28
+ else
29
+ single_box(g1, g2)
30
+ end
31
+ end
32
+ end
33
+
34
+ # A Grid represents the entire grid system of a Page and calculates
35
+ # the column width and row height of the base box.
36
+ class Grid
37
+ attr_reader :pdf, :columns, :rows, :gutter, :row_gutter, :column_gutter
38
+ # :nodoc
39
+ def initialize(pdf, options = {})
40
+ valid_options = [:columns, :rows, :gutter, :row_gutter, :column_gutter]
41
+ Prawn.verify_options valid_options, options
42
+
43
+ @pdf = pdf
44
+ @columns = options[:columns]
45
+ @rows = options[:rows]
46
+ set_gutter(options)
47
+ end
48
+
49
+ # Calculates the base width of boxes.
50
+ def column_width
51
+ @column_width ||= subdivide(pdf.bounds.width, columns, column_gutter)
52
+ end
53
+
54
+ # Calculates the base height of boxes.
55
+ def row_height
56
+ @row_height ||= subdivide(pdf.bounds.height, rows, row_gutter)
57
+ end
58
+
59
+ # Diagnostic tool to show all of the grids. Defaults to gray.
60
+ def show_all(color = "CCCCCC")
61
+ self.rows.times do |i|
62
+ self.columns.times do |j|
63
+ pdf.grid(i,j).show(color)
64
+ end
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def subdivide(total, num, gutter)
71
+ (total.to_f - (gutter * (num - 1).to_f)) / num.to_f
72
+ end
73
+
74
+ def set_gutter(options)
75
+ if options.has_key?(:gutter)
76
+ @gutter = options[:gutter].to_f
77
+ @row_gutter, @column_gutter = @gutter, @gutter
78
+ else
79
+ @row_gutter = options[:row_gutter].to_f
80
+ @column_gutter = options[:column_gutter].to_f
81
+ @gutter = 0
82
+ end
83
+ end
84
+ end
85
+
86
+ # A Box is a class that represents a bounded area of a page.
87
+ # A Grid object has methods that allow easy access to the coordinates of
88
+ # its corners, which can be plugged into most existing prawnmethods.
89
+ #
90
+ class Box
91
+ attr_reader :pdf
92
+
93
+ def initialize(pdf, i, j)
94
+ @pdf = pdf
95
+ @i = i
96
+ @j = j
97
+ end
98
+
99
+ # Mostly diagnostic method that outputs the name of a box as
100
+ # col_num, row_num
101
+ #
102
+ def name
103
+ "#{@i.to_s},#{@j.to_s}"
104
+ end
105
+
106
+ # :nodoc
107
+ def total_height
108
+ pdf.bounds.height.to_f
109
+ end
110
+
111
+ # Width of a box
112
+ def width
113
+ grid.column_width.to_f
114
+ end
115
+
116
+ # Height of a box
117
+ def height
118
+ grid.row_height.to_f
119
+ end
120
+
121
+ # Width of the gutter
122
+ def gutter
123
+ grid.gutter.to_f
124
+ end
125
+
126
+ # x-coordinate of left side
127
+ def left
128
+ @left ||= (width + grid.column_gutter) * @j.to_f
129
+ end
130
+
131
+ # x-coordinate of right side
132
+ def right
133
+ @right ||= left + width
134
+ end
135
+
136
+ # y-coordinate of the top
137
+ def top
138
+ @top ||= total_height - ((height + grid.row_gutter) * @i.to_f)
139
+ end
140
+
141
+ # y-coordinate of the bottom
142
+ def bottom
143
+ @bottom ||= top - height
144
+ end
145
+
146
+ # x,y coordinates of top left corner
147
+ def top_left
148
+ [left, top]
149
+ end
150
+
151
+ # x,y coordinates of top right corner
152
+ def top_right
153
+ [right, top]
154
+ end
155
+
156
+ # x,y coordinates of bottom left corner
157
+ def bottom_left
158
+ [left, bottom]
159
+ end
160
+
161
+ # x,y coordinates of bottom right corner
162
+ def bottom_right
163
+ [right, bottom]
164
+ end
165
+
166
+ # Creates a standard bounding box based on the grid box.
167
+ def bounding_box(&blk)
168
+ pdf.bounding_box(top_left, :width => width, :height => height, &blk)
169
+ end
170
+
171
+ # Diagnostic method
172
+ def show(grid_color = "CCCCCC")
173
+ self.bounding_box do
174
+ original_stroke_color = pdf.stroke_color
175
+
176
+ pdf.stroke_color = grid_color
177
+ pdf.text self.name
178
+ pdf.stroke_bounds
179
+
180
+ pdf.stroke_color = original_stroke_color
181
+ end
182
+ end
183
+
184
+ private
185
+ def grid
186
+ pdf.grid
187
+ end
188
+ end
189
+
190
+ # A MultiBox is specified by 2 Boxes and spans the areas between.
191
+ class MultiBox < Box
192
+ def initialize(pdf, b1, b2)
193
+ @pdf = pdf
194
+ @bs = [b1, b2]
195
+ end
196
+
197
+ def name
198
+ @bs.map {|b| b.name}.join(":")
199
+ end
200
+
201
+ def total_height
202
+ @bs[0].total_height
203
+ end
204
+
205
+ def width
206
+ right_box.right - left_box.left
207
+ end
208
+
209
+ def height
210
+ top_box.top - bottom_box.bottom
211
+ end
212
+
213
+ def gutter
214
+ @bs[0].gutter
215
+ end
216
+
217
+ def left
218
+ left_box.left
219
+ end
220
+
221
+ def right
222
+ right_box.right
223
+ end
224
+
225
+ def top
226
+ top_box.top
227
+ end
228
+
229
+ def bottom
230
+ bottom_box.bottom
231
+ end
232
+
233
+ private
234
+ def left_box
235
+ @left_box ||= @bs.min {|a,b| a.left <=> b.left}
236
+ end
237
+
238
+ def right_box
239
+ @right_box ||= @bs.max {|a,b| a.right <=> b.right}
240
+ end
241
+
242
+ def top_box
243
+ @top_box ||= @bs.max {|a,b| a.top <=> b.top}
244
+ end
245
+
246
+ def bottom_box
247
+ @bottom_box ||= @bs.min {|a,b| a.bottom <=> b.bottom}
248
+ end
249
+ end
250
+
251
+ private
252
+ def single_box(i, j)
253
+ Box.new(self, i, j)
254
+ end
255
+
256
+ def multi_box(b1, b2)
257
+ MultiBox.new(self, b1, b2)
258
+ end
259
+ end
260
+ end