prawn 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/prawn/document/bounding_box.rb +213 -141
  4. data/lib/prawn/document/column_box.rb +61 -26
  5. data/lib/prawn/document/internals.rb +25 -16
  6. data/lib/prawn/document/span.rb +20 -18
  7. data/lib/prawn/document.rb +257 -171
  8. data/lib/prawn/encoding.rb +2 -5
  9. data/lib/prawn/errors.rb +23 -34
  10. data/lib/prawn/font.rb +248 -135
  11. data/lib/prawn/font_metric_cache.rb +11 -10
  12. data/lib/prawn/fonts/afm.rb +85 -45
  13. data/lib/prawn/fonts/dfont.rb +7 -1
  14. data/lib/prawn/fonts/otf.rb +4 -1
  15. data/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
  16. data/lib/prawn/fonts/ttc.rb +7 -2
  17. data/lib/prawn/fonts/ttf.rb +305 -93
  18. data/lib/prawn/fonts.rb +14 -0
  19. data/lib/prawn/graphics/blend_mode.rb +25 -28
  20. data/lib/prawn/graphics/cap_style.rb +9 -12
  21. data/lib/prawn/graphics/color.rb +57 -34
  22. data/lib/prawn/graphics/dash.rb +45 -42
  23. data/lib/prawn/graphics/join_style.rb +17 -11
  24. data/lib/prawn/graphics/patterns.rb +190 -69
  25. data/lib/prawn/graphics/transformation.rb +48 -41
  26. data/lib/prawn/graphics/transparency.rb +16 -40
  27. data/lib/prawn/graphics.rb +363 -253
  28. data/lib/prawn/grid.rb +184 -57
  29. data/lib/prawn/image_handler.rb +27 -10
  30. data/lib/prawn/images/image.rb +8 -10
  31. data/lib/prawn/images/jpg.rb +42 -19
  32. data/lib/prawn/images/png.rb +92 -41
  33. data/lib/prawn/images.rb +44 -57
  34. data/lib/prawn/measurement_extensions.rb +39 -8
  35. data/lib/prawn/measurements.rb +60 -5
  36. data/lib/prawn/outline.rb +114 -108
  37. data/lib/prawn/repeater.rb +51 -35
  38. data/lib/prawn/security/arcfour.rb +4 -4
  39. data/lib/prawn/security.rb +75 -70
  40. data/lib/prawn/soft_mask.rb +42 -30
  41. data/lib/prawn/stamp.rb +38 -42
  42. data/lib/prawn/text/box.rb +146 -96
  43. data/lib/prawn/text/formatted/arranger.rb +87 -26
  44. data/lib/prawn/text/formatted/box.rb +221 -150
  45. data/lib/prawn/text/formatted/fragment.rb +130 -14
  46. data/lib/prawn/text/formatted/line_wrap.rb +33 -24
  47. data/lib/prawn/text/formatted/parser.rb +112 -72
  48. data/lib/prawn/text/formatted/wrap.rb +12 -17
  49. data/lib/prawn/text/formatted.rb +75 -0
  50. data/lib/prawn/text.rb +441 -196
  51. data/lib/prawn/transformation_stack.rb +29 -10
  52. data/lib/prawn/utilities.rb +13 -13
  53. data/lib/prawn/version.rb +2 -1
  54. data/lib/prawn/view.rb +68 -53
  55. data/lib/prawn.rb +23 -18
  56. data.tar.gz.sig +0 -0
  57. metadata +54 -177
  58. metadata.gz.sig +0 -0
  59. data/.yardopts +0 -10
  60. data/Gemfile +0 -5
  61. data/Rakefile +0 -25
  62. data/manual/absolute_position.pdf +0 -0
  63. data/manual/basic_concepts/adding_pages.rb +0 -26
  64. data/manual/basic_concepts/basic_concepts.rb +0 -43
  65. data/manual/basic_concepts/creation.rb +0 -38
  66. data/manual/basic_concepts/cursor.rb +0 -32
  67. data/manual/basic_concepts/measurement.rb +0 -24
  68. data/manual/basic_concepts/origin.rb +0 -37
  69. data/manual/basic_concepts/other_cursor_helpers.rb +0 -39
  70. data/manual/basic_concepts/view.rb +0 -48
  71. data/manual/bounding_box/bounding_box.rb +0 -41
  72. data/manual/bounding_box/bounds.rb +0 -48
  73. data/manual/bounding_box/canvas.rb +0 -23
  74. data/manual/bounding_box/creation.rb +0 -22
  75. data/manual/bounding_box/indentation.rb +0 -45
  76. data/manual/bounding_box/nesting.rb +0 -52
  77. data/manual/bounding_box/russian_boxes.rb +0 -40
  78. data/manual/bounding_box/stretchy.rb +0 -29
  79. data/manual/contents.rb +0 -35
  80. data/manual/cover.rb +0 -43
  81. data/manual/document_and_page_options/background.rb +0 -29
  82. data/manual/document_and_page_options/document_and_page_options.rb +0 -34
  83. data/manual/document_and_page_options/metadata.rb +0 -25
  84. data/manual/document_and_page_options/page_margins.rb +0 -36
  85. data/manual/document_and_page_options/page_size.rb +0 -34
  86. data/manual/document_and_page_options/print_scaling.rb +0 -23
  87. data/manual/example_helper.rb +0 -8
  88. data/manual/graphics/blend_mode.rb +0 -52
  89. data/manual/graphics/circle_and_ellipse.rb +0 -21
  90. data/manual/graphics/color.rb +0 -22
  91. data/manual/graphics/common_lines.rb +0 -29
  92. data/manual/graphics/fill_and_stroke.rb +0 -41
  93. data/manual/graphics/fill_rules.rb +0 -38
  94. data/manual/graphics/gradients.rb +0 -43
  95. data/manual/graphics/graphics.rb +0 -64
  96. data/manual/graphics/helper.rb +0 -34
  97. data/manual/graphics/line_width.rb +0 -36
  98. data/manual/graphics/lines_and_curves.rb +0 -40
  99. data/manual/graphics/polygon.rb +0 -27
  100. data/manual/graphics/rectangle.rb +0 -20
  101. data/manual/graphics/rotate.rb +0 -25
  102. data/manual/graphics/scale.rb +0 -42
  103. data/manual/graphics/soft_masks.rb +0 -44
  104. data/manual/graphics/stroke_cap.rb +0 -30
  105. data/manual/graphics/stroke_dash.rb +0 -47
  106. data/manual/graphics/stroke_join.rb +0 -29
  107. data/manual/graphics/translate.rb +0 -29
  108. data/manual/graphics/transparency.rb +0 -33
  109. data/manual/how_to_read_this_manual.rb +0 -39
  110. data/manual/images/absolute_position.rb +0 -22
  111. data/manual/images/fit.rb +0 -20
  112. data/manual/images/horizontal.rb +0 -24
  113. data/manual/images/images.rb +0 -41
  114. data/manual/images/plain_image.rb +0 -17
  115. data/manual/images/scale.rb +0 -21
  116. data/manual/images/vertical.rb +0 -30
  117. data/manual/images/width_and_height.rb +0 -24
  118. data/manual/layout/boxes.rb +0 -26
  119. data/manual/layout/content.rb +0 -24
  120. data/manual/layout/layout.rb +0 -27
  121. data/manual/layout/simple_grid.rb +0 -22
  122. data/manual/outline/add_subsection_to.rb +0 -60
  123. data/manual/outline/insert_section_after.rb +0 -46
  124. data/manual/outline/outline.rb +0 -33
  125. data/manual/outline/sections_and_pages.rb +0 -66
  126. data/manual/repeatable_content/alternate_page_numbering.rb +0 -36
  127. data/manual/repeatable_content/page_numbering.rb +0 -55
  128. data/manual/repeatable_content/repeatable_content.rb +0 -35
  129. data/manual/repeatable_content/repeater.rb +0 -54
  130. data/manual/repeatable_content/stamp.rb +0 -40
  131. data/manual/security/encryption.rb +0 -28
  132. data/manual/security/permissions.rb +0 -43
  133. data/manual/security/security.rb +0 -28
  134. data/manual/table.rb +0 -16
  135. data/manual/text/alignment.rb +0 -43
  136. data/manual/text/color.rb +0 -24
  137. data/manual/text/column_box.rb +0 -30
  138. data/manual/text/fallback_fonts.rb +0 -41
  139. data/manual/text/font.rb +0 -40
  140. data/manual/text/font_size.rb +0 -44
  141. data/manual/text/font_style.rb +0 -25
  142. data/manual/text/formatted_callbacks.rb +0 -70
  143. data/manual/text/formatted_text.rb +0 -61
  144. data/manual/text/free_flowing_text.rb +0 -50
  145. data/manual/text/inline.rb +0 -40
  146. data/manual/text/kerning_and_character_spacing.rb +0 -38
  147. data/manual/text/leading.rb +0 -24
  148. data/manual/text/line_wrapping.rb +0 -60
  149. data/manual/text/paragraph_indentation.rb +0 -31
  150. data/manual/text/positioned_text.rb +0 -37
  151. data/manual/text/registering_families.rb +0 -51
  152. data/manual/text/rendering_and_color.rb +0 -36
  153. data/manual/text/right_to_left_text.rb +0 -54
  154. data/manual/text/rotation.rb +0 -52
  155. data/manual/text/single_usage.rb +0 -36
  156. data/manual/text/text.rb +0 -75
  157. data/manual/text/text_box_excess.rb +0 -35
  158. data/manual/text/text_box_extensions.rb +0 -48
  159. data/manual/text/text_box_overflow.rb +0 -51
  160. data/manual/text/utf8.rb +0 -27
  161. data/manual/text/win_ansi_charset.rb +0 -62
  162. data/prawn.gemspec +0 -51
  163. data/spec/data/curves.pdf +0 -66
  164. data/spec/extensions/encoding_helpers.rb +0 -11
  165. data/spec/prawn/document/bounding_box_spec.rb +0 -550
  166. data/spec/prawn/document/column_box_spec.rb +0 -75
  167. data/spec/prawn/document/security_spec.rb +0 -176
  168. data/spec/prawn/document_annotations_spec.rb +0 -76
  169. data/spec/prawn/document_destinations_spec.rb +0 -15
  170. data/spec/prawn/document_grid_spec.rb +0 -99
  171. data/spec/prawn/document_reference_spec.rb +0 -27
  172. data/spec/prawn/document_span_spec.rb +0 -44
  173. data/spec/prawn/document_spec.rb +0 -805
  174. data/spec/prawn/font_metric_cache_spec.rb +0 -54
  175. data/spec/prawn/font_spec.rb +0 -544
  176. data/spec/prawn/graphics/blend_mode_spec.rb +0 -63
  177. data/spec/prawn/graphics/transparency_spec.rb +0 -81
  178. data/spec/prawn/graphics_spec.rb +0 -872
  179. data/spec/prawn/graphics_stroke_styles_spec.rb +0 -229
  180. data/spec/prawn/image_handler_spec.rb +0 -53
  181. data/spec/prawn/images/jpg_spec.rb +0 -20
  182. data/spec/prawn/images/png_spec.rb +0 -283
  183. data/spec/prawn/images_spec.rb +0 -229
  184. data/spec/prawn/measurements_extensions_spec.rb +0 -24
  185. data/spec/prawn/outline_spec.rb +0 -512
  186. data/spec/prawn/repeater_spec.rb +0 -166
  187. data/spec/prawn/soft_mask_spec.rb +0 -74
  188. data/spec/prawn/stamp_spec.rb +0 -173
  189. data/spec/prawn/text/box_spec.rb +0 -1110
  190. data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
  191. data/spec/prawn/text/formatted/box_spec.rb +0 -849
  192. data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
  193. data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -495
  194. data/spec/prawn/text/formatted/parser_spec.rb +0 -697
  195. data/spec/prawn/text_draw_text_spec.rb +0 -150
  196. data/spec/prawn/text_rendering_mode_spec.rb +0 -48
  197. data/spec/prawn/text_spacing_spec.rb +0 -95
  198. data/spec/prawn/text_spec.rb +0 -603
  199. data/spec/prawn/text_with_inline_formatting_spec.rb +0 -35
  200. data/spec/prawn/transformation_stack_spec.rb +0 -66
  201. data/spec/prawn/view_spec.rb +0 -63
  202. data/spec/prawn_manual_spec.rb +0 -35
  203. data/spec/spec_helper.rb +0 -48
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # document.rb : Implements PDF document generation for Prawn
4
- #
5
- # Copyright April 2008, Gregory Brown. All Rights Reserved.
6
- #
7
- # This is free software. Please see the LICENSE and COPYING files for details.
8
-
9
3
  require 'stringio'
