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,43 +1,59 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # text/formatted/parser.rb : Implements a bi-directional parser between a subset
4
- # of html and formatted text arrays
5
- #
6
- # Copyright February 2010, Daniel Nelson. All Rights Reserved.
7
- #
8
- # This is free software. Please see the LICENSE and COPYING files for details.
9
- #
10
-
11
3
  module Prawn
12
4
  module Text
13
5
  module Formatted
6
+ # Implements a bi-directional parser between a subset of html and
7
+ # formatted text arrays.
14
8
  class Parser
15
9
  # @group Extension API
16
10
 
11
+ # Parser regular expression.
12
+ # @private
17
13
  PARSER_REGEX =
18
14
  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]+"
15
+ regex_string =
16
+ "\n|" \
17
+ '<b>|</b>|' \
18
+ '<i>|</i>|' \
19
+ '<u>|</u>|' \
20
+ '<strikethrough>|</strikethrough>|' \
21
+ '<sub>|</sub>|' \
22
+ '<sup>|</sup>|' \
23
+ '<link[^>]*>|</link>|' \
24
+ '<color[^>]*>|</color>|' \
25
+ '<font[^>]*>|</font>|' \
26
+ '<strong>|</strong>|' \
27
+ '<em>|</em>|' \
28
+ '<a[^>]*>|</a>|' \
29
+ "[^<\n]+"
33
30
  Regexp.new(regex_string, Regexp::MULTILINE)
34
31
  end
35
32
 
33
+ # Escaped characters.
34
+ # @private
35
+ ESCAPE_CHARS = {
36
+ '&' => '&amp;',
37
+ '>' => '&gt;',
38
+ '<' => '&lt;',
39
+ }.freeze
40
+
41
+ # @private
42
+ UNESCAPE_CHARS = ESCAPE_CHARS.invert.freeze
43
+
44
+ # Parse formatted string.
45
+ #
46
+ # @param string [String]
47
+ # @return [Array<Hash>] Text fragments.
36
48
  def self.format(string, *_args)
37
49
  tokens = string.gsub(%r{<br\s*/?>}, "\n").scan(PARSER_REGEX)
38
50
  array_from_tokens(tokens)
39
51
  end
40
52
 
53
+ # Serialize text fragments to an inline format string.
54
+ #
55
+ # @param array [Array<Hash>]
56
+ # @return [String]
41
57
  def self.to_string(array)
42
58
  prefixes = {
43
59
  bold: '<b>',
@@ -45,7 +61,7 @@ module Prawn
45
61
  underline: '<u>',
46
62
  strikethrough: '<strikethrough>',
47
63
  subscript: '<sub>',
48
- superscript: '<sup>'
64
+ superscript: '<sup>',
49
65
  }
50
66
  suffixes = {
51
67
  bold: '</b>',
@@ -53,54 +69,60 @@ module Prawn
53
69
  underline: '</u>',
54
70
  strikethrough: '</strikethrough>',
55
71
  subscript: '</sub>',
56
- superscript: '</sup>'
72
+ superscript: '</sup>',
57
73
  }
