prawn 2.0.2 → 2.3.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 (277) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -9
  6. data/Rakefile +20 -23
  7. data/lib/prawn.rb +37 -49
  8. data/lib/prawn/document.rb +181 -133
  9. data/lib/prawn/document/bounding_box.rb +41 -29
  10. data/lib/prawn/document/column_box.rb +7 -7
  11. data/lib/prawn/document/internals.rb +18 -8
  12. data/lib/prawn/document/span.rb +21 -16
  13. data/lib/prawn/encoding.rb +69 -68
  14. data/lib/prawn/errors.rb +12 -7
  15. data/lib/prawn/font.rb +115 -69
  16. data/lib/prawn/font_metric_cache.rb +14 -8
  17. data/lib/prawn/{font → fonts}/afm.rb +102 -68
  18. data/lib/prawn/{font → fonts}/dfont.rb +5 -11
  19. data/lib/prawn/fonts/otf.rb +11 -0
  20. data/lib/prawn/fonts/ttc.rb +36 -0
  21. data/lib/prawn/{font → fonts}/ttf.rb +87 -68
  22. data/lib/prawn/graphics.rb +120 -80
  23. data/lib/prawn/graphics/blend_mode.rb +65 -0
  24. data/lib/prawn/graphics/cap_style.rb +3 -3
  25. data/lib/prawn/graphics/color.rb +27 -25
  26. data/lib/prawn/graphics/dash.rb +23 -11
  27. data/lib/prawn/graphics/join_style.rb +9 -3
  28. data/lib/prawn/graphics/patterns.rb +197 -67
  29. data/lib/prawn/graphics/transformation.rb +17 -8
  30. data/lib/prawn/graphics/transparency.rb +17 -13
  31. data/lib/prawn/grid.rb +48 -47
  32. data/lib/prawn/image_handler.rb +5 -5
  33. data/lib/prawn/images.rb +39 -30
  34. data/lib/prawn/images/image.rb +2 -1
  35. data/lib/prawn/images/jpg.rb +28 -22
  36. data/lib/prawn/images/png.rb +107 -66
  37. data/lib/prawn/measurement_extensions.rb +10 -9
  38. data/lib/prawn/measurements.rb +19 -15
  39. data/lib/prawn/outline.rb +97 -77
  40. data/lib/prawn/repeater.rb +14 -10
  41. data/lib/prawn/security.rb +81 -61
  42. data/lib/prawn/security/arcfour.rb +2 -2
  43. data/lib/prawn/soft_mask.rb +26 -26
  44. data/lib/prawn/stamp.rb +20 -13
  45. data/lib/prawn/text.rb +68 -52
  46. data/lib/prawn/text/box.rb +11 -8
  47. data/lib/prawn/text/formatted.rb +5 -5
  48. data/lib/prawn/text/formatted/arranger.rb +78 -49
  49. data/lib/prawn/text/formatted/box.rb +134 -100
  50. data/lib/prawn/text/formatted/fragment.rb +11 -14
  51. data/lib/prawn/text/formatted/line_wrap.rb +121 -63
  52. data/lib/prawn/text/formatted/parser.rb +139 -117
  53. data/lib/prawn/text/formatted/wrap.rb +43 -31
  54. data/lib/prawn/transformation_stack.rb +44 -0
  55. data/lib/prawn/utilities.rb +7 -22
  56. data/lib/prawn/version.rb +2 -2
  57. data/lib/prawn/view.rb +17 -7
  58. data/manual/basic_concepts/adding_pages.rb +6 -7
  59. data/manual/basic_concepts/basic_concepts.rb +31 -22
  60. data/manual/basic_concepts/creation.rb +10 -11
  61. data/manual/basic_concepts/cursor.rb +4 -5
  62. data/manual/basic_concepts/measurement.rb +6 -7
  63. data/manual/basic_concepts/origin.rb +5 -6
  64. data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
  65. data/manual/basic_concepts/view.rb +22 -16
  66. data/manual/bounding_box/bounding_box.rb +29 -24
  67. data/manual/bounding_box/bounds.rb +11 -12
  68. data/manual/bounding_box/canvas.rb +4 -5
  69. data/manual/bounding_box/creation.rb +6 -7
  70. data/manual/bounding_box/indentation.rb +14 -15
  71. data/manual/bounding_box/nesting.rb +24 -17
  72. data/manual/bounding_box/russian_boxes.rb +14 -13
  73. data/manual/bounding_box/stretchy.rb +12 -13
  74. data/manual/contents.rb +28 -22
  75. data/manual/cover.rb +33 -28
  76. data/manual/document_and_page_options/background.rb +11 -13
  77. data/manual/document_and_page_options/document_and_page_options.rb +25 -20
  78. data/manual/document_and_page_options/metadata.rb +18 -16
  79. data/manual/document_and_page_options/page_margins.rb +18 -20
  80. data/manual/document_and_page_options/page_size.rb +13 -12
  81. data/manual/document_and_page_options/print_scaling.rb +17 -15
  82. data/manual/example_helper.rb +5 -4
  83. data/manual/graphics/blend_mode.rb +52 -0
  84. data/manual/graphics/circle_and_ellipse.rb +4 -5
  85. data/manual/graphics/color.rb +7 -9
  86. data/manual/graphics/common_lines.rb +7 -8
  87. data/manual/graphics/fill_and_stroke.rb +4 -5
  88. data/manual/graphics/fill_rules.rb +9 -10
  89. data/manual/graphics/gradients.rb +27 -21
  90. data/manual/graphics/graphics.rb +48 -39
  91. data/manual/graphics/helper.rb +12 -9
  92. data/manual/graphics/line_width.rb +8 -7
  93. data/manual/graphics/lines_and_curves.rb +7 -8
  94. data/manual/graphics/polygon.rb +6 -8
  95. data/manual/graphics/rectangle.rb +4 -5
  96. data/manual/graphics/rotate.rb +6 -7
  97. data/manual/graphics/scale.rb +14 -15
  98. data/manual/graphics/soft_masks.rb +4 -5
  99. data/manual/graphics/stroke_cap.rb +6 -7
  100. data/manual/graphics/stroke_dash.rb +11 -12
  101. data/manual/graphics/stroke_join.rb +5 -6
  102. data/manual/graphics/translate.rb +9 -10
  103. data/manual/graphics/transparency.rb +7 -8
  104. data/manual/how_to_read_this_manual.rb +6 -6
  105. data/manual/images/absolute_position.rb +6 -7
  106. data/manual/images/fit.rb +7 -8
  107. data/manual/images/horizontal.rb +9 -10
  108. data/manual/images/images.rb +28 -24
  109. data/manual/images/plain_image.rb +5 -6
  110. data/manual/images/scale.rb +9 -10
  111. data/manual/images/vertical.rb +13 -14
  112. data/manual/images/width_and_height.rb +10 -11
  113. data/manual/layout/boxes.rb +5 -6
  114. data/manual/layout/content.rb +7 -8
  115. data/manual/layout/layout.rb +18 -16
  116. data/manual/layout/simple_grid.rb +6 -7
  117. data/manual/outline/add_subsection_to.rb +20 -21
  118. data/manual/outline/insert_section_after.rb +15 -16
  119. data/manual/outline/outline.rb +21 -17
  120. data/manual/outline/sections_and_pages.rb +17 -18
  121. data/manual/repeatable_content/alternate_page_numbering.rb +21 -17
  122. data/manual/repeatable_content/page_numbering.rb +17 -16
  123. data/manual/repeatable_content/repeatable_content.rb +25 -19
  124. data/manual/repeatable_content/repeater.rb +14 -15
  125. data/manual/repeatable_content/stamp.rb +14 -15
  126. data/manual/security/encryption.rb +9 -10
  127. data/manual/security/permissions.rb +19 -14
  128. data/manual/security/security.rb +19 -16
  129. data/manual/table.rb +3 -3
  130. data/manual/text/alignment.rb +16 -17
  131. data/manual/text/color.rb +12 -11
  132. data/manual/text/column_box.rb +9 -10
  133. data/manual/text/fallback_fonts.rb +25 -21
  134. data/manual/text/font.rb +11 -12
  135. data/manual/text/font_size.rb +13 -14
  136. data/manual/text/font_style.rb +7 -8
  137. data/manual/text/formatted_callbacks.rb +25 -21
  138. data/manual/text/formatted_text.rb +33 -25
  139. data/manual/text/free_flowing_text.rb +20 -21
  140. data/manual/text/inline.rb +18 -19
  141. data/manual/text/kerning_and_character_spacing.rb +14 -15
  142. data/manual/text/leading.rb +7 -8
  143. data/manual/text/line_wrapping.rb +37 -18
  144. data/manual/text/paragraph_indentation.rb +13 -14
  145. data/manual/text/positioned_text.rb +15 -16
  146. data/manual/text/registering_families.rb +20 -21
  147. data/manual/text/rendering_and_color.rb +9 -10
  148. data/manual/text/right_to_left_text.rb +26 -19
  149. data/manual/text/rotation.rb +28 -23
  150. data/manual/text/single_usage.rb +8 -9
  151. data/manual/text/text.rb +57 -52
  152. data/manual/text/text_box_excess.rb +20 -17
  153. data/manual/text/text_box_extensions.rb +18 -15
  154. data/manual/text/text_box_overflow.rb +18 -19
  155. data/manual/text/utf8.rb +11 -12
  156. data/manual/text/win_ansi_charset.rb +21 -19
  157. data/prawn.gemspec +45 -33
  158. data/spec/extensions/encoding_helpers.rb +3 -3
  159. data/spec/prawn/document/bounding_box_spec.rb +546 -0
  160. data/spec/prawn/document/column_box_spec.rb +75 -0
  161. data/spec/prawn/document/security_spec.rb +176 -0
  162. data/spec/prawn/document_annotations_spec.rb +76 -0
  163. data/spec/prawn/document_destinations_spec.rb +15 -0
  164. data/spec/prawn/document_grid_spec.rb +99 -0
  165. data/spec/prawn/document_reference_spec.rb +27 -0
  166. data/spec/prawn/document_span_spec.rb +36 -0
  167. data/spec/prawn/document_spec.rb +802 -0
  168. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  169. data/spec/prawn/font_spec.rb +542 -0
  170. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  171. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  172. data/spec/prawn/graphics_spec.rb +837 -0
  173. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  174. data/spec/prawn/image_handler_spec.rb +53 -0
  175. data/spec/prawn/images/jpg_spec.rb +20 -0
  176. data/spec/prawn/images/png_spec.rb +283 -0
  177. data/spec/prawn/images_spec.rb +224 -0
  178. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  179. data/spec/prawn/outline_spec.rb +412 -0
  180. data/spec/prawn/repeater_spec.rb +165 -0
  181. data/spec/prawn/soft_mask_spec.rb +74 -0
  182. data/spec/prawn/stamp_spec.rb +172 -0
  183. data/spec/prawn/text/box_spec.rb +1112 -0
  184. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  185. data/spec/prawn/text/formatted/box_spec.rb +846 -0
  186. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  187. data/spec/prawn/text/formatted/line_wrap_spec.rb +494 -0
  188. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  189. data/spec/prawn/text_draw_text_spec.rb +149 -0
  190. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  191. data/spec/prawn/text_spacing_spec.rb +95 -0
  192. data/spec/prawn/text_spec.rb +603 -0
  193. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  194. data/spec/prawn/transformation_stack_spec.rb +66 -0
  195. data/spec/prawn/view_spec.rb +63 -0
  196. data/spec/prawn_manual_spec.rb +35 -0
  197. data/spec/spec_helper.rb +19 -23
  198. metadata +145 -185
  199. metadata.gz.sig +4 -0
  200. data/data/images/16bit.alpha +0 -0
  201. data/data/images/16bit.color +0 -0
  202. data/data/images/16bit.png +0 -0
  203. data/data/images/arrow.png +0 -0
  204. data/data/images/arrow2.png +0 -0
  205. data/data/images/dice.alpha +0 -0
  206. data/data/images/dice.color +0 -0
  207. data/data/images/dice.png +0 -0
  208. data/data/images/dice_interlaced.png +0 -0
  209. data/data/images/fractal.jpg +0 -0
  210. data/data/images/indexed_color.dat +0 -0
  211. data/data/images/indexed_color.png +0 -0
  212. data/data/images/letterhead.jpg +0 -0
  213. data/data/images/license.md +0 -8
  214. data/data/images/page_white_text.alpha +0 -0
  215. data/data/images/page_white_text.color +0 -0
  216. data/data/images/page_white_text.png +0 -0
  217. data/data/images/pal_bk.png +0 -0
  218. data/data/images/pigs.jpg +0 -0
  219. data/data/images/prawn.png +0 -0
  220. data/data/images/ruport.png +0 -0
  221. data/data/images/ruport_data.dat +0 -0
  222. data/data/images/ruport_transparent.png +0 -0
  223. data/data/images/ruport_type0.png +0 -0
  224. data/data/images/stef.jpg +0 -0
  225. data/data/images/tru256.bmp +0 -0
  226. data/data/images/web-links.dat +0 -1
  227. data/data/images/web-links.png +0 -0
  228. data/data/pdfs/complex_template.pdf +0 -0
  229. data/data/pdfs/contains_ttf_font.pdf +0 -0
  230. data/data/pdfs/encrypted.pdf +0 -0
  231. data/data/pdfs/form.pdf +1 -819
  232. data/data/pdfs/hexagon.pdf +0 -61
  233. data/data/pdfs/indirect_reference.pdf +0 -86
  234. data/data/pdfs/multipage_template.pdf +0 -127
  235. data/data/pdfs/nested_pages.pdf +0 -118
  236. data/data/pdfs/page_without_mediabox.pdf +0 -193
  237. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  238. data/data/pdfs/two_hexagons.pdf +0 -90
  239. data/data/pdfs/version_1_6.pdf +0 -61
  240. data/data/shift_jis_text.txt +0 -1
  241. data/spec/acceptance/png.rb +0 -24
  242. data/spec/annotations_spec.rb +0 -67
  243. data/spec/bounding_box_spec.rb +0 -501
  244. data/spec/column_box_spec.rb +0 -59
  245. data/spec/destinations_spec.rb +0 -13
  246. data/spec/document_spec.rb +0 -742
  247. data/spec/extensions/mocha.rb +0 -45
  248. data/spec/font_metric_cache_spec.rb +0 -52
  249. data/spec/font_spec.rb +0 -475
  250. data/spec/formatted_text_arranger_spec.rb +0 -423
  251. data/spec/formatted_text_box_spec.rb +0 -716
  252. data/spec/formatted_text_fragment_spec.rb +0 -299
  253. data/spec/graphics_spec.rb +0 -666
  254. data/spec/grid_spec.rb +0 -95
  255. data/spec/image_handler_spec.rb +0 -53
  256. data/spec/images_spec.rb +0 -167
  257. data/spec/inline_formatted_text_parser_spec.rb +0 -568
  258. data/spec/jpg_spec.rb +0 -23
  259. data/spec/line_wrap_spec.rb +0 -366
  260. data/spec/measurement_units_spec.rb +0 -22
  261. data/spec/outline_spec.rb +0 -409
  262. data/spec/png_spec.rb +0 -235
  263. data/spec/reference_spec.rb +0 -25
  264. data/spec/repeater_spec.rb +0 -154
  265. data/spec/security_spec.rb +0 -151
  266. data/spec/soft_mask_spec.rb +0 -78
  267. data/spec/span_spec.rb +0 -43
  268. data/spec/stamp_spec.rb +0 -179
  269. data/spec/stroke_styles_spec.rb +0 -208
  270. data/spec/text_at_spec.rb +0 -142
  271. data/spec/text_box_spec.rb +0 -1038
  272. data/spec/text_rendering_mode_spec.rb +0 -45
  273. data/spec/text_spacing_spec.rb +0 -93
  274. data/spec/text_spec.rb +0 -549
  275. data/spec/text_with_inline_formatting_spec.rb +0 -35
  276. data/spec/transparency_spec.rb +0 -91
  277. data/spec/view_spec.rb +0 -42
