prawn 2.4.0 → 2.5.0

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.
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