58
- array.map do |hash|
59
- prefix = ''
60
- suffix = ''
61
- hash[:styles]&.each do |style|
62
- prefix += prefixes[style]
63
- suffix = suffixes[style] + suffix
64
- end
74
+ array
75
+ .map { |hash|
76
+ prefix = ''
77
+ suffix = ''
78
+ hash[:styles]&.each do |style|
79
+ prefix += prefixes[style]
80
+ suffix = suffixes[style] + suffix
81
+ end
65
82
 
66
- font = hash[:font] ? " name='#{hash[:font]}'" : nil
67
- size = hash[:size] ? " size='#{hash[:size]}'" : nil
68
- character_spacing =
69
- if hash[:character_spacing]
70
- " character_spacing='#{hash[:character_spacing]}'"
83
+ font = hash[:font] ? " name='#{hash[:font]}'" : nil
84
+ size = hash[:size] ? " size='#{hash[:size]}'" : nil
85
+ character_spacing =
86
+ if hash[:character_spacing]
87
+ " character_spacing='#{hash[:character_spacing]}'"
88
+ end
89
+ if font || size || character_spacing
90
+ prefix += "<font#{font}#{size}#{character_spacing}>"
91
+ suffix = '</font>'
71
92
  end
72
- if font || size || character_spacing
73
- prefix += "<font#{font}#{size}#{character_spacing}>"
74
- suffix = '</font>'
75
- end
76
93
 
77
- link = hash[:link] ? " href='#{hash[:link]}'" : nil
78
- anchor = hash[:anchor] ? " anchor='#{hash[:anchor]}'" : nil
79
- if link || anchor
80
- prefix += "<link#{link}#{anchor}>"
81
- suffix = '</link>'
82
- end
94
+ link = hash[:link] ? " href='#{hash[:link]}'" : nil
95
+ anchor = hash[:anchor] ? " anchor='#{hash[:anchor]}'" : nil
96
+ if link || anchor
97
+ prefix += "<link#{link}#{anchor}>"
98
+ suffix = '</link>'
99
+ end
83
100
 
84
- if hash[:color]
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
94
- suffix = '</color>'
95
- end
101
+ if hash[:color]
102
+ prefix +=
103
+ if hash[:color].is_a?(Array)
104
+ "<color c='#{hash[:color][0]}' " \
105
+ "m='#{hash[:color][1]}' " \
106
+ "y='#{hash[:color][2]}' " \
107
+ "k='#{hash[:color][3]}'>"
108
+ else
109
+ "<color rgb='#{hash[:color]}'>"
110
+ end
111
+ suffix = '</color>'
112
+ end
96
113
 
97
- string = hash[:text].gsub('&', '&amp;').gsub('>', '&gt;')
98
- .gsub('<', '&lt;')
99
- prefix + string + suffix
100
- end.join
114
+ string = escape(hash[:text])
115
+ prefix + string + suffix
116
+ }
117
+ .join
101
118
  end
102
119
 
103
- def self.array_paragraphs(array) #:nodoc:
120
+ # Break text into paragraphs.
121
+ #
122
+ # @private
123
+ # @param array [Array<Hash>] Text fragments.
124
+ # @return [Array<Array<Hash>>] Pragraphs of text fragments.
125
+ def self.array_paragraphs(array)
104
126
  paragraphs = []
105
127
  paragraph = []
106
128
  previous_string = "\n"
@@ -123,6 +145,9 @@ module Prawn
123
145
  paragraphs
124
146
  end
125
147
 
148
+ # @private
149
+ # @param tokens [Array<String>]
150
+ # @return [Array<Hash>]
126
151
  def self.array_from_tokens(tokens)
127
152
  array = []
128
153
  styles = []
@@ -189,16 +214,16 @@ module Prawn
189
214
 
190
215
  match = /c="#?([^"]*)"/.match(token) ||
191
216
  /c='#?([^']*)'/.match(token)
192
- c = match[1].to_i unless match.nil?
217
+ c = Integer(match[1], 10) unless match.nil?
193
218
  match = /m="#?([^"]*)"/.match(token) ||
194
219
  /m='#?([^']*)'/.match(token)
195
- m = match[1].to_i unless match.nil?
220
+ m = Integer(match[1], 10) unless match.nil?
196
221
  match = /y="#?([^"]*)"/.match(token) ||
197
222
  /y='#?([^']*)'/.match(token)
198
- y = match[1].to_i unless match.nil?
223
+ y = Integer(match[1], 10) unless match.nil?
199
224
  match = /k="#?([^"]*)"/.match(token) ||
200
225
  /k='#?([^']*)'/.match(token)
201
- k = match[1].to_i unless match.nil?
226
+ k = Integer(match[1], 10) unless match.nil?
202
227
  colors << [c, m, y, k] if [c, m, y, k].all?
203
228
 
204
229
  # intend to support rgb="#ffffff" or rgb='#ffffff',
@@ -215,14 +240,13 @@ module Prawn
215
240
 
216
241
  matches = /size="([^"]*)"/.match(token) ||
217
242
  /size='([^']*)'/.match(token)
218
- sizes << matches[1].to_f unless matches.nil?
243
+ sizes << Float(matches[1]) unless matches.nil?
219
244
 