@@ -1,70 +1,74 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  # measurements.rb: Conversions from other measurements to PDF points
3
4
  #
4
5
  # Copyright December 2008, Florian Witteler. All Rights Reserved.
5
6
  #
7
+
8
+ # rubocop: disable Naming/MethodParameterName
6
9
  module Prawn
7
10
  # @group Stable API
8
11
 
9
12
  module Measurements
10
13
  # metric conversions
11
14
  def cm2mm(cm)
12
- return cm * 10
15
+ cm * 10
13
16
  end
14
17
 
15
18
  def dm2mm(dm)
16
- return dm * 100
19
+ dm * 100
17
20
  end
18
21
 
19
22
  def m2mm(m)
20
- return m * 1000
23
+ m * 1000
21
24
  end
22
25
 
23
26
  # imperial conversions
24
27
  # from http://en.wikipedia.org/wiki/Imperial_units
25
28
  def ft2in(ft)
26
- return ft * 12
29
+ ft * 12
27
30
  end
28
31
 
29
32
  def yd2in(yd)
30
- return yd * 36
33
+ yd * 36
31
34
  end
32
35
 
33
36
  # PostscriptPoint-converisons
34
37
  def pt2pt(pt)
35
- return pt
38
+ pt
36
39
  end
37
40
 
