prawn 2.3.0 → 2.4.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 (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +2 -31
  5. data/lib/prawn.rb +1 -0
  6. data/lib/prawn/document.rb +20 -15
  7. data/lib/prawn/document/bounding_box.rb +10 -2
  8. data/lib/prawn/document/span.rb +2 -1
  9. data/lib/prawn/font.rb +6 -4
  10. data/lib/prawn/font_metric_cache.rb +7 -6
  11. data/lib/prawn/fonts/afm.rb +18 -16
  12. data/lib/prawn/fonts/ttf.rb +55 -29
  13. data/lib/prawn/graphics.rb +11 -11
  14. data/lib/prawn/graphics/color.rb +18 -16
  15. data/lib/prawn/graphics/join_style.rb +1 -1
  16. data/lib/prawn/graphics/patterns.rb +57 -49
  17. data/lib/prawn/graphics/transformation.rb +3 -3
  18. data/lib/prawn/grid.rb +36 -1
  19. data/lib/prawn/images.rb +29 -27
  20. data/lib/prawn/images/jpg.rb +4 -1
  21. data/lib/prawn/images/png.rb +2 -1
  22. data/lib/prawn/outline.rb +6 -5
  23. data/lib/prawn/repeater.rb +1 -1
  24. data/lib/prawn/security.rb +39 -36
  25. data/lib/prawn/text.rb +18 -18
  26. data/lib/prawn/text/box.rb +10 -9
  27. data/lib/prawn/text/formatted/arranger.rb +38 -19
  28. data/lib/prawn/text/formatted/box.rb +20 -15
  29. data/lib/prawn/text/formatted/line_wrap.rb +18 -16
  30. data/lib/prawn/text/formatted/parser.rb +28 -26
  31. data/lib/prawn/text/formatted/wrap.rb +15 -11
  32. data/lib/prawn/version.rb +1 -1
  33. data/lib/prawn/view.rb +2 -2
  34. data/manual/basic_concepts/measurement.rb +1 -1
  35. data/manual/bounding_box/canvas.rb +3 -3
  36. data/manual/bounding_box/nesting.rb +1 -1
  37. data/manual/document_and_page_options/background.rb +6 -2
  38. data/manual/document_and_page_options/document_and_page_options.rb +3 -3
  39. data/manual/document_and_page_options/print_scaling.rb +2 -1
  40. data/manual/graphics/common_lines.rb +1 -1
  41. data/manual/graphics/fill_and_stroke.rb +1 -1
  42. data/manual/graphics/fill_rules.rb +4 -3
  43. data/manual/graphics/helper.rb +11 -4
  44. data/manual/graphics/lines_and_curves.rb +1 -1
  45. data/manual/graphics/stroke_dash.rb +5 -5
  46. data/manual/graphics/translate.rb +2 -1
  47. data/manual/images/horizontal.rb +2 -2
  48. data/manual/images/scale.rb +3 -3
  49. data/manual/images/vertical.rb +6 -3
  50. data/manual/images/width_and_height.rb +3 -3
  51. data/manual/layout/content.rb +2 -2
  52. data/manual/outline/outline.rb +1 -1
  53. data/manual/security/permissions.rb +4 -2
  54. data/manual/security/security.rb +1 -1
  55. data/manual/text/alignment.rb +2 -2
  56. data/manual/text/column_box.rb +2 -2
  57. data/manual/text/font_style.rb +5 -2
  58. data/manual/text/formatted_callbacks.rb +17 -12
  59. data/manual/text/formatted_text.rb +7 -4
  60. data/manual/text/free_flowing_text.rb +3 -3
  61. data/manual/text/kerning_and_character_spacing.rb +4 -4
  62. data/manual/text/paragraph_indentation.rb +4 -5
  63. data/manual/text/rendering_and_color.rb +1 -1
  64. data/manual/text/right_to_left_text.rb +6 -6
  65. data/manual/text/rotation.rb +8 -3
  66. data/manual/text/text_box_extensions.rb +1 -1
  67. data/manual/text/text_box_overflow.rb +11 -9
  68. data/manual/text/win_ansi_charset.rb +9 -9
  69. data/prawn.gemspec +4 -10
  70. data/spec/prawn/document/bounding_box_spec.rb +82 -78
  71. data/spec/prawn/document/security_spec.rb +1 -1
  72. data/spec/prawn/document_span_spec.rb +14 -6
  73. data/spec/prawn/document_spec.rb +29 -26
  74. data/spec/prawn/font_spec.rb +16 -14
  75. data/spec/prawn/graphics_spec.rb +79 -44
  76. data/spec/prawn/images_spec.rb +13 -8
  77. data/spec/prawn/outline_spec.rb +127 -27
  78. data/spec/prawn/repeater_spec.rb +9 -8
  79. data/spec/prawn/soft_mask_spec.rb +1 -1
  80. data/spec/prawn/stamp_spec.rb +3 -2
  81. data/spec/prawn/text/box_spec.rb +57 -59
  82. data/spec/prawn/text/formatted/arranger_spec.rb +10 -10
  83. data/spec/prawn/text/formatted/box_spec.rb +8 -5
  84. data/spec/prawn/text/formatted/line_wrap_spec.rb +2 -1
  85. data/spec/prawn/text_draw_text_spec.rb +9 -8
  86. data/spec/prawn/text_spacing_spec.rb +2 -2
  87. data/spec/prawn/text_spec.rb +9 -9
  88. data/spec/prawn/text_with_inline_formatting_spec.rb +1 -1
  89. data/spec/prawn_manual_spec.rb +4 -4
  90. metadata +14 -98
  91. metadata.gz.sig +0 -0
@@ -14,23 +14,24 @@ module Prawn
14
14
  class Parser
15
15
  # @group Extension API
16
16
 
17
- PARSER_REGEX = begin
18
- regex_string = "\n|" \
19
- '<b>|</b>|' \
20
- '<i>|</i>|' \
21
- '<u>|</u>|' \
22
- '<strikethrough>|</strikethrough>|' \
23
- '<sub>|</sub>|' \
24
- '<sup>|</sup>|' \
25
- '<link[^>]*>|</link>|' \
26
- '<color[^>]*>|</color>|' \
27
- '<font[^>]*>|</font>|' \
28
- '<strong>|</strong>|' \
29
- '<em>|</em>|' \
30
- '<a[^>]*>|</a>|' \
31
- "[^<\n]+"
32
- Regexp.new(regex_string, Regexp::MULTILINE)
33
- end
17
+ PARSER_REGEX =
18
+ begin
19
+ regex_string = "\n|" \
20
+ '<b>|</b>|' \
21
+ '<i>|</i>|' \
22
+ '<u>|</u>|' \
23
+ '<strikethrough>|</strikethrough>|' \
24
+ '<sub>|</sub>|' \
25
+ '<sup>|</sup>|' \
26
+ '<link[^>]*>|</link>|' \
27
+ '<color[^>]*>|</color>|' \
28
+ '<font[^>]*>|</font>|' \
29
+ '<strong>|</strong>|' \
30
+ '<em>|</em>|' \
31
+ '<a[^>]*>|</a>|' \
32
+ "[^<\n]+"
33
+ Regexp.new(regex_string, Regexp::MULTILINE)
34
+ end
34
35
 
35
36
  def self.format(string, *_args)
36
37
  tokens = string.gsub(%r{<br\s*/?>}, "\n").scan(PARSER_REGEX)
@@ -54,7 +55,7 @@ module Prawn
54
55
  subscript: '</sub>',
55
56
  superscript: '</sup>'
56
57
  }