10
4
 
11
5
  require_relative 'document/bounding_box'
@@ -14,39 +8,45 @@ require_relative 'document/internals'
14
8
  require_relative 'document/span'
15
9
 
16
10
  module Prawn
17
- # The Prawn::Document class is how you start creating a PDF document.
11
+ # The `Prawn::Document` class is how you start creating a PDF document.
18
12
  #
19
13
  # There are three basic ways you can instantiate PDF Documents in Prawn, they
20
- # are through assignment, implicit block or explicit block. Below is an
14
+ # are through assignment, implicit block or explicit block. Below is an
21
15
  # example of each type, each example does exactly the same thing, makes a PDF
22
16
  # document with all the defaults and puts in the default font "Hello There"
23
- # and then saves it to the current directory as "example.pdf"
17
+ # and then saves it to the current directory as _example.pdf_.
24
18
  #
25
19
  # For example, assignment can be like this:
26
20
  #
27
- # pdf = Prawn::Document.new
28
- # pdf.text "Hello There"
29
- # pdf.render_file "example.pdf"
21
+ # ```ruby
22
+ # pdf = Prawn::Document.new
23
+ # pdf.text "Hello There"
24
+ # pdf.render_file "example.pdf"
25
+ # ```
30
26
  #
31
27
  # Or you can do an implied block form:
32
28
  #
33
- # Prawn::Document.generate "example.pdf" do
34
- # text "Hello There"
35
- # end
29
+ # ```ruby
30
+ # Prawn::Document.generate "example.pdf" do
31
+ # text "Hello There"
32
+ # end
33
+ # ```
36
34
  #
37
35
  # Or if you need to access a variable outside the scope of the block, the
38
36
  # explicit block form:
39
37
  #
40
- # words = "Hello There"
41
- # Prawn::Document.generate "example.pdf" do |pdf|
42
- # pdf.text words
43
- # end
38
+ # ```ruby
39
+ # words = "Hello There"
40
+ # Prawn::Document.generate "example.pdf" do |pdf|
41
+ # pdf.text words
42
+ # end
43
+ # ```
44
44
  #
45
45
  # Usually, the block forms are used when you are simply creating a PDF
46
46
  # document that you want to immediately save or render out.
47
47
  #
48
- # See the new and generate methods for further details on the above.
49
- #
48
+ # See the {#initialize new} and {.generate generate} methods for further
49
+ # details on the above.
50
50
  class Document
51
51
  include Prawn::Document::Internals
52
52
  include PDF::Core::Annotations
@@ -59,11 +59,14 @@ module Prawn
59
59
  include Prawn::SoftMask
60
60
  include Prawn::TransformationStack
61
61
 
62
+ alias inspect to_s
63
+
62
64
  # @group Extension API
63
65
 
64
66
  # NOTE: We probably need to rethink the options validation system, but this
65
67
  # constant temporarily allows for extensions to modify the list.
66
68
 
69
+ # List of recognised options.
67
70
  VALID_OPTIONS = %i[
68
71
  page_size page_layout margin left_margin
69
72
  right_margin top_margin bottom_margin skip_page_creation
@@ -72,17 +75,14 @@ module Prawn
72
75
  ].freeze
73
76
 
74
77
  # Any module added to this array will be included into instances of
75
- # Prawn::Document at the per-object level. These will also be inherited by
76
- # any subclasses.
77
- #
78
- # Example:
78
+ # {Prawn::Document} at the per-object level. These will also be inherited
79
+ # by any subclasses.
79
80
  #
81
+ # @example
80
82
  # module MyFancyModule
81
- #
82
83
  # def party!
83
84
  # text "It's a big party!"
84
85
  # end
85
- #
86
86
  # end
87
87
  #
88
88
  # Prawn::Document.extensions << MyFancyModule
@@ -91,7 +91,7 @@ module Prawn
91
91
  # party!
92
92
  # end
93
93
  #
94
- #
94
+ # @return [Array<Module>]
95
95
  def self.extensions
96
96
  @extensions ||= []
97
97
  end
@@ -104,12 +104,26 @@ module Prawn
104
104
 
105
105
  # @group Stable Attributes
106
106
 
107
+ # Current margin box.
108
+ # @return [Prawn::Document::BoundingBox]
107
109
  attr_accessor :margin_box
108
- attr_reader :margins, :y
110
+
111
+ # Current page margins.
112
+ # @return [{:left, :top, :right, :bottom => Number}]
113
+ attr_reader :margins
114
+
115
+ # Absolute cursor position.
116
+ # @return [Number]
117
+ attr_reader :y
118
+
119
+ # Current page number.
120
+ # @return [Integer]
109
121
  attr_accessor :page_number
110
122
 
111
123
  # @group Extension Attributes
112
124
 
125
+ # Current text formatter. By default it's {Text::Formatted::Parser}
126
+ # @return [Object]
113
127
  attr_accessor :text_formatter
114
128
 
115
129
  # @group Stable API