38
41
  def in2pt(inch)
39
- return inch * 72
42
+ inch * 72
40
43
  end
41
44
 
42
45
  def ft2pt(ft)
43
- return in2pt(ft2in(ft))
46
+ in2pt(ft2in(ft))
44
47
  end
45
48
 
46
49
  def yd2pt(yd)
47
- return in2pt(yd2in(yd))
50
+ in2pt(yd2in(yd))
48
51
  end
49
52
 
50
53
  def mm2pt(mm)
51
- return mm * (72 / 25.4)
54
+ mm * (72 / 25.4)
52
55
  end
53
56
 
54
57
  def cm2pt(cm)
55
- return mm2pt(cm2mm(cm))
58
+ mm2pt(cm2mm(cm))
56
59
  end
57
60
 
58
61
  def dm2pt(dm)
59
- return mm2pt(dm2mm(dm))
62
+ mm2pt(dm2mm(dm))
60
63
  end
61
64
 
62
65
  def m2pt(m)
63
- return mm2pt(m2mm(m))
66
+ mm2pt(m2mm(m))
64
67
  end
65
68
 
66
69
  def pt2mm(pt)
67
- return pt * 1 / mm2pt(1) # (25.4 / 72)
70
+ pt * 1 / mm2pt(1) # (25.4 / 72)
68
71
  end