57
- array.collect do |hash|
58
+ array.map do |hash|
58
59
  prefix = ''
59
60
  suffix = ''
60
61
  hash[:styles]&.each do |style|
@@ -81,14 +82,15 @@ module Prawn
81
82
  end
82
83
 
83
84
  if hash[:color]
84
- prefix += if hash[:color].is_a?(Array)
85
- "<color c='#{hash[:color][0]}'" \
86
- " m='#{hash[:color][1]}'" \
87
- " y='#{hash[:color][2]}'" \
88
- " k='#{hash[:color][3]}'>"
89
- else
90
- "<color rgb='#{hash[:color]}'>"
91
- end
85
+ prefix +=
86
+ if hash[:color].is_a?(Array)
87
+ "<color c='#{hash[:color][0]}'" \
88
+ " m='#{hash[:color][1]}'" \
89
+ " y='#{hash[:color][2]}'" \
90
+ " k='#{hash[:color][3]}'>"
91
+ else
92
+ "<color rgb='#{hash[:color]}'>"
93
+ end
92
94
  suffix = '</color>'
93
95
  end
94
96
 
@@ -98,8 +98,10 @@ module Prawn
98
98
  fragments_this_line.each do |fragment_this_line|
99
99
  fragment_this_line.default_direction = @direction
