prawn 1.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -0
  3. data/lib/prawn.rb +2 -2
  4. data/lib/prawn/text/box.rb +2 -0
  5. data/lib/prawn/text/formatted/box.rb +46 -21
  6. data/lib/prawn/text/formatted/line_wrap.rb +8 -2
  7. data/lib/prawn/text/formatted/wrap.rb +3 -1
  8. data/manual/contents.rb +1 -1
  9. data/manual/example_helper.rb +0 -1
  10. data/manual/table.rb +16 -0
  11. data/manual/text/text_box_overflow.rb +4 -0
  12. data/prawn.gemspec +2 -3
  13. data/spec/formatted_text_box_spec.rb +22 -0
  14. data/spec/line_wrap_spec.rb +4 -0
  15. data/spec/text_box_spec.rb +28 -0
  16. data/spec/text_spec.rb +19 -0
  17. metadata +6 -50
  18. data/lib/prawn/table.rb +0 -644
  19. data/lib/prawn/table/cell.rb +0 -772
  20. data/lib/prawn/table/cell/image.rb +0 -69
  21. data/lib/prawn/table/cell/in_table.rb +0 -33
  22. data/lib/prawn/table/cell/span_dummy.rb +0 -93
  23. data/lib/prawn/table/cell/subtable.rb +0 -66
  24. data/lib/prawn/table/cell/text.rb +0 -154
  25. data/lib/prawn/table/cells.rb +0 -255
  26. data/lib/prawn/table/column_width_calculator.rb +0 -182
  27. data/manual/table/basic_block.rb +0 -53
  28. data/manual/table/before_rendering_page.rb +0 -26
  29. data/manual/table/cell_border_lines.rb +0 -24
  30. data/manual/table/cell_borders_and_bg.rb +0 -31
  31. data/manual/table/cell_dimensions.rb +0 -30
  32. data/manual/table/cell_text.rb +0 -38
  33. data/manual/table/column_widths.rb +0 -30
  34. data/manual/table/content_and_subtables.rb +0 -39
  35. data/manual/table/creation.rb +0 -27
  36. data/manual/table/filtering.rb +0 -36
  37. data/manual/table/flow_and_header.rb +0 -17
  38. data/manual/table/image_cells.rb +0 -33
  39. data/manual/table/position.rb +0 -29
  40. data/manual/table/row_colors.rb +0 -20
  41. data/manual/table/span.rb +0 -30
  42. data/manual/table/style.rb +0 -22
  43. data/manual/table/table.rb +0 -52
  44. data/manual/table/width.rb +0 -27
  45. data/spec/cell_spec.rb +0 -629
  46. data/spec/table/span_dummy_spec.rb +0 -17
  47. data/spec/table_spec.rb +0 -1527