69
72
  end
70
73
  end
74
+ # rubocop: enable Naming/MethodParameterName
@@ -1,26 +1,28 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Prawn
4
4
  class Document
5
5
  # @group Stable API
6
6
 
7
- # Lazily instantiates a Prawn::Outline object for document. This is used as point of entry
8
- # to methods to build the outline tree for a document's table of contents.
7
+ # Lazily instantiates a Prawn::Outline object for document. This is used as
8
+ # point of entry to methods to build the outline tree for a document's table
9
+ # of contents.
9
10
  def outline
10
11
  @outline ||= Outline.new(self)
11
12
  end
12
13
  end
13
14
 
14
15
  # The Outline class organizes the outline tree items for the document.
15
- # Note that the prev and parent instance variables are adjusted while navigating
16
- # through the nested blocks. These variables along with the presence or absense
17
- # of blocks are the primary means by which the relations for the various
18
- # OutlineItems and the OutlineRoot are set. Unfortunately, the best way to
19
- # understand how this works is to follow the method calls through a real example.
16
+ # Note that the prev and parent instance variables are adjusted while
17
+ # navigating through the nested blocks. These variables along with the
18
+ # presence or absense of blocks are the primary means by which the relations
19
+ # for the various OutlineItems and the OutlineRoot are set. Unfortunately, the
20
+ # best way to understand how this works is to follow the method calls through
21
+ # a real example.
20
22
  #
21
- # Some ideas for the organization of this class were gleaned from name_tree. In
22
- # particular the way in which the OutlineItems are finally rendered into document
23
- # objects in PdfObject through a hash.
23
+ # Some ideas for the organization of this class were gleaned from name_tree.
24
+ # In particular the way in which the OutlineItems are finally rendered into
25
+ # document objects in PdfObject through a hash.
24
26
  #
25
27
  class Outline
26
28
  # @private
@@ -42,10 +44,11 @@ module Prawn
42
44
 
43
45
  # Defines/Updates an outline for the document.
44
46
  # The outline is an optional nested index that appears on the side of a PDF
45
- # document usually with direct links to pages. The outline DSL is defined by nested
46
- # blocks involving two methods: section and page; see the documentation on those methods
47
- # for their arguments and options. Note that one can also use outline#update
48
- # to add more sections to the end of the outline tree using the same syntax and scope.
47
+ # document usually with direct links to pages. The outline DSL is defined by
48
+ # nested blocks involving two methods: section and page; see the
49
+ # documentation on those methods for their arguments and options. Note that
50
+ # one can also use outline#update to add more sections to the end of the
51
+ # outline tree using the same syntax and scope.
49
52
  #
50
53
  # The syntax is best illustrated with an example:
51
54
  #
@@ -69,28 +72,31 @@ module Prawn
69
72
  # end
70
73
  #
71
74
  def define(&block)
72
- instance_eval(&block) if block
75
+ instance_eval(&block) if block
73
76
  end
74
77
 
75
- alias :update :define
78
+ alias update define
76
79
 
77
80
  # Inserts an outline section to the outline tree (see outline#define).
78
81
  # Although you will probably choose to exclusively use outline#define so
79
- # that your outline tree is contained and easy to manage, this method
80
- # gives you the option to insert sections to the outline tree at any point
81
- # during document generation. This method allows you to add a child subsection
82
- # to any other item at any level in the outline tree.
83
- # Currently the only way to locate the place of entry is with the title for the
84
- # item. If your title names are not unique consider using define_outline.
82
+ # that your outline tree is contained and easy to manage, this method gives
83
+ # you the option to insert sections to the outline tree at any point during
84
+ # document generation. This method allows you to add a child subsection to
85
+ # any other item at any level in the outline tree. Currently the only way
86
+ # to locate the place of entry is with the title for the item. If your title
87
+ # names are not unique consider using define_outline.
85
88
  # The method takes the following arguments:
86
- # title: a string that must match an outline title to add the subsection to
87
- # position: either :first or :last(the default) where the subsection will be placed relative
88
- # to other child elements. If you need to position your subsection in between
89
- # other elements then consider using #insert_section_after
89
+ # title: a string that must match an outline title to add
90
+ # the subsection to
91
+ # position: either :first or :last (the default) where the subsection will
92
+ # be placed relative to other child elements. If you need to position
93
+ # your subsection in between other elements then consider using
94
+ # #insert_section_after
90
95
  # block: uses the same DSL syntax as outline#define, for example:
91
96
  #
92
- # Consider using this method inside of outline.update if you want to have the outline object
93
- # to be scoped as self (see #insert_section_after example).
97
+ # Consider using this method inside of outline.update if you want to have
98
+ # the outline object to be scoped as self (see #insert_section_after
99
+ # example).
94
100
  #
95
101
  # go_to_page 2
96
102
  # start_new_page
@@ -101,8 +107,10 @@ module Prawn
101
107
  #
102
108
  def add_subsection_to(title, position = :last, &block)
103
109
  @parent = items[title]
104
- fail Prawn::Errors::UnknownOutlineTitle,
105
- "\n No outline item with title: '#{title}' exists in the outline tree" unless @parent
110
+ unless @parent
111
+ raise Prawn::Errors::UnknownOutlineTitle,
112
+ "\n No outline item with title: '#{title}' exists in the outline tree"
113
+ end
106
114
  @prev = position == :first ? nil : @parent.data.last
107
115
  nxt = position == :first ? @parent.data.first : nil
108
116
  insert_section(nxt, &block)
@@ -110,12 +118,13 @@ module Prawn
110
118
 
111
119
  # Inserts an outline section to the outline tree (see outline#define).
112
120
  # Although you will probably choose to exclusively use outline#define so
113
- # that your outline tree is contained and easy to manage, this method
114
- # gives you the option to insert sections to the outline tree at any point
115
- # during document generation. Unlike outline.add_section, this method allows
116
- # you to enter a section after any other item at any level in the outline tree.
117
- # Currently the only way to locate the place of entry is with the title for the
118
- # item. If your title names are not unique consider using define_outline.
121
+ # that your outline tree is contained and easy to manage, this method gives
122
+ # you the option to insert sections to the outline tree at any point during
123
+ # document generation. Unlike outline.add_section, this method allows you to
124
+ # enter a section after any other item at any level in the outline tree.
125
+ # Currently the only way to locate the place of entry is with the title for
126
+ # the item. If your title names are not unique consider using
127
+ # define_outline.
119
128
  # The method takes the following arguments:
120
129
  # title: the title of other section or page to insert new section after
121
130
  # block: uses the same DSL syntax as outline#define, for example:
@@ -131,30 +140,36 @@ module Prawn
131
140
  #
132
141
  def insert_section_after(title, &block)
133
142
  @prev = items[title]
134
- fail Prawn::Errors::UnknownOutlineTitle,
135
- "\n No outline item with title: '#{title}' exists in the outline tree" unless @prev
143
+ unless @prev
144
+ raise Prawn::Errors::UnknownOutlineTitle,
145
+ "\n No outline item with title: '#{title}' exists in the outline tree"
146
+ end
136
147
  @parent = @prev.data.parent
137
148
  nxt = @prev.data.next
138
149
  insert_section(nxt, &block)
139
150
  end
140
151
 
141
- # See outline#define above for documentation on how this is used in that context
152
+ # See outline#define above for documentation on how this is used in that
153
+ # context
142
154
  #
143
155
  # Adds an outine section to the outline tree.
144
156
  # Although you will probably choose to exclusively use outline#define so
145
- # that your outline tree is contained and easy to manage, this method
146
- # gives you the option to add sections to the outline tree at any point
147
- # during document generation. When not being called from within another #section block
148
- # the section will be added at the top level after the other root elements of the outline.
149
- # For more flexible placement try using outline#insert_section_after and/or
150
- # outline#add_subsection_to
157
+ # that your outline tree is contained and easy to manage, this method gives
158
+ # you the option to add sections to the outline tree at any point during
159
+ # document generation. When not being called from within another #section
160
+ # block the section will be added at the top level after the other root
161
+ # elements of the outline. For more flexible placement try using
162
+ # outline#insert_section_after and/or outline#add_subsection_to
163
+ #
151
164
  # Takes the following arguments:
152
165
  # title: the outline text that appears for the section.
153
- # options: destination - optional integer defining the page number for a destination link
154
- # to the top of the page (using a :FIT destination).
155
- # - or an array with a custom destination (see the #dest_* methods of the
156
- # PDF::Destination module)
157
- # closed - whether the section should show its nested outline elements.
166
+ # options: destination - optional integer defining the page number for
167
+ # a destination link to the top of the page (using a :FIT
168
+ # destination).
169
+ # - or an array with a custom destination (see the #dest_*
170
+ # methods of the PDF::Destination module)
171
+ # closed - whether the section should show its nested outline
172
+ # elements.
158
173
  # - defaults to false.
159
174
  # block: more nested subsections and/or page blocks
160
175
  #
@@ -167,36 +182,40 @@ module Prawn
167
182
  add_outline_item(title, options, &block)
168
183
  end
169
184
 
170
- # See Outline#define above for more documentation on how it is used in that context
185
+ # See Outline#define above for more documentation on how it is used in that
186
+ # context
171
187
  #
172
188
  # Adds a page to the outline.
173
189
  # Although you will probably choose to exclusively use outline#define so
174
190
  # that your outline tree is contained and easy to manage, this method also
175
191
  # gives you the option to add pages to the root of outline tree at any point
176
- # during document generation. Note that the page will be added at the
177
- # top level after the other root outline elements. For more flexible placement try
178
- # using outline#insert_section_after and/or outline#add_subsection_to.
192
+ # during document generation. Note that the page will be added at the top
193
+ # level after the other root outline elements. For more flexible placement
194
+ # try using outline#insert_section_after and/or outline#add_subsection_to.
179
195
  #
180
196
  # Takes the following arguments:
181
- # options:
182
- # title - REQUIRED. The outline text that appears for the page.
183
- # destination - optional integer defining the page number for a destination link
184
- # to the top of the page (using a :FIT destination).
185
- # - or an array with a custom destination (see the #dest_* methods of the
186
- # PDF::Destination module)
187
- # closed - whether the section should show its nested outline elements.
188
- # - defaults to false.
197
+ # options:
198
+ # title - REQUIRED. The outline text that appears for the page.
199
+ # destination - optional integer defining the page number for
200
+ # a destination link to the top of the page (using a :FIT
201
+ # destination).
202
+ # or an array with a custom destination (see the dest_* methods
203
+ # of the PDF::Destination module)
204
+ # closed - whether the section should show its nested outline elements.
205
+ # - defaults to false.
189
206
  # example usage:
190
207
  #
191
208
  # outline.page :title => "Very Last Page"
192
- # Note: this method is almost identical to section except that it does not accept a block
193
- # thereby defining the outline item as a leaf on the outline tree structure.
209
+ #
210
+ # Note: this method is almost identical to section except that it does not
211
+ # accept a block thereby defining the outline item as a leaf on the outline
212
+ # tree structure.
194
213
  def page(options = {})
195
214
  if options[:title]
196
215
  title = options[:title]
197
216
  else
198
- fail Prawn::Errors::RequiredOption,
199
- "\nTitle is a required option for page"
217
+ raise Prawn::Errors::RequiredOption,
218
+ "\nTitle is a required option for page"
200
219
  end
201
220
  add_outline_item(title, options)
202
221
  end
@@ -207,15 +226,16 @@ module Prawn
207
226
  # lazily initialized, so that documents that do not have an outline
208
227
  # do not incur the additional overhead.
209
228
  def root
210
- document.state.store.root.data[:Outlines] ||= document.ref!(PDF::Core::OutlineRoot.new)
229
+ document.state.store.root.data[:Outlines] ||=
230
+ document.ref!(PDF::Core::OutlineRoot.new)
211
231
  end
212
232
 
213
233
  def add_outline_item(title, options, &block)
214
234
  outline_item = create_outline_item(title, options)
215
- set_relations(outline_item)
235
+ establish_relations(outline_item)
216
236
  increase_count
217
237
  set_variables_for_block(outline_item, block)
218
- block.call if block
238
+ yield if block
219
239
  reset_parent(outline_item)
220
240
  end
221
241
 
@@ -234,7 +254,7 @@ module Prawn
234
254
  items[title] = document.ref!(outline_item)
235
255
  end
236
256
 
237
- def set_relations(outline_item)
257
+ def establish_relations(outline_item)
238
258
  prev.data.next = outline_item if prev
239
259
  parent.data.first = outline_item unless prev
240
260
  parent.data.last = outline_item
@@ -244,11 +264,11 @@ module Prawn
244
264
  counting_parent = parent
245
265
  while counting_parent
246
266
  counting_parent.data.count += 1
247
- if counting_parent == root
248
- counting_parent = nil
249
- else
250
- counting_parent = counting_parent.data.parent
251
- end
267
+ counting_parent = if counting_parent == root
268
+ nil
269
+ else
270
+ counting_parent.data.parent
271
+ end
252
272
  end
253
273
  end
254
274
 
@@ -267,7 +287,7 @@ module Prawn
267
287
  def insert_section(nxt, &block)
268
288
  last = @parent.data.last
269
289
  if block
270
- block.call
290
+ yield
271
291
  end
272
292
  adjust_relations(nxt, last)
273
293
  reset_root_positioning
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
2
- #
1
+ # frozen_string_literal: true
2
+
3
3
  # repeater.rb : Implements repeated page elements.
4
4
  # Heavy inspired by repeating_element() in PDF::Wrapper
5
5
  # http://pdf-wrapper.rubyforge.org/
@@ -20,9 +20,9 @@ module Prawn
20
20
 
21
21
  # @group Experimental API
22
22
 
23
- # Provides a way to execute a block of code repeatedly based on a
24
- # page_filter. Since Stamp is used under the hood, this method is very space
25
- # efficient.
23
+ # Provides a way to execute a block of code repeatedly based on
24
+ # a page_filter. Since Stamp is used under the hood, this method is very
25
+ # space efficient.
26
26
  #
27
27
  # Available page filters are:
28
28
  # :all -- repeats on every page
@@ -32,8 +32,9 @@ module Prawn
32
32
  # some_range -- repeats on every page included in the range
33
33
  # some_lambda -- yields page number and repeats for true return values
34
34
  #
35
- # Also accepts an optional second argument for dynamic content which executes the code
36
- # in the context of the filtered pages without using a Stamp.
35
+ # Also accepts an optional second argument for dynamic content which
36
+ # executes the code in the context of the filtered pages without using
37
+ # a Stamp.
37
38
  #
38
39
  # Example:
39
40
  #
@@ -75,7 +76,10 @@ module Prawn
75
76
  # end
76
77
  #
77
78
  def repeat(page_filter, options = {}, &block)
78
- repeaters << Prawn::Repeater.new(self, page_filter, !!options[:dynamic], &block)
79
+ dynamic = options.fetch(:dynamic, false)
80
+ repeaters << Prawn::Repeater.new(
81
+ self, page_filter, dynamic, &block
82
+ )
79
83
  end
80
84
  end
81
85
 
@@ -91,10 +95,10 @@ module Prawn
91
95
  attr_reader :name
92
96
 
93
97
  def initialize(document, page_filter, dynamic = false, &block)
94
- @document = document
98
+ @document = document
95
99
  @page_filter = page_filter
96
100
  @dynamic = dynamic
97
- @stamp_name = "prawn_repeater(#{Repeater.count})"
101
+ @stamp_name = "prawn_repeater(#{Repeater.count})"
98
102
  @document.create_stamp(@stamp_name, &block) unless dynamic