220
245
  matches = /character_spacing="([^"]*)"/.match(token) ||
221
246
  /character_spacing='([^']*)'/.match(token)
222
- character_spacings << matches[1].to_f unless matches.nil?
247
+ character_spacings << Float(matches[1]) unless matches.nil?
223
248
  else
224
- string = token.gsub('&lt;', '<').gsub('&gt;', '>')
225
- .gsub('&amp;', '&')
249
+ string = unescape(token)
226
250
  array << {
227
251
  text: string,
228
252
  styles: styles.dup,
@@ -232,12 +256,28 @@ module Prawn
232
256
  anchor: anchor,
233
257
  font: fonts.last,
234
258
  size: sizes.last,
235
- character_spacing: character_spacings.last
259
+ character_spacing: character_spacings.last,
236
260
  }
237
261
  end
238
262
  end
239
263
  array
240
264
  end
265
+
266
+ # Escape characters that can interfere with inline format parsing.
267
+ #
268
+ # @param text [String]
269
+ # @return [String]
270
+ def self.escape(text)
271
+ text.gsub(Regexp.union(ESCAPE_CHARS.keys), ESCAPE_CHARS)
272
+ end
273
+
274
+ # Unescape characters that can interfere with inline format parsing.
275
+ #
276
+ # @param text [String]
277
+ # @return [String]
278
+ def self.unescape(text)
279
+ text.gsub(Regexp.union(UNESCAPE_CHARS.keys), UNESCAPE_CHARS)
280
+ end
241
281
  end
242
282
  end
243
283
  end
@@ -1,25 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # wrap.rb: Handles text wrapping for for formatted text
4
- #
5
- # Contributed by Daniel Nelson
6
- #
7
- # This is free software. Please see the LICENSE and COPYING files for details.
8
-
9
3
  require_relative 'line_wrap'
10
4
  require_relative 'arranger'
11
5
 
12
6
  module Prawn
13
7
  module Text
14
- module Formatted #:nodoc:
8
+ module Formatted
9
+ # Handles text wrapping for for formatted text.
10
+ #
15
11
  # @private
16
-
17
- module Wrap #:nodoc:
12
+ module Wrap
18
13
  def initialize(_array, options)
19
14
  @line_wrap = Prawn::Text::Formatted::LineWrap.new
20
15
  @arranger = Prawn::Text::Formatted::Arranger.new(
21
16
  @document,
22
- kerning: options[:kerning]
17
+ kerning: options[:kerning],
23
18
  )
24
19
  @disable_wrap_by_char = options[:disable_wrap_by_char]
25
20
  end
@@ -44,7 +39,7 @@ module Prawn
44
39
  #
45
40
  # Returns any formatted text that was not printed
46
41
  #
47
- def wrap(array) #:nodoc:
42
+ def wrap(array)
48
43
  initialize_wrap(array)
49
44
 
50
45
  stop = false
@@ -57,7 +52,7 @@ module Prawn
57
52
  kerning: @kerning,
58
53
  width: available_width,
59
54
  arranger: @arranger,
60
- disable_wrap_by_char: @disable_wrap_by_char
55
+ disable_wrap_by_char: @disable_wrap_by_char,
61
56
  )
62
57
 
63
58
  if enough_height_for_this_line?
@@ -91,7 +86,7 @@ module Prawn
91
86
  printed_fragments << fragment.text
92
87
  fragments_this_line << fragment
93
88
  end
94
- @arranger.fragments.replace []
89
+ @arranger.fragments.replace([])
95
90
 
96
91
  accumulated_width = 0
97
92
  fragments_this_line.reverse! if @direction == :rtl
@@ -101,14 +96,14 @@ module Prawn
101
96
  fragment_this_line,
102
97
  accumulated_width,
103
98
  @line_wrap.width,
104
- word_spacing
99
+ word_spacing,
105
100
  )
106
101
  accumulated_width += fragment_this_line.width
107
102
  end
108
103
 
109
- @printed_lines << printed_fragments.map do |s|
104
+ @printed_lines << printed_fragments.map { |s|
110
105
  s.dup.force_encoding(::Encoding::UTF_8)
111
- end.join
106
+ }.join
112
107
  end