@@ -117,99 +131,108 @@ module Prawn
117
131
  # Creates and renders a PDF document.
118
132
  #
119
133
  # When using the implicit block form, Prawn will evaluate the block
120
- # within an instance of Prawn::Document, simplifying your syntax.
134
+ # within an instance of {Prawn::Document}, simplifying your syntax.
121
135
  # However, please note that you will not be able to reference variables
122
136
  # from the enclosing scope within this block.
123
137
  #
124
- # # Using implicit block form and rendering to a file
125
- # Prawn::Document.generate "example.pdf" do
126
- # # self here is set to the newly instantiated Prawn::Document
127
- # # and so any variables in the outside scope are unavailable
128
- # font "Times-Roman"
129
- # draw_text "Hello World", :at => [200,720], :size => 32
130
- # end
138
+ # ```ruby
139
+ # # Using implicit block form and rendering to a file
140
+ # Prawn::Document.generate "example.pdf" do
141
+ # # self here is set to the newly instantiated Prawn::Document
142
+ # # and so any variables in the outside scope are unavailable
143
+ # font "Times-Roman"
144
+ # draw_text "Hello World", at: [200,720], size: 32
145
+ # end
146
+ # ```
131
147
  #
132
148
  # If you need to access your local and instance variables, use the explicit
133
- # block form shown below. In this case, Prawn yields an instance of
134
- # PDF::Document and the block is an ordinary closure:
135
- #
136
- # # Using explicit block form and rendering to a file
137
- # content = "Hello World"
138
- # Prawn::Document.generate "example.pdf" do |pdf|
139
- # # self here is left alone
140
- # pdf.font "Times-Roman"
141
- # pdf.draw_text content, :at => [200,720], :size => 32
142
- # end
143
- #
149
+ # block form shown below. In this case, Prawn yields an instance of
150
+ # {Prawn::Document} and the block is an ordinary closure:
151
+ #
152
+ # ```ruby
153
+ # # Using explicit block form and rendering to a file
154
+ # content = "Hello World"
155
+ # Prawn::Document.generate "example.pdf" do |pdf|
156
+ # # self here is left alone
157
+ # pdf.font "Times-Roman"
158
+ # pdf.draw_text content, at: [200,720], size: 32
159
+ # end
160
+ # ```
144
161
  def self.generate(filename, options = {}, &block)
145
162
  pdf = new(options, &block)
146
163
  pdf.render_file(filename)
147
164
  end
148
165
 
149
- # Creates a new PDF Document. The following options are available (with
150
- # the default values marked in [])
151
- #
152
- # <tt>:page_size</tt>:: One of the PDF::Core::PageGeometry sizes [LETTER]
153
- # <tt>:page_layout</tt>:: Either <tt>:portrait</tt> or <tt>:landscape</tt>
154
- # <tt>:margin</tt>:: Sets the margin on all sides in points [0.5 inch]
155
- # <tt>:left_margin</tt>:: Sets the left margin in points [0.5 inch]
156
- # <tt>:right_margin</tt>:: Sets the right margin in points [0.5 inch]
157
- # <tt>:top_margin</tt>:: Sets the top margin in points [0.5 inch]
158
- # <tt>:bottom_margin</tt>:: Sets the bottom margin in points [0.5 inch]
159
- # <tt>:skip_page_creation</tt>:: Creates a document without starting the
160
- # first page [false]
161
- # <tt>:compress</tt>:: Compresses content streams before rendering them
162
- # [false]
163
- # <tt>:background</tt>:: An image path to be used as background on all pages
164
- # [nil]
165
- # <tt>:background_scale</tt>:: Backgound image scale [1] [nil]
166
- # <tt>:info</tt>:: Generic hash allowing for custom metadata properties
167
- # [nil]
168
- # <tt>:text_formatter</tt>: The text formatter to use for
169
- # <tt>:inline_format</tt>ted text
170
- # [Prawn::Text::Formatted::Parser]
171
- #
172
- # Setting e.g. the :margin to 100 points and the :left_margin to 50 will
166
+ # Creates a new PDF Document.
167
+ #
168
+ # Setting e.g. the `:margin` to 100 points and the `:left_margin` to 50 will
173
169
  # result in margins of 100 points on every side except for the left, where
174
170
  # it will be 50.
175
171
  #
176
- # The :margin can also be an array much like CSS shorthand:
172
+ # The `:margin` can also be an array much like CSS shorthand:
177
173
  #
178
- # # Top and bottom are 20, left and right are 100.
179
- # :margin => [20, 100]
180
- # # Top is 50, left and right are 100, bottom is 20.
181
- # :margin => [50, 100, 20]
182
- # # Top is 10, right is 20, bottom is 30, left is 40.
183
- # :margin => [10, 20, 30, 40]
174
+ # ```ruby
175
+ # # Top and bottom are 20, left and right are 100.
176
+ # margin: [20, 100]
177
+ # # Top is 50, left and right are 100, bottom is 20.
178
+ # margin: [50, 100, 20]
179
+ # # Top is 10, right is 20, bottom is 30, left is 40.
180
+ # margin: [10, 20, 30, 40]
181
+ # ```
184
182
  #
185
- # Additionally, :page_size can be specified as a simple two value array
183
+ # Additionally, `:page_size` can be specified as a simple two value array
186
184
  # giving the width and height of the document you need in PDF Points.
187
185
  #
188
- # Usage:
189
- #
190
- # # New document, US Letter paper, portrait orientation
186
+ # @example New document, US Letter paper, portrait orientation
191
187
  # pdf = Prawn::Document.new
192
188
  #
193
- # # New document, A4 paper, landscaped
189
+ # @example New document, A4 paper, landscaped
194
190
  # pdf = Prawn::Document.new(page_size: "A4", page_layout: :landscape)
195
191
  #
196
- # # New document, Custom size
192
+ # @example New document, Custom size
197
193
  # pdf = Prawn::Document.new(page_size: [200, 300])