99
103
  @block = block if dynamic
100
104
  @graphic_state = document.state.page.graphic_state.dup
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
2
- #
1
+ # frozen_string_literal: true
2
+
3
3
  # encryption.rb : Implements encrypted PDF and access permissions.
4
4
  #
5
5
  # Copyright August 2008, Brad Ediger. All Rights Reserved.
@@ -8,8 +8,6 @@
8
8
 
9
9
  require 'digest/md5'
10
10
 
11
- require 'pdf/core/byte_string'
12
-
13
11
  require_relative 'security/arcfour'
14
12
 
15
13
  module Prawn
@@ -88,14 +86,14 @@ module Prawn
88
86
  # PDF format.
89
87
  #
90
88
  def encrypt_document(options = {})
91
- Prawn.verify_options [:user_password, :owner_password, :permissions],
92
- options
93
- @user_password = options.delete(:user_password) || ""
89
+ Prawn.verify_options %i[user_password owner_password permissions],
90
+ options
91
+ @user_password = options.delete(:user_password) || ''
94
92
 
95
93
  @owner_password = options.delete(:owner_password) || @user_password
96
94
  if @owner_password == :random
97
95
  # Generate a completely ridiculous password
98
- @owner_password = (1..32).map{ rand(256) }.pack("c*")
96
+ @owner_password = (1..32).map { rand(256) }.pack('c*')
99
97
  end
100
98
 
101
99
  self.permissions = options.delete(:permissions) || {}
@@ -124,32 +122,41 @@ module Prawn
124
122
 
125
123
  # Provides the values for the trailer encryption dictionary.
126
124
  def encryption_dictionary
127
- { :Filter => :Standard, # default PDF security handler
128
- :V => 1, # "Algorithm 3.1", PDF reference 1.3
129
- :R => 2, # Revision 2 of the algorithm
130
- :O => PDF::Core::ByteString.new(owner_password_hash),
131
- :U => PDF::Core::ByteString.new(user_password_hash),
132
- :P => permissions_value }
125
+ {
126
+ Filter: :Standard, # default PDF security handler
127
+ V: 1, # "Algorithm 3.1", PDF reference 1.3
128
+ R: 2, # Revision 2 of the algorithm
129
+ O: PDF::Core::ByteString.new(owner_password_hash),
130
+ U: PDF::Core::ByteString.new(user_password_hash),
131
+ P: permissions_value
132
+ }
133
133
  end
134
134
 
135
135
  # Flags in the permissions word, numbered as LSB = 1
136
- PermissionsBits = { :print_document => 3,
137
- :modify_contents => 4,
138
- :copy_contents => 5,
139
- :modify_annotations => 6 }
136
+ PERMISSIONS_BITS = {
137
+ print_document: 3,
138
+ modify_contents: 4,
139
+ copy_contents: 5,
140
+ modify_annotations: 6
141
+ }.freeze
142
+ private_constant :PERMISSIONS_BITS
140
143
 
141
- FullPermissions = 0b1111_1111_1111_1111_1111_1111_1111_1111
144
+ FULL_PERMISSIONS = 0b1111_1111_1111_1111_1111_1111_1111_1111
145
+ private_constant :FULL_PERMISSIONS
142
146
 
143
147
  def permissions=(perms = {})
144
- @permissions ||= FullPermissions
148
+ @permissions ||= FULL_PERMISSIONS
145
149
  perms.each do |key, value|
146
- unless PermissionsBits[key]
147
- fail ArgumentError, "Unknown permission :#{key}. Valid options: " +
148
- PermissionsBits.keys.map(&:inspect).join(", ")
150
+ unless PERMISSIONS_BITS[key]
151
+ raise(
152
+ ArgumentError,
153
+ "Unknown permission :#{key}. Valid options: " +
154
+ PERMISSIONS_BITS.keys.map(&:inspect).join(', ')
155
+ )
149
156
  end
150
157
 
151
158
  # 0-based bit number, from LSB
152
- bit_position = PermissionsBits[key] - 1
159
+ bit_position = PERMISSIONS_BITS[key] - 1
153
160
 
154
161
  if value # set bit
155
162
  @permissions |= (1 << bit_position)
@@ -160,17 +167,17 @@ module Prawn
160
167
  end
161
168
 
162
169
  def permissions_value
163
- @permissions || FullPermissions
170
+ @permissions || FULL_PERMISSIONS
164
171
  end
165
172
 
166
- PasswordPadding =
167
- "28BF4E5E4E758A4164004E56FFFA01082E2E00B6D0683E802F0CA9FE6453697A".
168
- scan(/../).map{ |x| x.to_i(16) }.pack("c*")
173
+ PASSWORD_PADDING =
174
+ '28BF4E5E4E758A4164004E56FFFA01082E2E00B6D0683E802F0CA9FE6453697A'
175
+ .scan(/../).map { |x| x.to_i(16) }.pack('c*')
169
176
 
170
177
  # Pads or truncates a password to 32 bytes as per Alg 3.2.
171
178
  def pad_password(password)
172
179
  password = password[0, 32]
173
- password + PasswordPadding[0, 32 - password.length]
180
+ password + PASSWORD_PADDING[0, 32 - password.length]
174
181
  end
175
182
 
176
183
  def user_encryption_key
@@ -178,7 +185,7 @@ module Prawn
178
185
  md5 = Digest::MD5.new
179
186
  md5 << pad_password(@user_password)
180
187
  md5 << owner_password_hash
181
- md5 << [permissions_value].pack("V")
188
+ md5 << [permissions_value].pack('V')
182
189
  md5.digest[0, 5]
183
190
  end
184
191
  end
@@ -193,7 +200,7 @@ module Prawn
193
200
 
194
201
  # The U (user) value in the encryption dictionary. Algorithm 3.4.
195
202
  def user_password_hash