113
108
 
114
109
  def word_spacing_for_this_line
@@ -161,7 +156,7 @@ module Prawn
161
156
  fragment,
162
157
  accumulated_width,
163
158
  line_width,
164
- word_spacing
159
+ word_spacing,
165
160
  )
166
161
  end
167
162
  end
@@ -2,6 +2,81 @@
2
2
 
3
3
  require_relative 'formatted/wrap'
4
4
 
5
+ module Prawn
6
+ module Text
7
+ # Fancy pretty text.
8
+ module Formatted
9
+ # @group Stable API
10
+
11
+ # Draws the requested formatted text into a box.
12
+ #
13
+ # When the text overflows the rectangle shrink to fit or truncate the
14
+ # text. Text boxes are independent of the document y position.
15
+ #
16
+ # @example
17
+ # formatted_text_box([{ :text => "hello" },
18
+ # { :text => "world",
19
+ # :size => 24,
20
+ # :styles => [:bold, :italic] }])
21
+ #
22
+ # @param array [Array<Hash{Symbol => any}>]
23
+ # Formatted text is an array of hashes, where each hash defines text and
24
+ # format information. The following hash options are supported:
25
+ #
26
+ # - `:text` --- the text to format according to the other hash options.
27
+ # - `:styles` --- an array of styles to apply to this text. Available
28
+ # styles include `:bold`, `:italic`, `:underline`, `:strikethrough`,
29
+ # `:subscript`, and `:superscript`.
30
+ # - `:size` ---a number denoting the font size to apply to this text.
31
+ # - `:character_spacing` --- a number denoting how much to increase or
32
+ # decrease the default spacing between characters.
33
+ # - `:font` --- the name of a font. The name must be an AFM font with
34
+ # the desired faces or must be a font that is already registered using
35
+ # {Prawn::Document#font_families}.
36
+ # - `:color` --- anything compatible with
37
+ # {Prawn::Graphics::Color#fill_color} and
38
+ # {Prawn::Graphics::Color#stroke_color}.
39
+ # - :link` --- a URL to which to create a link. A clickable link will be
40
+ # created to that URL. Note that you must explicitly underline and
41
+ # color using the appropriate tags if you which to draw attention to
42
+ # the link.
43
+ # - `:anchor` --- a destination that has already been or will be
44
+ # registered using
45
+ # `PDF::Core::Destinations#add_dest`{:.language-plain}. A clickable
46
+ # link will be created to that destination. Note that you must
47
+ # explicitly underline and color using the appropriate tags if you
48
+ # which to draw attention to the link.
49
+ # - `:local` --- a file or application to be opened locally. A clickable
50
+ # link will be created to the provided local file or application. If
51
+ # the file is another PDF, it will be opened in a new window. Note
52
+ # that you must explicitly underline and color using the appropriate
53
+ # options if you which to draw attention to the link.
54
+ # - `:draw_text_callback` --- if provided, this Proc will be called
55
+ # instead of {#draw_text!} once per fragment for every low-level
56
+ # addition of text to the page.
57
+ # - `:callback` --- an object (or array of such objects) with two
58
+ # methods: `#render_behind`{:.language-plain} and
59
+ # `#render_in_front`{:.language-plain}, which are called immediately
60
+ # prior to and immediately after rendering the text fragment and which
61
+ # are passed the fragment as an argument.
62
+ # @param options [Hash{Symbol => any}]
63
+ # Accepts the same options as {Text::Box}.
64
+ #
65
+ # @return [Array<Hash>]
66
+ # A formatted text array representing any text that did not print under
67
+ # the current settings.
68
+ #
69
+ # @raise [Prawn::Text::Formatted::Arranger::BadFontFamily]
70
+ # If no font family is defined for the current font.
71
+ # @raise [Prawn::Errors::CannotFit]
72
+ # If not wide enough to print any text.
73
+ def formatted_text_box(array, options = {})
74
+ Text::Formatted::Box.new(array, options.merge(document: self)).render
75
+ end
76
+ end
77
+ end
78
+ end
79
+
5
80
  require_relative 'formatted/box'
6
81
  require_relative 'formatted/parser'
7
82
  require_relative 'formatted/fragment'