100
100
  format_and_draw_fragment(
101
- fragment_this_line, accumulated_width,
102
- @line_wrap.width, word_spacing
101
+ fragment_this_line,
102
+ accumulated_width,
103
+ @line_wrap.width,
104
+ word_spacing
103
105
  )
104
106
  accumulated_width += fragment_this_line.width
105
107
  end
@@ -122,11 +124,12 @@ module Prawn
122
124
  @line_height = @arranger.max_line_height
123
125
  @descender = @arranger.max_descender
124
126
  @ascender = @arranger.max_ascender
125
- diff = if @baseline_y.zero?
126
- @ascender + @descender
127
- else
128
- @descender + @line_height + @leading
129
- end
127
+ diff =
128
+ if @baseline_y.zero?
129
+ @ascender + @descender
130
+ else
131
+ @descender + @line_height + @leading
132
+ end
130
133
  require_relatived_total_height = @baseline_y.abs + diff
131
134
  if require_relatived_total_height > @height + 0.0001
132
135
  # no room for the full height of this line
@@ -152,12 +155,13 @@ module Prawn
152
155
  @everything_printed = false
153
156
  end
154
157
 
155
- def format_and_draw_fragment(fragment, accumulated_width,
156
- line_width, word_spacing)
158
+ def format_and_draw_fragment(fragment, accumulated_width, line_width, word_spacing)
157
159
  @arranger.apply_color_and_font_settings(fragment) do
158
160
  draw_fragment(
159
- fragment, accumulated_width,
160
- line_width, word_spacing
161
+ fragment,
162
+ accumulated_width,
163
+ line_width,
164
+ word_spacing
161
165
  )
162
166
  end
163
167
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prawn
4
- VERSION = '2.3.0'
4
+ VERSION = '2.4.0'
5
5
  end
@@ -72,11 +72,11 @@ module Prawn
72
72
  def method_missing(method_name, *arguments, &block)
73
73
  return super unless document.respond_to?(method_name)
74
74
 
75
- document.send(method_name, *arguments, &block)
75
+ document.public_send(method_name, *arguments, &block)
76
76
  end
77
77
 
78
78
  def respond_to_missing?(method_name, _include_all = false)
79
- document.respond_to?(method_name)
79
+ document.respond_to?(method_name) || super
80
80
  end
81
81
 
82
82
  # Syntactic sugar that uses +instance_eval+ under the hood to provide
@@ -18,7 +18,7 @@ Prawn::ManualBuilder::Example.generate(filename) do
18
18
  require 'prawn/measurement_extensions'
19
19
 
20
20
  %i[mm cm dm m in yd ft].each do |measurement|
21
- text "1 #{measurement} in PDF Points: #{1.send(measurement)} pt"
21
+ text "1 #{measurement} in PDF Points: #{1.public_send(measurement)} pt"
22
22
  move_down 5.mm
23
23
  end
24
24
  end
@@ -15,9 +15,9 @@ require_relative '../example_helper'
15
15
  filename = File.basename(__FILE__).gsub('.rb', '.pdf')
16
16
  Prawn::ManualBuilder::Example.generate(filename) do
17
17
  canvas do
18
- fill_circle [bounds.left, bounds.top], 30
19
- fill_circle [bounds.right, bounds.top], 30
18
+ fill_circle [bounds.left, bounds.top], 30
19
+ fill_circle [bounds.right, bounds.top], 30
20
20
  fill_circle [bounds.right, bounds.bottom], 30
21
- fill_circle [0, 0], 30
21
+ fill_circle [0, 0], 30
22
22
  end
23
23
  end