196
- Arcfour.new(user_encryption_key).encrypt(PasswordPadding)
203
+ Arcfour.new(user_encryption_key).encrypt(PASSWORD_PADDING)
197
204
  end
198
205
  end
199
206
  end
@@ -204,46 +211,53 @@ module PDF
204
211
  module Core
205
212
  module_function
206
213
 
207
- # Like PdfObject, but returns an encrypted result if required.
214
+ # Like pdf_object, but returns an encrypted result if required.
208
215
  # For direct objects, requires the object identifier and generation number
209
216
  # from the indirect object referencing obj.
210
217
  #
211
218
  # @private
212
- def EncryptedPdfObject(obj, key, id, gen, in_content_stream = false)
219
+ def encrypted_pdf_object(obj, key, id, gen, in_content_stream = false)
213
220
  case obj
214
221
  when Array
215
- "[" << obj.map { |e|
216
- EncryptedPdfObject(e, key, id, gen, in_content_stream)
217
- }.join(' ') << "]"
222
+ '[' + obj.map do |e|
223
+ encrypted_pdf_object(e, key, id, gen, in_content_stream)
224
+ end.join(' ') + ']'
218
225
  when LiteralString
219
- obj = ByteString.new(Prawn::Document::Security.encrypt_string(obj, key, id, gen)).gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
226
+ obj = ByteString.new(
227
+ Prawn::Document::Security.encrypt_string(obj, key, id, gen)
228
+ ).gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
220
229
  "(#{obj})"
221
230
  when Time
222
- obj = obj.strftime("D:%Y%m%d%H%M%S%z").chop.chop + "'00'"
223
- obj = ByteString.new(Prawn::Document::Security.encrypt_string(obj, key, id, gen)).gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
231
+ obj = obj.strftime('D:%Y%m%d%H%M%S%z').chop.chop + "'00'"
232
+ obj = ByteString.new(
233
+ Prawn::Document::Security.encrypt_string(obj, key, id, gen)
234
+ ).gsub(/[\\\n\(\)]/) { |m| "\\#{m}" }
224
235
  "(#{obj})"
225
236
  when String
226
- PdfObject(
237
+ pdf_object(
227
238
  ByteString.new(
228
- Prawn::Document::Security.encrypt_string(obj, key, id, gen)),
229
- in_content_stream)
239
+ Prawn::Document::Security.encrypt_string(obj, key, id, gen)
240
+ ),
241
+ in_content_stream
242
+ )
230
243
  when ::Hash
231
- output = "<< "
232
- obj.each do |k, v|
233
- unless String === k || Symbol === k
234
- fail PDF::Core::Errors::FailedObjectConversion,
235
- "A PDF Dictionary must be keyed by names"
236
- end
237
- output << PdfObject(k.to_sym, in_content_stream) << " " << EncryptedPdfObject(v, key, id, gen, in_content_stream) << "\n"
238
- end
239
- output << ">>"
244
+ '<< ' +
245
+ obj.map do |k, v|
246
+ unless k.is_a?(String) || k.is_a?(Symbol)
247
+ raise PDF::Core::Errors::FailedObjectConversion,
248
+ 'A PDF Dictionary must be keyed by names'
249
+ end
250
+ pdf_object(k.to_sym, in_content_stream) + ' ' +
251
+ encrypted_pdf_object(v, key, id, gen, in_content_stream) + "\n"
252
+ end.join('') +
253
+ '>>'
240
254
  when NameTree::Value
241
- PdfObject(obj.name) + " " +
242
- EncryptedPdfObject(obj.value, key, id, gen, in_content_stream)
255
+ pdf_object(obj.name) + ' ' +
256
+ encrypted_pdf_object(obj.value, key, id, gen, in_content_stream)
243
257
  when PDF::Core::OutlineRoot, PDF::Core::OutlineItem
244
- EncryptedPdfObject(obj.to_hash, key, id, gen, in_content_stream)
245
- else # delegate back to PdfObject
246
- PdfObject(obj, in_content_stream)
258
+ encrypted_pdf_object(obj.to_hash, key, id, gen, in_content_stream)
259
+ else # delegate back to pdf_object
260
+ pdf_object(obj, in_content_stream)
247
261
  end
248
262
  end
249
263
 
@@ -251,7 +265,10 @@ module PDF
251
265
  class Stream
252
266
  def encrypted_object(key, id, gen)
253
267
  if filtered_stream
254
- "stream\n#{Prawn::Document::Security.encrypt_string filtered_stream, key, id, gen}\nendstream\n"
268
+ "stream\n" +
269
+ Prawn::Document::Security.encrypt_string(
270
+ filtered_stream, key, id, gen
271
+ ) + "\nendstream\n"
255
272
  else
256
273
  ''
257
274
  end
@@ -263,13 +280,16 @@ module PDF
263
280
  # Returns the object definition for the object this references, keyed from
264
281
  # +key+.
265
282
  def encrypted_object(key)
266
- @on_encode.call(self) if @on_encode
283
+ @on_encode&.call(self)
267
284
 
268
- output = "#{@identifier} #{gen} obj\n"
285
+ output = +"#{@identifier} #{gen} obj\n"
269
286
  if @stream.empty?
270
- output << PDF::Core::EncryptedPdfObject(data, key, @identifier, gen) << "\n"
287
+ output <<
288
+ PDF::Core.encrypted_pdf_object(data, key, @identifier, gen) << "\n"
271
289
  else
272
- output << PDF::Core::EncryptedPdfObject(data.merge(@stream.data), key, @identifier, gen) << "\n" <<
290
+ output << PDF::Core.encrypted_pdf_object(
291
+ data.merge(@stream.data), key, @identifier, gen
292
+ ) << "\n" <<
273
293
  @stream.encrypted_object(key, @identifier, gen)
274
294
  end
275
295