198
194
  #
199
- # # New document, with background
195
+ # @example New document, with background
200
196
  # pdf = Prawn::Document.new(
201
197
  # background: "#{Prawn::DATADIR}/images/pigs.jpg"
202
198
  # )
203
199
  #
200
+ # @param options [Hash{Symbol => any}]
201
+ # @option options :page_size [String, Array(Number, Number)] (LETTER)
202
+ # One of the `PDF::Core::PageGeometry` sizes.
203
+ # @option options :page_layout [:portrait, :landscape]
204
+ # Page orientation.
205
+ # @option options :margin [Number, Array<Number>] ([32])
206
+ # Sets the margin on all sides in points.
207
+ # @option options :left_margin [Number] (32)
208
+ # Sets the left margin in points.
209
+ # @option options :right_margin [Number] (32)
210
+ # Sets the right margin in points.
211
+ # @option options :top_margin [Number] (32)
212
+ # Sets the top margin in points.
213
+ # @option options :bottom_margin [Number] (32)
214
+ # Sets the bottom margin in points.
215
+ # @option options :skip_page_creation [Boolean] (false)
216
+ # Creates a document without starting the first page.
217
+ # @option options :compress [Boolean] (false)
218
+ # Compresses content streams before rendering them.
219
+ # @option options :background [String?] (nil)
220
+ # An image path to be used as background on all pages.
221
+ # @option options :background_scale [Number?] (1)
222
+ # Background image scale.
223
+ # @option options :info [Hash{Symbol => any}?] (nil)
224
+ # Generic hash allowing for custom metadata properties.
225
+ # @option options :text_formatter [Object] (Prawn::Text::Formatted::Parser)
226
+ # The text formatter to use for `:inline_format`ted text.
204
227
  def initialize(options = {}, &block)
205
228
  options = options.dup
206
229
 
207
- Prawn.verify_options VALID_OPTIONS, options
230
+ Prawn.verify_options(VALID_OPTIONS, options)
208
231
 
209
232
  # need to fix, as the refactoring breaks this
210
233
  # raise NotImplementedError if options[:skip_page_creation]
211
234
 
212
- self.class.extensions.reverse_each { |e| extend e }
235
+ self.class.extensions.reverse_each { |e| extend(e) }
213
236
  self.state = PDF::Core::DocumentState.new(options)
214
237
  state.populate_pages_from_store(self)
215
238
  renderer.min_version(state.store.min_version) if state.store.min_version
@@ -245,13 +268,34 @@ module Prawn
245
268
  # Creates and advances to a new page in the document.
246
269
  #
247
270
  # Page size, margins, and layout can also be set when generating a
248
- # new page. These values will become the new defaults for page creation
271
+ # new page. These values will become the new defaults for page creation.
249
272
  #
273
+ # @example
250
274
  # pdf.start_new_page #=> Starts new page keeping current values
251
- # pdf.start_new_page(:size => "LEGAL", :layout => :landscape)
252
- # pdf.start_new_page(:left_margin => 50, :right_margin => 50)
253
- # pdf.start_new_page(:margin => 100)
254
- #
275
+ # pdf.start_new_page(size: "LEGAL", :layout => :landscape)
276
+ # pdf.start_new_page(left_margin: 50, right_margin: 50)
277
+ # pdf.start_new_page(margin: 100)
278
+ #
279
+ # @param options [Hash]
280
+ # @option options :margins [Hash{:left, :right, :top, :bottom => Number}, nil]
281
+ # ({ left: 0, right: 0, top: 0, bottom: 0 }) Page margins
282
+ # @option options :crop [Hash{:left, :right, :top, :bottom => Number}, nil] (PDF::Core::Page::ZERO_INDENTS)
283
+ # Page crop box
284
+ # @option options :bleed [Hash{:left, :right, :top, :bottom => Number}, nil] (PDF::Core::Page::ZERO_INDENTS)
285
+ # Page bleed box
286
+ # @option options :trims [Hash{:left, :right, :top, :bottom => Number}, nil] (PDF::Core::Page::ZERO_INDENTS)
287
+ # Page trim box
288
+ # @option options :art_indents [Hash{:left, :right, :top, :bottom => Number}, nil] (PDF::Core::Page::ZERO_INDENTS)
289
+ # Page art box indents.
290
+ # @option options :graphic_state [PDF::Core::GraphicState, nil] (nil)
291
+ # Initial graphic state
292
+ # @option options :size [String, Array<Number>, nil] ('LETTER')
293
+ # Page size. A string identifies a named page size defined in
294
+ # `PDF::Core::PageGeometry`. An array must be a two element array
295
+ # specifying width and height in points.
296
+ # @option options :layout [:portrait, :landscape, nil] (:portrait)
297
+ # Page orientation.
298
+ # @return [void]
255
299
  def start_new_page(options = {})
256
300
  last_page = state.page
257
301
  if last_page
@@ -263,7 +307,7 @@ module Prawn
263
307
  page_options = {
264
308
  size: options[:size] || last_page_size,
265
309
  layout: options[:layout] || last_page_layout,
266
- margins: last_page_margins
310
+ margins: last_page_margins,
267
311
  }
268
312
  if last_page
269
313
  if last_page.graphic_state
@@ -307,8 +351,9 @@ module Prawn
307
351
  end
308
352
  end
309
353
 
310
- # Remove page of the document by index
354
+ # Remove page of the document by index.
311
355
  #
356
+ # @example
312
357
  # pdf = Prawn::Document.new
313
358
  # pdf.page_count #=> 1
314
359
  # 3.times { pdf.start_new_page }
@@ -316,6 +361,8 @@ module Prawn
316
361
  # pdf.delete_page(-1)
317
362
  # pdf.page_count #=> 3
318
363
  #
364
+ # @param index [Integer]
365
+ # @return [Boolean]
319
366
  def delete_page(index)
320
367
  return false if index.abs > (state.pages.count - 1)
321
368
 