@@ -3,7 +3,7 @@
3
3
  # Normally when we provide the top left corner of a bounding box we
4
4
  # express the coordinates relative to the margin box. This is not the
5
5
  # case when we have nested bounding boxes. Once nested the inner bounding box
6
- # coordinates are relative to the outter bounding box.
6
+ # coordinates are relative to the outer bounding box.
7
7
  #
8
8
  # This example shows some nested bounding boxes with fixed and stretchy heights.
9
9
  # Note how the <code>cursor</code> method returns coordinates relative to
@@ -16,10 +16,14 @@ Prawn::Document.generate(filename, background: img, margin: 100) do
16
16
  move_down font.height * 2
17
17
 
18
18
  text 'Here is my text explaning this report. ' * 20,
19
- size: 12, align: :left, leading: 2
19
+ size: 12,
20
+ align: :left,
21
+ leading: 2
20
22
 
21
23
  move_down font.height
22
24
 
23
25
  text "I'm using a soft background. " * 40,
24
- size: 12, align: :left, leading: 2
26
+ size: 12,
27
+ align: :left,
28
+ leading: 2
25
29
  end
@@ -7,10 +7,10 @@ require_relative '../example_helper'
7
7
  filename = File.basename(__FILE__).gsub('.rb', '.pdf')
8
8
  Prawn::ManualBuilder::Example.generate(filename, page_size: 'FOLIO') do
9
9
  package 'document_and_page_options' do |p|
10
- p.example 'page_size', eval_source: false, full_source: true
10
+ p.example 'page_size', eval_source: false, full_source: true
11
11
  p.example 'page_margins', eval_source: false, full_source: true
12
- p.example 'background', eval_source: false, full_source: true
13
- p.example 'metadata', eval_source: false, full_source: true
12
+ p.example 'background', eval_source: false, full_source: true
13
+ p.example 'metadata', eval_source: false, full_source: true
14
14
  p.example 'print_scaling', eval_source: false, full_source: true
15
15
 
16
16
  p.intro do
@@ -15,7 +15,8 @@ require_relative '../example_helper'
15
15
  filename = File.basename(__FILE__).gsub('.rb', '.pdf')
16
16
  Prawn::Document.generate(
17
17
  filename,
18
- page_layout: :landscape, print_scaling: :none
18
+ page_layout: :landscape,
19
+ print_scaling: :none
19
20
  ) do
20
21
  text 'When you print this document, the scale to fit in print preview '\
21
22
  'should be disabled by default.'
@@ -22,7 +22,7 @@ Prawn::ManualBuilder::Example.generate(filename) do
22
22
  move_down 50
23
23
  horizontal_rule
24
24
 
25
- vertical_line 100, 300, at: 50
25
+ vertical_line 100, 300, at: 50
26
26
 
27
27
  horizontal_line 200, 500, at: 150
28
28
  end
@@ -33,7 +33,7 @@ Prawn::ManualBuilder::Example.generate(filename) do
33
33
 
34
34
  # With block
35
35
  stroke { line [200, 200], [300, 150] }
36
- fill { rectangle [200, 100], 100, 100 }
36
+ fill { rectangle [200, 100], 100, 100 }
37
37
 
38
38
  # Method hook
39
39
  stroke_line [400, 200], [500, 150]
@@ -25,9 +25,10 @@ Prawn::ManualBuilder::Example.generate(filename) do
25
25
  stroke_color 'ff0000'
26
26
  line_width 2
27
27
 
28
- text_box 'Nonzero Winding Number', at: [50, 215],
29
- width: 170,
30
- align: :center
28
+ text_box 'Nonzero Winding Number',
29
+ at: [50, 215],
30
+ width: 170,
31
+ align: :center
31
32
  polygon(*pentagram.map { |x, y| [x + 50, y] })
32
33
  fill_and_stroke
33
34
 
@@ -17,11 +17,18 @@ filename = File.basename(__FILE__).gsub('.rb', '.pdf')
17
17
  Prawn::ManualBuilder::Example.generate(filename) do
18
18
  stroke_axis