@@ -1,182 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Prawn
4
- class Table
5
- # @private
6
- class ColumnWidthCalculator
7
- def initialize(cells)
8
- @cells = cells
9
-
10
- @widths_by_column = Hash.new(0)
11
- @rows_with_a_span_dummy = Hash.new(false)
12
-
13
- #calculate for each row if it includes a Cell:SpanDummy
14
- @cells.each do |cell|
15
- @rows_with_a_span_dummy[cell.row] = true if cell.is_a?(Cell::SpanDummy)
16
- end
17
- end
18
-
19
- # does this row include a Cell:SpanDummy?
20
- #
21
- # @param row - the row that should be checked for Cell:SpanDummy elements
22
- #
23
- def has_a_span_dummy?(row)
24
- @rows_with_a_span_dummy[row]
25
- end
26
-
27
- # helper method
28
- # column widths are stored in the values array
29
- # a cell may span cells whose value is only partly given
30
- # this function handles this special case
31
- #
32
- # @param values - The columns widths calculated up until now
33
- # @param cell - The current cell
34
- # @param index - The current column
35
- # @param meth - Meth (min/max); used to calculate values to be filled
36
- #
37
- def fill_values_if_needed(values, cell, index, meth)
38
- #have all spanned indices been filled with a value?
39
- #e.g. values[0], values[1] and values[2] don't return nil given a index of 0 and a colspan of 3
40
- number_of_nil_values = 0
41
- cell.colspan.times do |i|
42
- number_of_nil_values += 1 if values[index+i].nil?
43
- end
44
-
45
- #nothing to do? because
46
- #a) all values are filled
47
- return values if number_of_nil_values == 0
48
- #b) no values are filled
49
- return values if number_of_nil_values == cell.colspan
50
- #c) I am not sure why this line is needed FIXXME
51
- #some test cases manage to this line even though there is no dummy cell in the row
52
- #I'm not sure if this is a sign for a further underlying bug.
53
- return values unless has_a_span_dummy?(cell.row)
54
- #fill up the values array
55
-
56
- #calculate the new sum
57
- new_sum = cell.send(meth) * cell.colspan
58
- #substract any calculated values
59
- cell.colspan.times do |i|
60
- new_sum -= values[index+i] unless values[index+i].nil?
61
- end
62
-
63
- #calculate value for the remaining - not yet filled - cells.
64
- new_value = new_sum.to_f / number_of_nil_values
65
- #fill the not yet filled cells
66
- cell.colspan.times do |i|
67
- values[index+i] = new_value if values[index+i].nil?
68
- end
69
- return values
70
- end
71
-
72
- def natural_widths
73
- #calculate natural column width for all rows that do not include a span dummy
74
- @cells.each do |cell|
75
- unless has_a_span_dummy?(cell.row)
76
- @widths_by_column[cell.column] =
77
- [@widths_by_column[cell.column], cell.width.to_f].max
78
- end
79
- end
80
-
81
- #integrate natural column widths for all rows that do include a span dummy
82
- @cells.each do |cell|
83
- next unless has_a_span_dummy?(cell.row)
84
- #the width of a SpanDummy cell will be calculated by the "mother" cell
85
- next if cell.is_a?(Cell::SpanDummy)
86
-
87
- if cell.colspan == 1
88
- @widths_by_column[cell.column] =
89
- [@widths_by_column[cell.column], cell.width.to_f].max
90
- else
91
- #calculate the current with of all cells that will be spanned by the current cell
92
- current_width_of_spanned_cells =
93
- @widths_by_column.to_a[cell.column..(cell.column + cell.colspan - 1)]
94
- .collect{|key, value| value}.inject(0, :+)
95
-
96
- #update the Hash only if the new with is at least equal to the old one
97
- #due to arithmetic errors we need to ignore a small difference in the new and the old sum
98
- #the same had to be done in the column_widht_calculator#natural_width
99
- update_hash = ((cell.width.to_f - current_width_of_spanned_cells) >
100
- Prawn::FLOAT_PRECISION)
101
-
102
- if update_hash
103
- # Split the width of colspanned cells evenly by columns
104
- width_per_column = cell.width.to_f / cell.colspan
105
- # Update the Hash
106
- cell.colspan.times do |i|
107
- @widths_by_column[cell.column + i] = width_per_column
108
- end
109
- end
110
- end
111
- end
112
-
113
- @widths_by_column.sort_by { |col, _| col }.map { |_, w| w }
114
- end
115
-
116
- # get column widths (either min or max depending on meth)
117
- # used in cells.rb
118
- #
119
- # @param row_or_column - you may call this on either rows or columns
120
- # @param meth - min/max
121
- # @param aggregate - functions from cell.rb to be used to aggregate e.g. avg_spanned_min_width
122
- #
123
- def aggregate_cell_values(row_or_column, meth, aggregate)
124
- values = {}
125
-
126
- #calculate values for all cells that do not span accross multiple cells
127
- #this ensures that we don't have a problem if the first line includes
128
- #a cell that spans across multiple cells
129
- @cells.each do |cell|
130
- #don't take spanned cells
131
- if cell.colspan == 1 and cell.class != Prawn::Table::Cell::SpanDummy
132
- index = cell.send(row_or_column)
133
- values[index] = [values[index], cell.send(meth)].compact.send(aggregate)
134
- end
135
- end
136
-
137
- # if there are only colspanned or rowspanned cells in a table
138
- spanned_width_needs_fixing = true
139
-
140
- @cells.each do |cell|
141
- index = cell.send(row_or_column)
142
- if cell.colspan > 1
143
- #special treatment if some but not all spanned indices in the values array have been calculated
144
- #only applies to rows
145
- values = fill_values_if_needed(values, cell, index, meth) if row_or_column == :column
146
- #calculate current (old) return value before we do anything
147
- old_sum = 0
148
- cell.colspan.times { |i|
149
- old_sum += values[index+i] unless values[index+i].nil?
150
- }
151
-
152
- #calculate future return value
153
- new_sum = cell.send(meth) * cell.colspan
154
-
155
- #due to float rounding errors we need to ignore a small difference in the new
156
- #and the old sum the same had to be done in
157
- #the column_width_calculator#natural_width
158
- spanned_width_needs_fixing = ((new_sum - old_sum) > Prawn::FLOAT_PRECISION)
159
-
160
- if spanned_width_needs_fixing
161
- #not entirely sure why we need this line, but with it the tests pass
162
- values[index] = [values[index], cell.send(meth)].compact.send(aggregate)
163
- #overwrite the old values with the new ones, but only if all entries existed
164
- entries_exist = true
165
- cell.colspan.times { |i| entries_exist = false if values[index+i].nil? }
166
- cell.colspan.times { |i|
167
- values[index+i] = cell.send(meth) if entries_exist
168
- }
169
- end
170
- else
171
- if spanned_width_needs_fixing && cell.class == Prawn::Table::Cell::SpanDummy
172
- values[index] = [values[index], cell.send(meth)].compact.send(aggregate)
173
- end
174
- end
175
- end
176
-
177
- return values.values.inject(0, &:+)
178
- end
179
- end
180
-
181
- end
182
- end
@@ -1,53 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # All of the previous styling options we've seen deal with all the table cells
4
- # at once.
5
- #
6
- # With initializer blocks we may deal with specific cells.
7
- # A block passed to one of the table methods (<code>Prawn::Table.new</code>,
8
- # <code>Prawn::Document#table</code>, <code>Prawn::Document#make_table</code>)
9
- # will be called after cell setup but before layout. This is a very flexible way
10
- # to specify styling and layout constraints.
11
- #
12
- # Just like the <code>Prawn::Document.generate</code> method, the table
13
- # initializer blocks may be used with and without a block argument.
14
- #
15
- # The table class has three methods that are handy within an initializer block:
16
- # <code>cells</code>, <code>rows</code> and <code>columns</code>. All three
17
- # return an instance of <code>Prawn::Table::Cells</code> which represents
18
- # a selection of cells.
19
- #
20
- # <code>cells</code> return all the table cells, while <code>rows</code> and
21
- # <code>columns</code> accept a number or a range as argument which returns a
22
- # single row/column or a range of rows/columns respectively. (<code>rows</code>
23
- # and <code>columns</code> are also aliased as <code>row</code> and
24
- # <code>column</code>)
25
- #
26
- # The <code>Prawn::Table::Cells</code> class also defines <code>rows</code> and
27
- # <code>columns</code> so they may be chained to narrow the selection of cells.
28
- #
29
- # All of the cell styling options we've seen on previous examples may be set as
30
- # properties of the selection of cells.
31
- #
32
- require File.expand_path(File.join(File.dirname(__FILE__),
33
- %w[.. example_helper]))
34
-
35
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
36
- Prawn::ManualBuilder::Example.generate(filename) do
37
- data = [ ["Header", "A " * 5, "B"],
38
- ["Data row", "C", "D " * 5],
39
- ["Another data row", "E", "F"]]
40
-
41
- table(data) do
42
- cells.padding = 12
43
- cells.borders = []
44
-
45
- row(0).borders = [:bottom]
46
- row(0).border_width = 2
47
- row(0).font_style = :bold
48
-
49
- columns(0..1).borders = [:right]
50
-
51
- row(0).columns(0..1).borders = [:bottom, :right]
52
- end
53
- end
@@ -1,26 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # <code>Prawn::Table#initialize</code> takes a
4
- # <code>:before_rendering_page</code> argument, to adjust the way an entire page
5
- # of table cells is styled. This allows you to do things like draw a border
6
- # around the entire table as displayed on a page.
7
- #
8
- # The callback is passed a Cells object that is numbered based on the order of
9
- # the cells on the page (e.g., the first row on the page is
10
- # <code>cells.row(0)</code>).
11
- #
12
- require File.expand_path(File.join(File.dirname(__FILE__),
13
- %w[.. example_helper]))
14
-
15
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
16
- Prawn::ManualBuilder::Example.generate(filename) do
17
- table([["foo", "bar", "baz"]] * 40) do |t|
18
- t.cells.border_width = 1
19
- t.before_rendering_page do |page|
20
- page.row(0).border_top_width = 3
21
- page.row(-1).border_bottom_width = 3
22
- page.column(0).border_left_width = 3
23
- page.column(-1).border_right_width = 3
24
- end
25
- end
26
- end
@@ -1,24 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # The <code>border_lines</code> option accepts an array with the styles of the
4
- # border sides. The default is <code>[:solid, :solid, :solid, :solid]</code>.
5
- #
6
- # <code>border_lines</code> must be set to an array.
7
- #
8
- require File.expand_path(File.join(File.dirname(__FILE__),
9
- %w[.. example_helper]))
10
-
11
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
12
- Prawn::ManualBuilder::Example.generate(filename) do
13
- data = [ ["Look at how the cell border lines can be mixed", "", ""],
14
- ["dotted top border", "", ""],
15
- ["solid right border", "", ""],
16
- ["dotted bottom border", "", ""],
17
- ["dashed left border", "", ""]
18
- ]
19
-
20
- text "Cell :border_lines => [:dotted, :solid, :dotted, :dashed]"
21
-
22
- table(data, :cell_style =>
23
- { :border_lines => [:dotted, :solid, :dotted, :dashed] })
24
- end
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # The <code>borders</code> option accepts an array with the border sides that
4
- # will be drawn. The default is <code>[:top, :bottom, :left, :right]</code>.
5
- #
6
- # <code>border_width</code> may be set with a numeric value.
7
- #
8
- # Both <code>border_color</code> and <code>background_color</code> accept an
9
- # HTML like RGB color string ("FF0000")
10
- #
11
- require File.expand_path(File.join(File.dirname(__FILE__),
12
- %w[.. example_helper]))
13
-
14
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
15
- Prawn::ManualBuilder::Example.generate(filename) do
16
- data = [ ["Look at how the cells will look when styled", "", ""],
17
- ["They probably won't look the same", "", ""]
18
- ]
19
-
20
- { :borders => [:top, :left],
21
- :border_width => 3,
22
- :border_color => "FF0000"}.each do |property, value|
23
-
24
- text "Cell #{property}: #{value.inspect}"
25
- table(data, :cell_style => {property => value})
26
- move_down 20
27
- end
28
-
29
- text "Cell background_color: FFFFCC"
30
- table(data, :cell_style => {:background_color => "FFFFCC"})
31
- end
@@ -1,30 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # To style all the table cells you can use the <code>:cell_style</code> option
4
- # with the table methods. It accepts a hash with the cell style options.
5
- #
6
- # Some straightforward options are <code>width</code>, <code>height</code>,
7
- # and <code>padding</code>. All three accept numeric values to set the property.
8
- #
9
- # <code>padding</code> also accepts a four number array that defines the padding
10
- # in a CSS like syntax setting the top, right, bottom, left sequentially. The
11
- # default is 5pt for all sides.
12
- #
13
- require File.expand_path(File.join(File.dirname(__FILE__),
14
- %w[.. example_helper]))
15
-
16
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
17
- Prawn::ManualBuilder::Example.generate(filename) do
18
- data = [ ["Look at how the cells will look when styled", "", ""],
19
- ["They probably won't look the same", "", ""]
20
- ]
21
-
22
- {:width => 160, :height => 50, :padding => 12}.each do |property, value|
23
- text "Cell's #{property}: #{value}"
24
- table(data, :cell_style => {property => value})
25
- move_down 20
26
- end
27
-
28
- text "Padding can also be set with an array: [0, 0, 0, 30]"
29
- table(data, :cell_style => {:padding => [0, 0, 0, 30]})
30
- end
@@ -1,38 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Text cells accept the following options: <code>align</code>,
4
- # <code>font</code>, <code>font_style</code>, <code>inline_format</code>,
5
- # <code>kerning</code>, <code>leading</code>, <code>min_font_size</code>,
6
- # <code>overflow</code>, <code>rotate</code>, <code>rotate_around</code>,
7
- # <code>single_line</code>, <code>size</code>, <code>text_color</code>,
8
- # and <code>valign</code>.
9
- #
10
- # Most of these style options are direct translations from the text methods
11
- # styling options.
12
- #
13
- require File.expand_path(File.join(File.dirname(__FILE__),
14
- %w[.. example_helper]))
15
-
16
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
17
- Prawn::ManualBuilder::Example.generate(filename) do
18
- data = [ ["Look at how the cells will look when styled", "", ""],
19
- ["They probably won't look the same", "", ""]
20
- ]
21
-
22
- table data, :cell_style => { :font => "Times-Roman", :font_style => :italic }
23
- move_down 20
24
-
25
- table data, :cell_style => { :size => 18, :text_color => "346842" }
26
- move_down 20
27
-
28
- table [["Just <font size='18'>some</font> <b><i>inline</i></b>", "", ""],
29
- ["<color rgb='FF00FF'>styles</color> being applied here", "", ""]],
30
- :cell_style => { :inline_format => true }
31
- move_down 20
32
-
33
- table [["1", "2", "3", "rotate"]], :cell_style => { :rotate => 30 }
34
- move_down 20
35
-
36
- table data, :cell_style => { :overflow => :shrink_to_fit, :min_font_size => 8,
37
- :width => 60, :height => 30 }
38
- end
@@ -1,30 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Prawn will make its best attempt to identify the best width for the columns.
4
- # If the end result isn't good, we can override it with some styling.
5
- #
6
- # Individual column widths can be set with the <code>:column_widths</code>
7
- # option. Just provide an array with the sequential width values for the columns
8
- # or a hash were each key-value pair represents the column 0-based index and its
9
- # width.
10
- #
11
- require File.expand_path(File.join(File.dirname(__FILE__),
12
- %w[.. example_helper]))
13
-
14
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
15
- Prawn::ManualBuilder::Example.generate(filename) do
16
- data = [ ["this is not quite as long as the others",
17
- "here we have a line that is long but with smaller words",
18
- "this is so very looooooooooooooooooooooooooooooong"] ]
19
-
20
- text "Prawn trying to guess the column widths"
21
- table(data)
22
- move_down 20
23
-
24
- text "Manually setting all the column widths"
25
- table(data, :column_widths => [100, 200, 240])
26
- move_down 20
27
-
28
- text "Setting only the last column width"
29
- table(data, :column_widths => {2 => 240})
30
- end
@@ -1,39 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # There are five kinds of objects which can be put in table cells:
4
- # 1. String: produces a text cell (the most common usage)
5
- # 2. <code>Prawn::Table::Cell</code>
6
- # 3. <code>Prawn::Table</code>
7
- # 4. Array
8
- # 5. Images
9
- #
10
- # Whenever a table or an array is provided as a cell, a subtable will be created
11
- # (a table within a cell).
12
- #
13
- # If you'd like to provide a cell or table directly, the best way is to
14
- # use the <code>make_cell</code> and <code>make_table</code> methods as they
15
- # don't call <code>draw</code> on the created object.
16
- #
17
- # To insert an image just provide a hash with an with an <code>:image</code> key
18
- # pointing to the image path.
19
- #
20
- require File.expand_path(File.join(File.dirname(__FILE__),
21
- %w[.. example_helper]))
22
-
23
- filename = File.basename(__FILE__).gsub('.rb', '.pdf')
24
- Prawn::ManualBuilder::Example.generate(filename) do
25
- cell_1 = make_cell(:content => "this row content comes directly ")
26
- cell_2 = make_cell(:content => "from cell objects")
27
-
28
- two_dimensional_array = [ ["..."], ["subtable from an array"], ["..."] ]
29
-
30
- my_table = make_table([ ["..."], ["subtable from another table"], ["..."] ])
31
-
32
- image_path = "#{Prawn::DATADIR}/images/stef.jpg"
33
-
34
- table([ ["just a regular row", "", "", "blah blah blah"],
35
- [cell_1, cell_2, "", ""],
36
- ["", "", two_dimensional_array, ""],
37
- ["just another regular row", "", "", ""],
38
- [{:image => image_path}, "", my_table, ""]])
39
- end