@@ -327,13 +374,15 @@ module Prawn
327
374
  true
328
375
  end
329
376
 
330
- # Returns the number of pages in the document
377
+ # Number of pages in the document.
331
378
  #
379
+ # @example
332
380
  # pdf = Prawn::Document.new
333
381
  # pdf.page_count #=> 1
334
382
  # 3.times { pdf.start_new_page }
335
383
  # pdf.page_count #=> 4
336
384
  #
385
+ # @return [Integer]
337
386
  def page_count
338
387
  state.page_count
339
388
  end
@@ -341,8 +390,8 @@ module Prawn
341
390
  # Re-opens the page with the given (1-based) page number so that you can
342
391
  # draw on it.
343
392
  #
344
- # See Prawn::Document#number_pages for a sample usage of this capability.
345
- #
393
+ # @param page_number [Integer]
394
+ # @return [void]
346
395
  def go_to_page(page_number)
347
396
  @page_number = page_number
348
397
  state.page = state.pages[page_number - 1]
@@ -350,6 +399,10 @@ module Prawn
350
399
  @y = @bounding_box.absolute_top
351
400
  end
352
401
 
402
+ # Set cursor absolute position.
403
+ #
404
+ # @param new_y [Number]
405
+ # @return [new_y]
353
406
  def y=(new_y)
354
407
  @y = new_y
355
408
  bounds.update_height
@@ -358,12 +411,15 @@ module Prawn
358
411
  # The current y drawing position relative to the innermost bounding box,
359
412
  # or to the page margins at the top level.
360
413
  #
414
+ # @return [Number]
361
415
  def cursor
362
416
  y - bounds.absolute_bottom
363
417
  end
364
418
 
365
419
  # Moves to the specified y position in relative terms to the bottom margin.
366
420
  #
421
+ # @param new_y [Number]
422
+ # @return [void]
367
423
  def move_cursor_to(new_y)
368
424
  self.y = new_y + bounds.absolute_bottom
369
425
  end
@@ -372,6 +428,7 @@ module Prawn
372
428
  # were created during this block, it will teleport back to the original
373
429
  # page when done.
374
430
  #
431
+ # @example
375
432
  # pdf.text "A"
376
433
  #
377
434
  # pdf.float do
@@ -381,6 +438,7 @@ module Prawn
381
438
  #
382
439
  # pdf.text "B"
383
440
  #
441
+ # @return [void]
384
442
  def float
385
443
  original_page = page_number
386
444
  original_y = y
@@ -392,26 +450,32 @@ module Prawn
392
450
  # Renders the PDF document to string.
393
451
  # Pass an open file descriptor to render to file.
394
452
  #
395
- def render(*arguments, &block)
453
+ # @overload render(output = nil)
454
+ # @param output [#<<]
455
+ # @return [String]
456
+ def render(*arguments)
396
457
  (1..page_count).each do |i|
397
- go_to_page i
458
+ go_to_page(i)
398
459
  repeaters.each { |r| r.run(i) }
399
460
  end
400
461
 
401
- renderer.render(*arguments, &block)
462
+ renderer.render(*arguments)
402
463
  end
403
464
 
404
465
  # Renders the PDF document to file.
405
466
  #
467
+ # @example
406
468
  # pdf.render_file "foo.pdf"
407
469
  #
470
+ # @param filename [String]
471
+ # @return [void]
408
472
  def render_file(filename)
409
473
  File.open(filename, 'wb') { |f| render(f) }
410
474
  end
411
475
 
412
476
  # The bounds method returns the current bounding box you are currently in,
413
477
  # which is by default the box represented by the margin box on the
414
- # document itself. When called from within a created <tt>bounding_box</tt>
478
+ # document itself. When called from within a created `bounding_box`
415
479
  # block, the box defined by that call will be returned instead of the
416
480
  # document margin box.
417
481
  #
@@ -419,8 +483,7 @@ module Prawn
419
483
  # y measurements within a bounding box code block are relative to the bottom
420
484
  # left corner of the bounding box.
421
485
  #
422
- # For example:
423
- #
486
+ # @example
424
487
  # Prawn::Document.new do
425
488
  # # In the default "margin box" of a Prawn document of 0.5in along each
426
489
  # # edge
@@ -437,6 +500,7 @@ module Prawn
437
500
  # stroke_bounds
438
501
  # end
439
502
  #
503
+ # @return [Prawn::Document::BoundingBox]
440
504
  def bounds
441
505
  @bounding_box
442
506
  end
@@ -444,15 +508,18 @@ module Prawn
444
508
  # Returns the innermost non-stretchy bounding box.
445
509
  #
446
510
  # @private
511
+ # @return [Prawn::Document::BoundingBox]
447
512
  def reference_bounds
448
513
  @bounding_box.reference_bounds
449
514
  end
450
515
 
451
- # Sets Document#bounds to the BoundingBox provided. See above for a brief
452
- # description of what a bounding box is. This function is useful if you
453
- # really need to change the bounding box manually, but usually, just
516
+ # Sets {Document#bounds} to the {BoundingBox} provided. See {#bounds} for
517
+ # a brief description of what a bounding box is. This function is useful if
518
+ # you really need to change the bounding box manually, but usually, just
454
519
  # entering and exiting bounding box code blocks is good enough.
455
520
  #
521
+ # @param bounding_box [Prawn::Document::BoundingBox]
522
+ # @return [bounding_box]
456
523
  def bounds=(bounding_box)
457
524
  @bounding_box = bounding_box
458
525
  end
@@ -460,6 +527,8 @@ module Prawn
460
527
  # Moves up the document by n points relative to the current position inside
461
528
  # the current bounding box.
462
529
  #
530
+ # @param amount [Number]
531
+ # @return [void]
463
532
  def move_up(amount)
464
533
  self.y += amount
465
534
  end
@@ -467,18 +536,24 @@ module Prawn
467
536
  # Moves down the document by n points relative to the current position
468
537
  # inside the current bounding box.