19
19
  stroke_axis(
20
- at: [70, 70], height: 200, step_length: 50,
21
- negative_axes_length: 5, color: '0000FF'
20
+ at: [70, 70],
21
+ height: 200,
22
+ step_length: 50,
23
+ negative_axes_length: 5,
24
+ color: '0000FF'
22
25
  )
23
26
  stroke_axis(
24
- at: [140, 140], width: 200, height: cursor.to_i - 140,
25
- step_length: 20, negative_axes_length: 40, color: 'FF0000'
27
+ at: [140, 140],
28
+ width: 200,
29
+ height: cursor.to_i - 140,
30
+ step_length: 20,
31
+ negative_axes_length: 40,
32
+ color: 'FF0000'
26
33
  )
27
34
  end
@@ -29,7 +29,7 @@ Prawn::ManualBuilder::Example.generate(filename) do
29
29
  line_to 0, 100
30
30
 
31
31
  curve_to [150, 250], bounds: [[20, 200], [120, 200]]
32
- curve_to [200, 0], bounds: [[150, 200], [450, 10]]
32
+ curve_to [200, 0], bounds: [[150, 200], [450, 10]]
33
33
  end
34
34
 
35
35
  # line and curve
@@ -28,16 +28,16 @@ Prawn::ManualBuilder::Example.generate(filename) do
28
28
 
29
29
  24.times do |i|
30
30
  length = (i / 4) + 1
31
- space = length # space between dashes same length as dash
32
- phase = 0 # start with dash
31
+ space = length # space between dashes same length as dash
32
+ phase = 0 # start with dash
33
33
 
34
34
  case i % 4
35
35
  when 0 then base_y -= 5
36
- when 1 then phase = length # start with space between dashes
36
+ when 1 then phase = length # start with space between dashes
37
37
  when 2 then space = length * 0.5 # space between dashes half as long as dash
38
38
  when 3
39
- space = length * 0.5 # space between dashes half as long as dash
40
- phase = length # start with space between dashes
39
+ space = length * 0.5 # space between dashes half as long as dash
40
+ phase = length # start with space between dashes
41
41
  end
42
42
  base_y -= 5
43
43
 
@@ -16,7 +16,8 @@ Prawn::ManualBuilder::Example.generate(filename) do
16
16
  # Draw a point on the new origin
17
17
  fill_circle [0, 0], 2
18
18
  draw_text "New origin after translation to [#{x}, #{y}]",
19
- at: [5, -2], size: 8
19
+ at: [5, -2],
20
+ size: 8
20
21
 
21
22
  stroke_rectangle [100, 75], 100, 50
22
23
  text_box 'Top left corner at [100,75]',
@@ -14,11 +14,11 @@ Prawn::ManualBuilder::Example.generate(filename) do
14
14
  stroke_bounds
15
15
 
16
16
  %i[left center right].each do |position|
17
- text "Image aligned to the #{position}."
17
+ text "Image aligned to the #{position}."
18
18
  image "#{Prawn::DATADIR}/images/stef.jpg", position: position
19
19
  end
20
20
 
21
- text 'The next image has a 50 point offset from the left boundary'
21
+ text 'The next image has a 50 point offset from the left boundary'
22
22
  image "#{Prawn::DATADIR}/images/stef.jpg", position: 50
23
23
  end
24
24
  end
@@ -8,14 +8,14 @@ require_relative '../example_helper'
8
8
 
9
9
  filename = File.basename(__FILE__).gsub('.rb', '.pdf')
10
10
  Prawn::ManualBuilder::Example.generate(filename) do
11
- text 'Normal size'
11
+ text 'Normal size'
12
12
  image "#{Prawn::DATADIR}/images/stef.jpg"
13
13
  move_down 20
14
14
 
15
- text 'Scaled to 50%'
15
+ text 'Scaled to 50%'
16
16
  image "#{Prawn::DATADIR}/images/stef.jpg", scale: 0.5
17
17
  move_down 20
18
18
 
19
- text 'Scaled to 200%'
19
+ text 'Scaled to 200%'
20
20
  image "#{Prawn::DATADIR}/images/stef.jpg", scale: 2
21
21
  end
@@ -16,12 +16,15 @@ Prawn::ManualBuilder::Example.generate(filename) do
16
16
  %i[top center bottom].each do |vposition|
