jerryvos-prawn-layout 0.2.0.3 → 0.2.0.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.
- data/Rakefile +1 -1
- data/lib/prawn/layout/grid.rb +238 -0
- data/lib/prawn/layout/page.rb +116 -0
- data/lib/prawn/layout.rb +21 -0
- data/lib/prawn/table/cell.rb +287 -0
- data/lib/prawn/table.rb +515 -0
- data/spec/grid_spec.rb +61 -0
- data/spec/page_layout_spec.rb +41 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/table_spec.rb +400 -0
- metadata +10 -1
data/spec/table_spec.rb
ADDED
@@ -0,0 +1,400 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
|
+
|
5
|
+
describe "A table's width" do
|
6
|
+
it "should equal sum(column_widths)" do
|
7
|
+
pdf = Prawn::Document.new
|
8
|
+
table = Prawn::Table.new( [%w[ a b c ], %w[d e f]], pdf,
|
9
|
+
:column_widths => { 0 => 50, 1 => 100, 2 => 150 })
|
10
|
+
|
11
|
+
table.width.should == 300
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should calculate unspecified column widths even " +
|
15
|
+
"with rowspan cells declared (as hashes)" do
|
16
|
+
pdf = Prawn::Document.new
|
17
|
+
hpad, fs = 3, 12
|
18
|
+
# +--------------------+
|
19
|
+
# | foo | foobar |
|
20
|
+
# +--------------------+
|
21
|
+
# | foo | foo | foo |
|
22
|
+
# +--------------------+
|
23
|
+
data = [ [ { :text => 'foo', :colspan => 2 }, "foobar" ],
|
24
|
+
[ "foo", "foo", "foo" ] ]
|
25
|
+
table = Prawn::Table.new( data, pdf,
|
26
|
+
:horizontal_padding => hpad,
|
27
|
+
:font_size => fs )
|
28
|
+
# The relevant cells are:
|
29
|
+
# - (1, 0) "foo"
|
30
|
+
# - (1, 1) "foo"
|
31
|
+
# - (0 ,1) "foobar" [at col 2]
|
32
|
+
cells = %w( foo foo foobar )
|
33
|
+
|
34
|
+
table.width.should == width_table_for( pdf, hpad, fs, cells )
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should calculate unspecified column widths even " +
|
38
|
+
"with rowspan cells declared before another bigger cells" do
|
39
|
+
pdf = Prawn::Document.new
|
40
|
+
hpad, fs = 3, 12
|
41
|
+
# +----------------------------+
|
42
|
+
# | foobarfoobar | foobar |
|
43
|
+
# +----------------------------+
|
44
|
+
# | foo | foo | foo |
|
45
|
+
# | foobarfoo | foo | foo |
|
46
|
+
# +----------------------------+
|
47
|
+
data = [ [ { :text => 'foobarfoobar', :colspan => 2 }, "foobar" ],
|
48
|
+
[ "foo", "foo", "foo" ],
|
49
|
+
[ "foobarfoo", "foo", "foo" ] ]
|
50
|
+
table = Prawn::Table.new( data, pdf,
|
51
|
+
:horizontal_padding => hpad,
|
52
|
+
:font_size => fs )
|
53
|
+
# The relevant cells are:
|
54
|
+
# - (2, 0) "foobarfoo"
|
55
|
+
# - (1, 1) "foo"
|
56
|
+
# - (0, 1) "foobar"
|
57
|
+
cells = %w( foobarfoo foo foobar )
|
58
|
+
|
59
|
+
table.width.should == width_table_for( pdf, hpad, fs, cells )
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should calculate unspecified column widths even when there is a cell " +
|
63
|
+
"with colspan attribute and it's bigger than the other cells of " +
|
64
|
+
"these columns" do
|
65
|
+
pdf = Prawn::Document.new
|
66
|
+
hpad, fs = 3, 12
|
67
|
+
|
68
|
+
# +---------------------------------+
|
69
|
+
# | foobar baz waldo waldo | foobar |
|
70
|
+
# +---------------------------------+
|
71
|
+
# | foo | foo | foo |
|
72
|
+
# +---------------------------------+
|
73
|
+
data = [ [ { :text => 'foobar baz waldo waldo', :colspan => 2 }, "foobar" ],
|
74
|
+
[ "foo", "foo", "foo" ] ]
|
75
|
+
table = Prawn::Table.new( data, pdf,
|
76
|
+
:horizontal_padding => hpad,
|
77
|
+
:font_size => fs )
|
78
|
+
# The relevant cells are:
|
79
|
+
# - (0, 0) "foobar baz waldo waldo"
|
80
|
+
# - (0 ,1) "foobar" [at col 2]
|
81
|
+
cells = %w( foobar\ baz\ waldo\ waldo foobar )
|
82
|
+
|
83
|
+
table.width.should == width_table_for( pdf, hpad, fs, cells )
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should calculate unspecified column widths even when there are cells " +
|
87
|
+
"with rowspain attribute" do
|
88
|
+
pdf = Prawn::Document.new
|
89
|
+
hpad, fs = 3, 12
|
90
|
+
|
91
|
+
# +---------------------------------+
|
92
|
+
# | foobar baz waldo waldo | foobar |
|
93
|
+
# | + -------+
|
94
|
+
# | | foo |
|
95
|
+
# +---------------------------------+
|
96
|
+
data = [ [ { :text => 'foobar baz waldo waldo', :rowspan => 2 }, "foobar" ],
|
97
|
+
[ "foo" ] ]
|
98
|
+
table = Prawn::Table.new( data, pdf,
|
99
|
+
:horizontal_padding => hpad,
|
100
|
+
:font_size => fs )
|
101
|
+
# The relevant cells are:
|
102
|
+
# - (0, 0) "foobar baz waldo waldo"
|
103
|
+
# - (0 ,1) "foobar" [at col 2]
|
104
|
+
cells = %w( foobar\ baz\ waldo\ waldo foobar )
|
105
|
+
|
106
|
+
table.width.should == width_table_for( pdf, hpad, fs, cells )
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should calculate unspecified column widths as "+
|
110
|
+
"(max(string_width).ceil + 2*horizontal_padding)" do
|
111
|
+
pdf = Prawn::Document.new
|
112
|
+
hpad, fs = 3, 12
|
113
|
+
columns = 2
|
114
|
+
table = Prawn::Table.new( [%w[ foo b ], %w[d foobar]], pdf,
|
115
|
+
:horizontal_padding => hpad, :font_size => fs)
|
116
|
+
|
117
|
+
col0_width = pdf.width_of("foo", :size => fs)
|
118
|
+
col1_width = pdf.width_of("foobar", :size => fs)
|
119
|
+
|
120
|
+
table.width.should == col0_width.ceil + col1_width.ceil + 2*columns*hpad
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should allow mixing autocalculated and preset"+
|
124
|
+
"column widths within a single table" do
|
125
|
+
|
126
|
+
pdf = Prawn::Document.new
|
127
|
+
hpad, fs = 10, 6
|
128
|
+
stretchy_columns = 2
|
129
|
+
|
130
|
+
col0_width = 50
|
131
|
+
col1_width = pdf.width_of("foo", :size => fs)
|
132
|
+
col2_width = pdf.width_of("foobar", :size => fs)
|
133
|
+
col3_width = 150
|
134
|
+
|
135
|
+
table = Prawn::Table.new( [%w[snake foo b apple],
|
136
|
+
%w[kitten d foobar banana]], pdf,
|
137
|
+
:horizontal_padding => hpad, :font_size => fs,
|
138
|
+
:column_widths => { 0 => col0_width, 3 => col3_width } )
|
139
|
+
|
140
|
+
table.width.should == col1_width.ceil + col2_width.ceil +
|
141
|
+
2*stretchy_columns*hpad +
|
142
|
+
col0_width.ceil + col3_width.ceil
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should not exceed the maximum width of the margin_box" do
|
147
|
+
|
148
|
+
pdf = Prawn::Document.new
|
149
|
+
expected_width = pdf.margin_box.width
|
150
|
+
|
151
|
+
data = [
|
152
|
+
['This is a column with a lot of text that should comfortably exceed '+
|
153
|
+
'the width of a normal document margin_box width', 'Some more text',
|
154
|
+
'and then some more', 'Just a bit more to be extra sure']
|
155
|
+
]
|
156
|
+
|
157
|
+
table = Prawn::Table.new(data, pdf)
|
158
|
+
|
159
|
+
table.width.should == expected_width
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should not exceed the maximum width of the margin_box even with manual widths specified" do
|
164
|
+
|
165
|
+
pdf = Prawn::Document.new
|
166
|
+
expected_width = pdf.margin_box.width
|
167
|
+
|
168
|
+
data = [
|
169
|
+
['This is a column with a lot of text that should comfortably exceed '+
|
170
|
+
'the width of a normal document margin_box width', 'Some more text',
|
171
|
+
'and then some more', 'Just a bit more to be extra sure']
|
172
|
+
]
|
173
|
+
|
174
|
+
|
175
|
+
table = Prawn::Table.new(data, pdf, :column_widths => { 1 => 100 })
|
176
|
+
|
177
|
+
table.width.should == expected_width
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should be the width of the :width parameter" do
|
182
|
+
|
183
|
+
pdf = Prawn::Document.new
|
184
|
+
expected_width = 300
|
185
|
+
|
186
|
+
table = Prawn::Table.new( [%w[snake foo b apple],
|
187
|
+
%w[kitten d foobar banana]], pdf,
|
188
|
+
:width => expected_width
|
189
|
+
)
|
190
|
+
|
191
|
+
table.width.should == expected_width
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should not exceed the :width option" do
|
196
|
+
|
197
|
+
pdf = Prawn::Document.new
|
198
|
+
expected_width = 400
|
199
|
+
|
200
|
+
data = [
|
201
|
+
['This is a column with a lot of text that should comfortably exceed '+
|
202
|
+
'the width of a normal document margin_box width', 'Some more text',
|
203
|
+
'and then some more', 'Just a bit more to be extra sure']
|
204
|
+
]
|
205
|
+
|
206
|
+
table = Prawn::Table.new(data, pdf, :width => expected_width)
|
207
|
+
|
208
|
+
table.width.should == expected_width
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should not exceed the :width option even with manual widths specified" do
|
213
|
+
|
214
|
+
pdf = Prawn::Document.new
|
215
|
+
expected_width = 400
|
216
|
+
|
217
|
+
data = [
|
218
|
+
['This is a column with a lot of text that should comfortably exceed '+
|
219
|
+
'the width of a normal document margin_box width', 'Some more text',
|
220
|
+
'and then some more', 'Just a bit more to be extra sure']
|
221
|
+
]
|
222
|
+
|
223
|
+
table = Prawn::Table.new(data, pdf, :column_widths => { 1 => 100 }, :width => expected_width)
|
224
|
+
|
225
|
+
table.width.should == expected_width
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "A table's height" do
|
232
|
+
|
233
|
+
before :each do
|
234
|
+
data = [["foo"],["bar"],["baaaz"]]
|
235
|
+
pdf = Prawn::Document.new
|
236
|
+
@num_rows = data.length
|
237
|
+
|
238
|
+
@vpad = 4
|
239
|
+
origin = pdf.y
|
240
|
+
pdf.table data, :vertical_padding => @vpad
|
241
|
+
|
242
|
+
@table_height = origin - pdf.y
|
243
|
+
|
244
|
+
@font_height = pdf.font.height
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should have a height of n rows" do
|
248
|
+
@table_height.should.be.close(
|
249
|
+
@num_rows*@font_height + 2*@vpad*@num_rows, 0.001 )
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
describe "A table's content" do
|
255
|
+
|
256
|
+
it "should not cause an error if rendering the very first row causes a page break" do
|
257
|
+
Prawn::Document.new( :page_layout => :portrait ) do
|
258
|
+
arr = Array(1..5).collect{|i| ["cell #{i}"] }
|
259
|
+
|
260
|
+
move_down( y - (bounds.absolute_bottom + 3) )
|
261
|
+
|
262
|
+
lambda {
|
263
|
+
table( arr,
|
264
|
+
:font_size => 9,
|
265
|
+
:horizontal_padding => 3,
|
266
|
+
:vertical_padding => 3,
|
267
|
+
:border_width => 0.05,
|
268
|
+
:border_style => :none,
|
269
|
+
:row_colors => %w{ffffff eeeeee},
|
270
|
+
:column_widths => {0 =>110},
|
271
|
+
:position => :left,
|
272
|
+
:headers => ["exploding header"],
|
273
|
+
:align => :left,
|
274
|
+
:align_headers => :center)
|
275
|
+
}.should.not.raise
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should output content cell by cell, row by row" do
|
280
|
+
data = [["foo","bar"],["baz","bang"]]
|
281
|
+
@pdf = Prawn::Document.new
|
282
|
+
@pdf.table(data)
|
283
|
+
output = PDF::Inspector::Text.analyze(@pdf.render)
|
284
|
+
output.strings.should == data.flatten
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should add headers to output when specified" do
|
288
|
+
data = [["foo","bar"],["baz","bang"]]
|
289
|
+
headers = %w[a b]
|
290
|
+
@pdf = Prawn::Document.new
|
291
|
+
@pdf.table(data, :headers => headers)
|
292
|
+
output = PDF::Inspector::Text.analyze(@pdf.render)
|
293
|
+
output.strings.should == headers + data.flatten
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should repeat headers across pages" do
|
297
|
+
data = [["foo","bar"]]*30
|
298
|
+
headers = ["baz","foobar"]
|
299
|
+
@pdf = Prawn::Document.new
|
300
|
+
@pdf.table(data, :headers => headers)
|
301
|
+
output = PDF::Inspector::Text.analyze(@pdf.render)
|
302
|
+
output.strings.should == headers + data.flatten[0..-3] + headers +
|
303
|
+
data.flatten[-2..-1]
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should allow empty fields" do
|
307
|
+
lambda {
|
308
|
+
data = [["foo","bar"],["baz",""]]
|
309
|
+
@pdf = Prawn::Document.new
|
310
|
+
@pdf.table(data)
|
311
|
+
}.should.not.raise
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should paginate for large tables" do
|
315
|
+
# 30 rows fit on the table with default setting, 31 exceed.
|
316
|
+
data = [["foo"]] * 31
|
317
|
+
pdf = Prawn::Document.new
|
318
|
+
|
319
|
+
pdf.table data
|
320
|
+
pdf.page_count.should == 2
|
321
|
+
|
322
|
+
pdf.table data
|
323
|
+
pdf.page_count.should == 3
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should accurately count columns from data" do
|
327
|
+
# First data row may contain colspan which would hide true column count
|
328
|
+
data = [["Name:",{:text => "Some very long name", :colspan => 5}]]
|
329
|
+
pdf = Prawn::Document.new
|
330
|
+
table = Prawn::Table.new data, pdf
|
331
|
+
table.column_widths.length.should == 6
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
describe "An invalid table" do
|
337
|
+
|
338
|
+
before(:each) do
|
339
|
+
@pdf = Prawn::Document.new
|
340
|
+
@bad_data = ["Single Nested Array"]
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should raise error when invalid table data is given" do
|
344
|
+
|
345
|
+
assert_raises(Prawn::Errors::InvalidTableData) do
|
346
|
+
@pdf.table(@bad_data)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should raise an EmptyTableError with empty table data" do
|
351
|
+
lambda {
|
352
|
+
data = []
|
353
|
+
@pdf = Prawn::Document.new
|
354
|
+
@pdf.table(data)
|
355
|
+
}.should.raise( Prawn::Errors::EmptyTable )
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should raise an EmptyTableError with nil table data" do
|
359
|
+
lambda {
|
360
|
+
data = nil
|
361
|
+
@pdf = Prawn::Document.new
|
362
|
+
@pdf.table(data)
|
363
|
+
}.should.raise( Prawn::Errors::EmptyTable )
|
364
|
+
end
|
365
|
+
|
366
|
+
it "should raise an InvalidTableData with bad formed data" do
|
367
|
+
lambda {
|
368
|
+
data = [ [ 'a', 'b' ], [ 'c' ] ]
|
369
|
+
@pdf.table( data )
|
370
|
+
}.should.raise( Prawn::Errors::InvalidTableData )
|
371
|
+
|
372
|
+
lambda {
|
373
|
+
data = [ [ 'a' ], [ 'b', 'c' ] ]
|
374
|
+
@pdf.table( data )
|
375
|
+
}.should.raise( Prawn::Errors::InvalidTableData )
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should raise an InvalidTableData with bad formed data even with " +
|
379
|
+
"either rowspan or colspan cells" do
|
380
|
+
lambda {
|
381
|
+
data = [ [ { :rowspan => 2, :text => 'a' }, 'b' ],
|
382
|
+
[ 'c', 'd' ] ]
|
383
|
+
@pdf.table( data )
|
384
|
+
}.should.raise( Prawn::Errors::InvalidTableData )
|
385
|
+
|
386
|
+
lambda {
|
387
|
+
data = [ [ { :rowspan => 2, :text => 'a' },
|
388
|
+
{ :rowspan => 2, :text => 'b' } ],
|
389
|
+
[ 'c', 'd', 'e', 'f', 'g' ] ]
|
390
|
+
@pdf.table( data )
|
391
|
+
}.should.raise( Prawn::Errors::InvalidTableData )
|
392
|
+
|
393
|
+
lambda {
|
394
|
+
data = [ [ { :rowspan => 2, :text => 'a' },
|
395
|
+
{ :colspan => 2, :text => 'b' } ],
|
396
|
+
[ 'c', 'd', 'e' ] ]
|
397
|
+
@pdf.table( data )
|
398
|
+
}.should.raise( Prawn::Errors::InvalidTableData )
|
399
|
+
end
|
400
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jerryvos-prawn-layout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0.
|
4
|
+
version: 0.2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregory Brown
|
@@ -22,6 +22,15 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
+
- lib/prawn/layout/grid.rb
|
26
|
+
- lib/prawn/layout/page.rb
|
27
|
+
- lib/prawn/layout.rb
|
28
|
+
- lib/prawn/table/cell.rb
|
29
|
+
- lib/prawn/table.rb
|
30
|
+
- spec/grid_spec.rb
|
31
|
+
- spec/page_layout_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
- spec/table_spec.rb
|
25
34
|
- Rakefile
|
26
35
|
has_rdoc: true
|
27
36
|
homepage: http://prawn.majesticseacreature.com
|