469
538
  #
539
+ # @param amount [Number]
540
+ # @return [void]
470
541
  def move_down(amount)
471
542
  self.y -= amount
472
543
  end
473
544
 
474
545
  # Moves down the document and then executes a block.
475
546
  #
547
+ # @example
476
548
  # pdf.text "some text"
477
549
  # pdf.pad_top(100) do
478
550
  # pdf.text "This is 100 points below the previous line of text"
479
551
  # end
480
552
  # pdf.text "This text appears right below the previous line of text"
481
553
  #
554
+ # @param y [Number]
555
+ # @return [void]
556
+ # @yield
482
557
  def pad_top(y)
483
558
  move_down(y)
484
559
  yield
@@ -486,12 +561,16 @@ module Prawn
486
561
 
487
562
  # Executes a block then moves down the document
488
563
  #
564
+ # @example
489
565
  # pdf.text "some text"
490
566
  # pdf.pad_bottom(100) do
491
567
  # pdf.text "This text appears right below the previous line of text"
492
568
  # end
493
569
  # pdf.text "This is 100 points below the previous line of text"
494
570
  #
571
+ # @param y [Number]
572
+ # @return [void]
573
+ # @yield
495
574
  def pad_bottom(y)
496
575
  yield
497
576
  move_down(y)
@@ -500,12 +579,16 @@ module Prawn
500
579
  # Moves down the document by y, executes a block, then moves down the
501
580
  # document by y again.
502
581
  #
582
+ # @example
503
583
  # pdf.text "some text"
504
584
  # pdf.pad(100) do
505
585
  # pdf.text "This is 100 points below the previous line of text"
506
586
  # end
507
587
  # pdf.text "This is 100 points below the previous line of text"
508
588
  #
589
+ # @param y [Number]
590
+ # @return [void]
591
+ # @yield
509
592
  def pad(y)
510
593
  move_down(y)
511
594
  yield
@@ -514,6 +597,7 @@ module Prawn
514
597
 
515
598
  # Indents the specified number of PDF points for the duration of the block
516
599
  #
600
+ # @example
517
601
  # pdf.text "some text"
518
602
  # pdf.indent(20) do
519
603
  # pdf.text "This is indented 20 points"
@@ -524,52 +608,50 @@ module Prawn
524
608
  # pdf.text "This line is indented on both sides."
525
609
  # end
526
610
  #
611
+ # @param left [Number]
612
+ # @param right [Number]
613
+ # @yield
614
+ # @return [void]
527
615
  def indent(left, right = 0, &block)
528
616
  bounds.indent(left, right, &block)
529
617
  end
530
618
 
531
619
  # Places a text box on specified pages for page numbering. This should be
532
620
  # called towards the end of document creation, after all your content is
533
- # already in place. In your template string, <page> refers to the current
534
- # page, and <total> refers to the total amount of pages in the document.
535
- # Page numbering should occur at the end of your Prawn::Document.generate
621
+ # already in place. In your template string, `<page>` refers to the current
622
+ # page, and `<total>` refers to the total amount of pages in the document.
623
+ # Page numbering should occur at the end of your {Prawn::Document.generate}
536
624
  # block because the method iterates through existing pages after they are
537
625
  # created.
538
626
  #
539
- # Parameters are:
540
- #
541
- # <tt>string</tt>:: Template string for page number wording.
542
- # Should include '<page>' and, optionally, '<total>'.
543
- # <tt>options</tt>:: A hash for page numbering and text box options.
544
- # <tt>:page_filter</tt>:: A filter to specify which pages to place page
545
- # numbers on. Refer to the method 'page_match?'
546
- # <tt>:start_count_at</tt>:: The starting count to increment pages from.
547
- # <tt>:total_pages</tt>:: If provided, will replace <total> with the
548
- # value given. Useful to override the total
549
- # number of pages when using the start_count_at
550
- # option.
551
- # <tt>:color</tt>:: Text fill color.
552
- #
553
- # Please refer to Prawn::Text::text_box for additional options
554
- # concerning text formatting and placement.
555
- #
556
- # Example:
557
- # Print page numbers on every page except for the first. Start counting
558
- # from five.
559
- #
560
- # Prawn::Document.generate("page_with_numbering.pdf") do
561
- # number_pages "<page> in a total of <total>", {
562
- # start_count_at: 5,
563
- # page_filter: lambda { |pg| pg != 1 },
564
- # at: [bounds.right - 50, 0],
565
- # align: :right,
566
- # size: 14
567
- # }
568
- # end
627
+ # Please refer to {Prawn::Text#text_box} for additional options concerning
628
+ # text formatting and placement.
629
+ #
630
+ # @example Print page numbers on every page except for the first. Start counting from five.
631
+ # Prawn::Document.generate("page_with_numbering.pdf") do
632
+ # number_pages "<page> in a total of <total>", {
633
+ # start_count_at: 5,
634
+ # page_filter: lambda { |pg| pg != 1 },
635
+ # at: [bounds.right - 50, 0],
636
+ # align: :right,
637
+ # size: 14
638
+ # }
639
+ # end
569
640
  #
641
+ # @param string [String] Template string for page number wording.
642
+ # Should include `<page>` and, optionally, `<total>`.
643
+ # @param options [Hash{Symbol => any}] A hash for page numbering and text box options.
644
+ # @option options :page_filter []
645
+ # A filter to specify which pages to place page numbers on. Refer to the method {#page_match?}
646
+ # @option options :start_count_at [Integer]
647
+ # The starting count to increment pages from.
648
+ # @option options :total_pages [Integer]
649
+ # If provided, will replace `<total>` with the value given. Useful to
650
+ # override the total number of pages when using the start_count_at option.
651
+ # @option options :color [String, Array<Number>] Text fill color.
570
652
  def number_pages(string, options = {})
571
653
  opts = options.dup
572
- start_count_at = opts.delete(:start_count_at).to_i
654
+ start_count_at = opts.delete(:start_count_at)
573
655
 