17
17
  text "Image vertically aligned to the #{vposition}.", valign: vposition
18
18
  image "#{Prawn::DATADIR}/images/stef.jpg",
19
- position: 250, vposition: vposition
19
+ position: 250,
20
+ vposition: vposition
20
21
  end
21
22
 
22
23
  text_box 'The next image has a 100 point offset from the top boundary',
23
- at: [bounds.width - 110, bounds.top - 10], width: 100
24
+ at: [bounds.width - 110, bounds.top - 10],
25
+ width: 100
24
26
  image "#{Prawn::DATADIR}/images/stef.jpg",
25
- position: :right, vposition: 100
27
+ position: :right,
28
+ vposition: 100
26
29
  end
27
30
  end
@@ -11,14 +11,14 @@ require_relative '../example_helper'
11
11
 
12
12
  filename = File.basename(__FILE__).gsub('.rb', '.pdf')
13
13
  Prawn::ManualBuilder::Example.generate(filename) do
14
- text 'Scale by setting only the width'
14
+ text 'Scale by setting only the width'
15
15
  image "#{Prawn::DATADIR}/images/pigs.jpg", width: 150
16
16
  move_down 20
17
17
 
18
- text 'Scale by setting only the height'
18
+ text 'Scale by setting only the height'
19
19
  image "#{Prawn::DATADIR}/images/pigs.jpg", height: 100
20
20
  move_down 20
21
21
 
22
- text 'Stretch to fit the width and height provided'
22
+ text 'Stretch to fit the width and height provided'
23
23
  image "#{Prawn::DATADIR}/images/pigs.jpg", width: 500, height: 100
24
24
  end
@@ -15,10 +15,10 @@ Prawn::ManualBuilder::Example.generate(filename) do
15
15
  define_grid(columns: 5, rows: 8, gutter: 10)
16
16
 
17
17
  grid([5, 0], [7, 1]).bounding_box do
18
- text "Adding some content to this multi_box.\n" + ' _ ' * 200
18
+ text "Adding some content to this multi_box.\n#{' _ ' * 200}"
19
19
  end
20
20
 
21
21
  grid(6, 3).bounding_box do
22
- text "Just a little snippet here.\n" + ' _ ' * 10
22
+ text "Just a little snippet here.\n#{' _ ' * 10}"
23
23
  end
24
24
  end
@@ -11,7 +11,7 @@ Prawn::ManualBuilder::Example.generate('outline.pdf', page_size: 'FOLIO') do
11
11
  end
12
12
 
13
13
  p.section 'Adding nodes later' do |s|
14
- s.example 'add_subsection_to', eval_source: false
14
+ s.example 'add_subsection_to', eval_source: false
15
15
  s.example 'insert_section_after', eval_source: false
16
16
  end
17
17
 
@@ -21,7 +21,8 @@ require_relative '../example_helper'
21
21
  Prawn::ManualBuilder::Example.generate('cannot_print.pdf') do
22
22
  text "If you used the user password you won't be able to print the doc."
23
23
  encrypt_document(
24
- user_password: 'foo', owner_password: 'bar',
24
+ user_password: 'foo',
25
+ owner_password: 'bar',
25
26
  permissions: { print_document: false }
26
27
  )
27
28
  end
@@ -30,7 +31,8 @@ end
30
31
  Prawn::ManualBuilder::Example.generate('no_permissions.pdf') do
31
32
  text "You may only view this and won't be able to use the owner password."
32
33
  encrypt_document(
33
- user_password: 'foo', owner_password: :random,
34
+ user_password: 'foo',
35
+ owner_password: :random,
34
36
  permissions: {
35
37
  print_document: false,
36
38
  modify_contents: false,
@@ -6,7 +6,7 @@ require_relative '../example_helper'
6
6
 
7
7
  Prawn::ManualBuilder::Example.generate('security.pdf', page_size: 'FOLIO') do
8
8
  package 'security' do |p|
9
- p.example 'encryption', eval_source: false, full_source: true
9
+ p.example 'encryption', eval_source: false, full_source: true
10
10
  p.example 'permissions', eval_source: false, full_source: true
11
11
 
12
12
  p.intro do