574
656
  page_filter =
575
657
  if opts.key?(:page_filter)
@@ -589,21 +671,23 @@ module Prawn
589
671
  unless start_count
590
672
  pseudopage =
591
673
  case start_count_at
592
- when 0
593
- 1
674
+ when String
675
+ Integer(start_count_at, 10)
676
+ when (1..)
677
+ Integer(start_count_at)
594
678
  else
595
- start_count_at.to_i
679
+ 1
596
680
  end
597
681
  end
598
682
  if page_match?(page_filter, p)
599
683
  go_to_page(p)
600
684
  # have to use fill_color here otherwise text reverts back to default
601
685
  # fill color
602
- fill_color txtcolor unless txtcolor.nil?
603
- total_pages = total_pages.nil? ? page_count : total_pages
686
+ fill_color(txtcolor) unless txtcolor.nil?
687
+ total_pages = page_count if total_pages.nil?
604
688
  str = string.gsub('<page>', pseudopage.to_s)
605
689
  .gsub('<total>', total_pages.to_s)
606
- text_box str, opts
690
+ text_box(str, opts)
607
691
  start_count = true # increment page count as soon as first match found
608
692
  end
609
693
  pseudopage += 1 if start_count
@@ -612,31 +696,22 @@ module Prawn
612
696
 
613
697
  # @group Experimental API
614
698
 
615
- # Attempts to group the given block vertically within the current context.
616
- # First attempts to render it in the current position on the current page.
617
- # If that attempt overflows, it is tried anew after starting a new context
618
- # (page or column). Returns a logically true value if the content fits in
619
- # one page/column, false if a new page or column was needed.
620
- #
621
- # Raises CannotGroup if the provided content is too large to fit alone in
622
- # the current page or column.
623
- #
624
699
  # @private
625
700
  def group(*_arguments)
626
701
  raise NotImplementedError,
627
702
  'Document#group has been disabled because its implementation ' \
628
- 'lead to corrupted documents whenever a page boundary was ' \
629
- 'crossed. We will try to work on reimplementing it in a ' \
630
- 'future release'
703
+ 'lead to corrupted documents whenever a page boundary was ' \
704
+ 'crossed. We will try to work on reimplementing it in a ' \
705
+ 'future release'
631
706
  end
632
707
 
633
708
  # @private
634
709
  def transaction
635
710
  raise NotImplementedError,
636
711
  'Document#transaction has been disabled because its implementation ' \
637
- 'lead to corrupted documents whenever a page boundary was ' \
638
- 'crossed. We will try to work on reimplementing it in a ' \
639
- 'future release'
712
+ 'lead to corrupted documents whenever a page boundary was ' \
713
+ 'crossed. We will try to work on reimplementing it in a ' \
714
+ 'future release'
640
715
  end
641
716
 
642
717
  # Provides a way to execute a block of code repeatedly based on a
@@ -645,10 +720,16 @@ module Prawn
645
720
  # Available page filters are:
646
721
  # :all repeats on every page
647
722
  # :odd repeats on odd pages
648
- # :even repeats on even pages
649
- # some_array repeats on every page listed in the array
650
- # some_range repeats on every page included in the range
651
- # some_lambda yields page number and repeats for true return values
723
+ #
724
+ # @param page_filter [:all, :odd, :even, Array<Number>, Range, Proc]
725
+ # * `:all`: repeats on every page
726
+ # * `:odd`: repeats on odd pages
727
+ # * `:even`: repeats on even pages
728
+ # * array: repeats on every page listed in the array
729
+ # * range: repeats on every page included in the range
730
+ # * lambda: yields page number and repeats for true return values
731
+ # @param page_number [Integer]
732
+ # @return [Boolean]
652
733
  def page_match?(page_filter, page_number)
653
734
  case page_filter
654
735
  when :all
@@ -665,7 +746,6 @@ module Prawn
665
746
  end
666
747
 
667
748
  # @private
668
-
669
749
  def mask(*fields)
670
750
  # Stores the current state of the named attributes, executes the block,
671
751
  # and then restores the original values after the block has executed.
@@ -673,11 +753,17 @@ module Prawn
673
753
  stored = {}
674
754
  fields.each { |f| stored[f] = public_send(f) }
675
755
  yield
676
- fields.each { |f| public_send("#{f}=", stored[f]) }
756
+ fields.each { |f| public_send(:"#{f}=", stored[f]) }
677
757
  end
678
758
 
679
759
  # @group Extension API
680
760
 
761
+ # Initializes the first page in a new document.
762
+ # This methods allows customisation of this process in extensions such as
763
+ # Prawn::Template.
764
+ #
765
+ # @param options [Hash]
766
+ # @return [void]
681
767
  def initialize_first_page(options)
682
768
  if options[:skip_page_creation]
683
769
  start_new_page(options.merge(orphan: true))
@@ -720,7 +806,7 @@ module Prawn
720
806
  width: page.dimensions[-2] -
721
807
  (page.margins[:left] + page.margins[:right]),
722
808
  height: page.dimensions[-1] -
723
- (page.margins[:top] + page.margins[:bottom])
809
+ (page.margins[:top] + page.margins[:bottom]),
724
810
  )
725
811
 
726
812
  # This check maintains indentation settings across page breaks
@@ -744,7 +830,7 @@ module Prawn
744
830
  3 => [0, 1, 2, 1],
745
831
  2 => [0, 1, 0, 1],
746
832
  1 => [0, 0, 0, 0],
747
- 0 => []
833
+ 0 => [],
748
834
  }[margin.length]
749
835
 
750
836
  sides.zip(positions).each do |side, pos|
@@ -753,7 +839,7 @@ module Prawn
753
839
  end
754
840
  end
755
841
 
756
- def font_metric_cache #:nodoc:
842
+ def font_metric_cache # :nodoc:
757
843
  @font_metric_cache ||= FontMetricCache.new(self)
758
844
  end
759
845
  end