prawn 2.1.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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/GPLv2 +20 -21
- data/Gemfile +3 -9
- data/Rakefile +9 -41
- data/lib/prawn.rb +37 -49
- data/lib/prawn/document.rb +193 -141
- data/lib/prawn/document/bounding_box.rb +50 -30
- data/lib/prawn/document/column_box.rb +7 -7
- data/lib/prawn/document/internals.rb +8 -6
- data/lib/prawn/document/span.rb +22 -16
- data/lib/prawn/encoding.rb +69 -68
- data/lib/prawn/errors.rb +12 -7
- data/lib/prawn/font.rb +104 -69
- data/lib/prawn/font_metric_cache.rb +20 -13
- data/lib/prawn/{font → fonts}/afm.rb +108 -72
- data/lib/prawn/{font → fonts}/dfont.rb +5 -11
- data/lib/prawn/fonts/otf.rb +11 -0
- data/lib/prawn/fonts/ttc.rb +36 -0
- data/lib/prawn/{font → fonts}/ttf.rb +126 -81
- data/lib/prawn/graphics.rb +119 -81
- data/lib/prawn/graphics/blend_mode.rb +9 -8
- data/lib/prawn/graphics/cap_style.rb +3 -3
- data/lib/prawn/graphics/color.rb +43 -39
- data/lib/prawn/graphics/dash.rb +23 -11
- data/lib/prawn/graphics/join_style.rb +9 -3
- data/lib/prawn/graphics/patterns.rb +204 -102
- data/lib/prawn/graphics/transformation.rb +15 -9
- data/lib/prawn/graphics/transparency.rb +17 -13
- data/lib/prawn/grid.rb +84 -48
- data/lib/prawn/image_handler.rb +5 -5
- data/lib/prawn/images.rb +60 -49
- data/lib/prawn/images/image.rb +2 -1
- data/lib/prawn/images/jpg.rb +31 -22
- data/lib/prawn/images/png.rb +67 -63
- data/lib/prawn/measurement_extensions.rb +10 -9
- data/lib/prawn/measurements.rb +19 -15
- data/lib/prawn/outline.rb +98 -77
- data/lib/prawn/repeater.rb +15 -11
- data/lib/prawn/security.rb +93 -70
- data/lib/prawn/security/arcfour.rb +2 -2
- data/lib/prawn/soft_mask.rb +26 -26
- data/lib/prawn/stamp.rb +20 -13
- data/lib/prawn/text.rb +76 -60
- data/lib/prawn/text/box.rb +18 -14
- data/lib/prawn/text/formatted.rb +5 -5
- data/lib/prawn/text/formatted/arranger.rb +80 -40
- data/lib/prawn/text/formatted/box.rb +140 -101
- data/lib/prawn/text/formatted/fragment.rb +11 -14
- data/lib/prawn/text/formatted/line_wrap.rb +128 -67
- data/lib/prawn/text/formatted/parser.rb +147 -123
- data/lib/prawn/text/formatted/wrap.rb +48 -32
- data/lib/prawn/transformation_stack.rb +7 -5
- data/lib/prawn/utilities.rb +7 -22
- data/lib/prawn/version.rb +2 -2
- data/lib/prawn/view.rb +17 -7
- data/manual/basic_concepts/adding_pages.rb +6 -7
- data/manual/basic_concepts/basic_concepts.rb +31 -22
- data/manual/basic_concepts/creation.rb +10 -11
- data/manual/basic_concepts/cursor.rb +4 -5
- data/manual/basic_concepts/measurement.rb +7 -8
- data/manual/basic_concepts/origin.rb +5 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
- data/manual/basic_concepts/view.rb +22 -16
- data/manual/bounding_box/bounding_box.rb +29 -24
- data/manual/bounding_box/bounds.rb +11 -12
- data/manual/bounding_box/canvas.rb +7 -8
- data/manual/bounding_box/creation.rb +6 -7
- data/manual/bounding_box/indentation.rb +14 -15
- data/manual/bounding_box/nesting.rb +25 -18
- data/manual/bounding_box/russian_boxes.rb +14 -13
- data/manual/bounding_box/stretchy.rb +12 -13
- data/manual/contents.rb +28 -22
- data/manual/cover.rb +33 -28
- data/manual/document_and_page_options/background.rb +15 -13
- data/manual/document_and_page_options/document_and_page_options.rb +25 -20
- data/manual/document_and_page_options/metadata.rb +18 -16
- data/manual/document_and_page_options/page_margins.rb +18 -20
- data/manual/document_and_page_options/page_size.rb +13 -12
- data/manual/document_and_page_options/print_scaling.rb +18 -15
- data/manual/example_helper.rb +5 -4
- data/manual/graphics/blend_mode.rb +12 -9
- data/manual/graphics/circle_and_ellipse.rb +4 -5
- data/manual/graphics/color.rb +7 -9
- data/manual/graphics/common_lines.rb +7 -8
- data/manual/graphics/fill_and_stroke.rb +5 -6
- data/manual/graphics/fill_rules.rb +10 -10
- data/manual/graphics/gradients.rb +27 -21
- data/manual/graphics/graphics.rb +48 -40
- data/manual/graphics/helper.rb +19 -9
- data/manual/graphics/line_width.rb +8 -7
- data/manual/graphics/lines_and_curves.rb +7 -8
- data/manual/graphics/polygon.rb +6 -8
- data/manual/graphics/rectangle.rb +4 -5
- data/manual/graphics/rotate.rb +6 -7
- data/manual/graphics/scale.rb +14 -15
- data/manual/graphics/soft_masks.rb +3 -4
- data/manual/graphics/stroke_cap.rb +6 -7
- data/manual/graphics/stroke_dash.rb +15 -16
- data/manual/graphics/stroke_join.rb +5 -6
- data/manual/graphics/translate.rb +10 -10
- data/manual/graphics/transparency.rb +7 -8
- data/manual/how_to_read_this_manual.rb +6 -6
- data/manual/images/absolute_position.rb +6 -7
- data/manual/images/fit.rb +7 -8
- data/manual/images/horizontal.rb +10 -11
- data/manual/images/images.rb +28 -24
- data/manual/images/plain_image.rb +5 -6
- data/manual/images/scale.rb +9 -10
- data/manual/images/vertical.rb +16 -14
- data/manual/images/width_and_height.rb +10 -11
- data/manual/layout/boxes.rb +5 -6
- data/manual/layout/content.rb +7 -8
- data/manual/layout/layout.rb +18 -16
- data/manual/layout/simple_grid.rb +6 -7
- data/manual/outline/add_subsection_to.rb +20 -21
- data/manual/outline/insert_section_after.rb +15 -16
- data/manual/outline/outline.rb +21 -17
- data/manual/outline/sections_and_pages.rb +17 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +21 -17
- data/manual/repeatable_content/page_numbering.rb +17 -16
- data/manual/repeatable_content/repeatable_content.rb +25 -19
- data/manual/repeatable_content/repeater.rb +14 -15
- data/manual/repeatable_content/stamp.rb +14 -15
- data/manual/security/encryption.rb +9 -10
- data/manual/security/permissions.rb +21 -14
- data/manual/security/security.rb +19 -16
- data/manual/table.rb +3 -3
- data/manual/text/alignment.rb +16 -17
- data/manual/text/color.rb +12 -11
- data/manual/text/column_box.rb +9 -10
- data/manual/text/fallback_fonts.rb +25 -21
- data/manual/text/font.rb +11 -12
- data/manual/text/font_size.rb +13 -14
- data/manual/text/font_style.rb +10 -8
- data/manual/text/formatted_callbacks.rb +33 -24
- data/manual/text/formatted_text.rb +36 -25
- data/manual/text/free_flowing_text.rb +22 -23
- data/manual/text/inline.rb +18 -19
- data/manual/text/kerning_and_character_spacing.rb +14 -15
- data/manual/text/leading.rb +7 -8
- data/manual/text/line_wrapping.rb +37 -18
- data/manual/text/paragraph_indentation.rb +12 -14
- data/manual/text/positioned_text.rb +15 -16
- data/manual/text/registering_families.rb +20 -21
- data/manual/text/rendering_and_color.rb +9 -10
- data/manual/text/right_to_left_text.rb +26 -19
- data/manual/text/rotation.rb +33 -23
- data/manual/text/single_usage.rb +8 -9
- data/manual/text/text.rb +57 -52
- data/manual/text/text_box_excess.rb +20 -17
- data/manual/text/text_box_extensions.rb +18 -15
- data/manual/text/text_box_overflow.rb +20 -19
- data/manual/text/utf8.rb +11 -12
- data/manual/text/win_ansi_charset.rb +27 -25
- data/prawn.gemspec +41 -34
- data/spec/extensions/encoding_helpers.rb +3 -3
- data/spec/prawn/document/bounding_box_spec.rb +550 -0
- data/spec/prawn/document/column_box_spec.rb +75 -0
- data/spec/prawn/document/security_spec.rb +176 -0
- data/spec/prawn/document_annotations_spec.rb +76 -0
- data/spec/prawn/document_destinations_spec.rb +15 -0
- data/spec/prawn/document_grid_spec.rb +99 -0
- data/spec/prawn/document_reference_spec.rb +27 -0
- data/spec/prawn/document_span_spec.rb +44 -0
- data/spec/prawn/document_spec.rb +805 -0
- data/spec/prawn/font_metric_cache_spec.rb +54 -0
- data/spec/prawn/font_spec.rb +544 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
- data/spec/prawn/graphics/transparency_spec.rb +81 -0
- data/spec/prawn/graphics_spec.rb +872 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
- data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +14 -14
- data/spec/prawn/images/jpg_spec.rb +20 -0
- data/spec/prawn/images/png_spec.rb +283 -0
- data/spec/prawn/images_spec.rb +229 -0
- data/spec/prawn/measurements_extensions_spec.rb +24 -0
- data/spec/prawn/outline_spec.rb +512 -0
- data/spec/prawn/repeater_spec.rb +166 -0
- data/spec/prawn/soft_mask_spec.rb +74 -0
- data/spec/prawn/stamp_spec.rb +173 -0
- data/spec/prawn/text/box_spec.rb +1110 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
- data/spec/prawn/text/formatted/box_spec.rb +849 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
- data/spec/prawn/text/formatted/parser_spec.rb +697 -0
- data/spec/prawn/text_draw_text_spec.rb +150 -0
- data/spec/prawn/text_rendering_mode_spec.rb +48 -0
- data/spec/prawn/text_spacing_spec.rb +95 -0
- data/spec/prawn/text_spec.rb +603 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
- data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +22 -19
- data/spec/prawn/view_spec.rb +63 -0
- data/spec/prawn_manual_spec.rb +35 -0
- data/spec/spec_helper.rb +18 -19
- metadata +102 -222
- metadata.gz.sig +0 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +0 -0
- data/data/images/16bit.png +0 -0
- data/data/images/arrow.png +0 -0
- data/data/images/arrow2.png +0 -0
- data/data/images/blend_modes_bottom_layer.jpg +0 -0
- data/data/images/blend_modes_top_layer.jpg +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/indexed_transparency.png +0 -0
- data/data/images/indexed_transparency_alpha.dat +0 -0
- data/data/images/indexed_transparency_color.dat +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/prawn.png +0 -0
- data/data/images/ruport.png +0 -0
- data/data/images/ruport_data.dat +0 -0
- data/data/images/ruport_transparent.png +0 -0
- data/data/images/ruport_type0.png +0 -0
- data/data/images/stef.jpg +0 -0
- data/data/images/tru256.bmp +0 -0
- data/data/images/web-links.dat +0 -1
- data/data/images/web-links.png +0 -0
- data/data/pdfs/complex_template.pdf +0 -0
- data/data/pdfs/contains_ttf_font.pdf +0 -0
- data/data/pdfs/encrypted.pdf +0 -0
- data/data/pdfs/form.pdf +1 -819
- data/data/pdfs/hexagon.pdf +0 -61
- data/data/pdfs/indirect_reference.pdf +0 -86
- data/data/pdfs/multipage_template.pdf +0 -127
- data/data/pdfs/nested_pages.pdf +0 -118
- data/data/pdfs/page_without_mediabox.pdf +0 -193
- data/data/pdfs/resources_as_indirect_object.pdf +0 -83
- data/data/pdfs/two_hexagons.pdf +0 -90
- data/data/pdfs/version_1_6.pdf +0 -61
- data/data/shift_jis_text.txt +0 -1
- data/spec/acceptance/png_spec.rb +0 -35
- data/spec/annotations_spec.rb +0 -67
- data/spec/blend_mode_spec.rb +0 -71
- data/spec/bounding_box_spec.rb +0 -501
- data/spec/column_box_spec.rb +0 -59
- data/spec/destinations_spec.rb +0 -13
- data/spec/document_spec.rb +0 -738
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -475
- data/spec/formatted_text_arranger_spec.rb +0 -452
- data/spec/formatted_text_box_spec.rb +0 -716
- data/spec/formatted_text_fragment_spec.rb +0 -299
- data/spec/graphics_spec.rb +0 -705
- data/spec/grid_spec.rb +0 -95
- data/spec/images_spec.rb +0 -167
- data/spec/inline_formatted_text_parser_spec.rb +0 -568
- data/spec/jpg_spec.rb +0 -23
- data/spec/line_wrap_spec.rb +0 -366
- data/spec/measurement_units_spec.rb +0 -22
- data/spec/outline_spec.rb +0 -409
- data/spec/png_spec.rb +0 -257
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -154
- data/spec/security_spec.rb +0 -151
- data/spec/soft_mask_spec.rb +0 -78
- data/spec/span_spec.rb +0 -43
- data/spec/stamp_spec.rb +0 -179
- data/spec/stroke_styles_spec.rb +0 -208
- data/spec/text_at_spec.rb +0 -142
- data/spec/text_box_spec.rb +0 -1042
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -543
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
- data/spec/view_spec.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d64c2da1e4be48e40f4fa6fa4de35e04c75debf0119e8c59b3fba9d944c112db
|
4
|
+
data.tar.gz: 393bbdd1a5df657d5c6190d4bd10ecd7353522e714b2f60c8d9c5f70e5bc1ce9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4980639ca24796d577be790ed0f6fa85c985f1a6eb147e4c5db1df261c5d50afe8a466f06b65588b71a897e22e8d2b7b01daceed1714f6164124057154d2d28
|
7
|
+
data.tar.gz: e0fd560d4a80f2827736d599266bcb2e2fe19abedcde639520fba8bd19a2f12fe2cf0e8a60a91b87dbac4336d25c680f94b2341e5f9ce3d6d24f2e65f24e24a3
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/GPLv2
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
2
|
+
Version 2, June 1991
|
3
3
|
|
4
|
-
Copyright (C) 1989, 1991 Free Software Foundation, Inc
|
5
|
-
|
4
|
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
5
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6
6
|
Everyone is permitted to copy and distribute verbatim copies
|
7
7
|
of this license document, but changing it is not allowed.
|
8
8
|
|
9
|
-
|
9
|
+
Preamble
|
10
10
|
|
11
11
|
The licenses for most software are designed to take away your
|
12
12
|
freedom to share and change it. By contrast, the GNU General Public
|
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
|
15
15
|
General Public License applies to most of the Free Software
|
16
16
|
Foundation's software and to any other program whose authors commit to
|
17
17
|
using it. (Some other Free Software Foundation software is covered by
|
18
|
-
the GNU
|
18
|
+
the GNU Lesser General Public License instead.) You can apply it to
|
19
19
|
your programs, too.
|
20
20
|
|
21
21
|
When we speak of free software, we are referring to freedom, not
|
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|
55
55
|
|
56
56
|
The precise terms and conditions for copying, distribution and
|
57
57
|
modification follow.
|
58
|
-
|
59
|
-
|
58
|
+
|
59
|
+
GNU GENERAL PUBLIC LICENSE
|
60
60
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61
61
|
|
62
62
|
0. This License applies to any program or other work which contains
|
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
|
110
110
|
License. (Exception: if the Program itself is interactive but
|
111
111
|
does not normally print such an announcement, your work based on
|
112
112
|
the Program is not required to print an announcement.)
|
113
|
-
|
113
|
+
|
114
114
|
These requirements apply to the modified work as a whole. If
|
115
115
|
identifiable sections of that work are not derived from the Program,
|
116
116
|
and can be reasonably considered independent and separate works in
|
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
|
168
168
|
access to copy the source code from the same place counts as
|
169
169
|
distribution of the source code, even though third parties are not
|
170
170
|
compelled to copy the source along with the object code.
|
171
|
-
|
171
|
+
|
172
172
|
4. You may not copy, modify, sublicense, or distribute the Program
|
173
173
|
except as expressly provided under this License. Any attempt
|
174
174
|
otherwise to copy, modify, sublicense or distribute the Program is
|
@@ -225,7 +225,7 @@ impose that choice.
|
|
225
225
|
|
226
226
|
This section is intended to make thoroughly clear what is believed to
|
227
227
|
be a consequence of the rest of this License.
|
228
|
-
|
228
|
+
|
229
229
|
8. If the distribution and/or use of the Program is restricted in
|
230
230
|
certain countries either by patents or by copyrighted interfaces, the
|
231
231
|
original copyright holder who places the Program under this License
|
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
|
255
255
|
of preserving the free status of all derivatives of our free software and
|
256
256
|
of promoting the sharing and reuse of software generally.
|
257
257
|
|
258
|
-
|
258
|
+
NO WARRANTY
|
259
259
|
|
260
260
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261
261
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
277
277
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278
278
|
POSSIBILITY OF SUCH DAMAGES.
|
279
279
|
|
280
|
-
|
281
|
-
|
282
|
-
|
280
|
+
END OF TERMS AND CONDITIONS
|
281
|
+
|
282
|
+
How to Apply These Terms to Your New Programs
|
283
283
|
|
284
284
|
If you develop a new program, and you want it to be of the greatest
|
285
285
|
possible use to the public, the best way to achieve this is to make it
|
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
|
303
303
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
304
304
|
GNU General Public License for more details.
|
305
305
|
|
306
|
-
You should have received a copy of the GNU General Public License
|
307
|
-
|
308
|
-
|
309
|
-
|
306
|
+
You should have received a copy of the GNU General Public License along
|
307
|
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
308
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
310
309
|
|
311
310
|
Also add information on how to contact you by electronic and paper mail.
|
312
311
|
|
313
312
|
If the program is interactive, make it output a short notice like this
|
314
313
|
when it starts in an interactive mode:
|
315
314
|
|
316
|
-
Gnomovision version 69, Copyright (C) year
|
315
|
+
Gnomovision version 69, Copyright (C) year name of author
|
317
316
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
318
317
|
This is free software, and you are welcome to redistribute it
|
319
318
|
under certain conditions; type `show c' for details.
|
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
|
336
335
|
This General Public License does not permit incorporating your program into
|
337
336
|
proprietary programs. If your program is a subroutine library, you may
|
338
337
|
consider it more useful to permit linking proprietary applications with the
|
339
|
-
library. If this is what you want to do, use the GNU
|
338
|
+
library. If this is what you want to do, use the GNU Lesser General
|
340
339
|
Public License instead of this License.
|
data/Gemfile
CHANGED
@@ -1,11 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
|
6
|
-
platforms :rbx do
|
7
|
-
gem "rubysl-singleton", "~> 2.0"
|
8
|
-
gem "rubysl-digest", "~> 2.0"
|
9
|
-
gem "rubysl-enumerator", "~> 2.0"
|
10
|
-
end
|
11
|
-
end
|
5
|
+
gemspec
|
data/Rakefile
CHANGED
@@ -1,49 +1,19 @@
|
|
1
|
-
|
2
|
-
Bundler.setup
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
require '
|
6
|
-
require 'yard'
|
7
|
-
require 'rubygems/package_task'
|
8
|
-
require 'rubocop/rake_task'
|
3
|
+
GEMSPEC = File.expand_path('prawn.gemspec', __dir__)
|
4
|
+
require 'prawn/dev/tasks'
|
9
5
|
|
10
|
-
task :
|
11
|
-
|
12
|
-
desc "Run all rspec files"
|
13
|
-
RSpec::Core::RakeTask.new("spec") do |c|
|
14
|
-
c.rspec_opts = "-t ~unresolved"
|
15
|
-
end
|
16
|
-
|
17
|
-
desc "Show library's code statistics"
|
18
|
-
task :stats do
|
19
|
-
require 'code_statistics/code_statistics'
|
20
|
-
puts CodeStatistics::CodeStatistics.new(
|
21
|
-
[
|
22
|
-
["Prawn", "lib"],
|
23
|
-
["Specs", "spec"]
|
24
|
-
]
|
25
|
-
).to_s
|
26
|
-
end
|
27
|
-
|
28
|
-
YARD::Rake::YardocTask.new do |t|
|
29
|
-
t.options = ['--output-dir', 'doc/html']
|
30
|
-
end
|
31
|
-
task :docs => :yard
|
6
|
+
task default: %i[spec rubocop]
|
32
7
|
|
33
8
|
desc "Generate the 'Prawn by Example' manual"
|
34
9
|
task :manual do
|
35
|
-
puts
|
36
|
-
require File.expand_path(File.join(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
spec = Gem::Specification.load "prawn.gemspec"
|
41
|
-
Gem::PackageTask.new(spec) do |pkg|
|
42
|
-
pkg.need_zip = true
|
43
|
-
pkg.need_tar = true
|
10
|
+
puts 'Building manual...'
|
11
|
+
require File.expand_path(File.join(__dir__, %w[manual contents]))
|
12
|
+
prawn_manual_document.render_file('manual.pdf')
|
13
|
+
puts 'The Prawn manual is available at manual.pdf. Happy Prawning!'
|
44
14
|
end
|
45
15
|
|
46
|
-
desc
|
16
|
+
desc 'Run a console with Prawn loaded'
|
47
17
|
task :console do
|
48
18
|
require 'irb'
|
49
19
|
require 'irb/completion'
|
@@ -53,5 +23,3 @@ task :console do
|
|
53
23
|
ARGV.clear
|
54
24
|
IRB.start
|
55
25
|
end
|
56
|
-
|
57
|
-
RuboCop::RakeTask.new
|
data/lib/prawn.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Welcome to Prawn, the best PDF Generation library ever.
|
4
4
|
# This documentation covers user level functionality.
|
5
5
|
#
|
6
|
-
require
|
6
|
+
require 'set'
|
7
7
|
|
8
8
|
require 'ttfunk'
|
9
|
-
require
|
9
|
+
require 'pdf/core'
|
10
10
|
|
11
11
|
module Prawn
|
12
|
-
extend self
|
13
|
-
|
14
12
|
file = __FILE__
|
15
13
|
file = File.readlink(file) if File.symlink?(file)
|
16
|
-
dir
|
14
|
+
dir = File.dirname(file)
|
17
15
|
|
18
16
|
# The base source directory for Prawn as installed on the system
|
19
17
|
#
|
@@ -32,59 +30,49 @@ module Prawn
|
|
32
30
|
# Detected unknown option(s): [:tomato]
|
33
31
|
# Accepted options are: [:page_size, :page_layout, :left_margin, ...]
|
34
32
|
#
|
35
|
-
|
33
|
+
# @private
|
34
|
+
attr_accessor :debug
|
35
|
+
|
36
|
+
module_function :debug, :debug=
|
36
37
|
|
37
|
-
|
38
|
+
module_function
|
39
|
+
|
40
|
+
# @private
|
41
|
+
def verify_options(accepted, actual)
|
38
42
|
return unless debug || $DEBUG
|
43
|
+
|
39
44
|
unless (act = Set[*actual.keys]).subset?(acc = Set[*accepted])
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
raise Prawn::Errors::UnknownOption,
|
46
|
+
"\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" \
|
47
|
+
"Accepted options are: #{accepted.inspect}"
|
43
48
|
end
|
44
49
|
yield if block_given?
|
45
50
|
end
|
46
|
-
|
47
|
-
module Configurable # @private
|
48
|
-
def configuration(*args)
|
49
|
-
@config ||= Marshal.load(Marshal.dump(default_configuration))
|
50
|
-
if Hash === args[0]
|
51
|
-
@config.update(args[0])
|
52
|
-
elsif args.length > 1
|
53
|
-
@config.values_at(*args)
|
54
|
-
elsif args.length == 1
|
55
|
-
@config[args[0]]
|
56
|
-
else
|
57
|
-
@config
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
alias_method :C, :configuration
|
62
|
-
end
|
63
51
|
end
|
64
52
|
|
65
|
-
require_relative
|
53
|
+
require_relative 'prawn/version'
|
66
54
|
|
67
|
-
require_relative
|
55
|
+
require_relative 'prawn/errors'
|
68
56
|
|
69
|
-
require_relative
|
70
|
-
require_relative
|
71
|
-
require_relative
|
72
|
-
require_relative
|
73
|
-
require_relative
|
74
|
-
require_relative
|
75
|
-
require_relative
|
76
|
-
require_relative
|
77
|
-
require_relative
|
78
|
-
require_relative
|
79
|
-
require_relative
|
80
|
-
require_relative
|
81
|
-
require_relative
|
82
|
-
require_relative
|
83
|
-
require_relative
|
84
|
-
require_relative
|
85
|
-
require_relative
|
86
|
-
require_relative
|
87
|
-
require_relative
|
57
|
+
require_relative 'prawn/utilities'
|
58
|
+
require_relative 'prawn/text'
|
59
|
+
require_relative 'prawn/graphics'
|
60
|
+
require_relative 'prawn/images'
|
61
|
+
require_relative 'prawn/images/image'
|
62
|
+
require_relative 'prawn/images/jpg'
|
63
|
+
require_relative 'prawn/images/png'
|
64
|
+
require_relative 'prawn/stamp'
|
65
|
+
require_relative 'prawn/soft_mask'
|
66
|
+
require_relative 'prawn/security'
|
67
|
+
require_relative 'prawn/transformation_stack'
|
68
|
+
require_relative 'prawn/document'
|
69
|
+
require_relative 'prawn/font'
|
70
|
+
require_relative 'prawn/measurements'
|
71
|
+
require_relative 'prawn/repeater'
|
72
|
+
require_relative 'prawn/outline'
|
73
|
+
require_relative 'prawn/grid'
|
74
|
+
require_relative 'prawn/view'
|
75
|
+
require_relative 'prawn/image_handler'
|
88
76
|
|
89
77
|
Prawn.image_handler.register(Prawn::Images::PNG)
|
90
78
|
Prawn.image_handler.register(Prawn::Images::JPG)
|
data/lib/prawn/document.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# document.rb : Implements PDF document generation for Prawn
|
4
4
|
#
|
@@ -6,21 +6,21 @@
|
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
|
9
|
-
require
|
9
|
+
require 'stringio'
|
10
10
|
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
11
|
+
require_relative 'document/bounding_box'
|
12
|
+
require_relative 'document/column_box'
|
13
|
+
require_relative 'document/internals'
|
14
|
+
require_relative 'document/span'
|
15
15
|
|
16
16
|
module Prawn
|
17
17
|
# The Prawn::Document class is how you start creating a PDF document.
|
18
18
|
#
|
19
19
|
# 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
|
21
|
-
# of each type, each example does exactly the same thing, makes a PDF
|
22
|
-
# with all the defaults and puts in the default font "Hello There"
|
23
|
-
# saves it to the current directory as "example.pdf"
|
20
|
+
# are through assignment, implicit block or explicit block. Below is an
|
21
|
+
# example of each type, each example does exactly the same thing, makes a PDF
|
22
|
+
# 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"
|
24
24
|
#
|
25
25
|
# For example, assignment can be like this:
|
26
26
|
#
|
@@ -42,8 +42,8 @@ module Prawn
|
|
42
42
|
# pdf.text words
|
43
43
|
# end
|
44
44
|
#
|
45
|
-
# Usually, the block forms are used when you are simply creating a PDF
|
46
|
-
# that you want to immediately save or render out.
|
45
|
+
# Usually, the block forms are used when you are simply creating a PDF
|
46
|
+
# document that you want to immediately save or render out.
|
47
47
|
#
|
48
48
|
# See the new and generate methods for further details on the above.
|
49
49
|
#
|
@@ -64,10 +64,12 @@ module Prawn
|
|
64
64
|
# NOTE: We probably need to rethink the options validation system, but this
|
65
65
|
# constant temporarily allows for extensions to modify the list.
|
66
66
|
|
67
|
-
VALID_OPTIONS = [
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
VALID_OPTIONS = %i[
|
68
|
+
page_size page_layout margin left_margin
|
69
|
+
right_margin top_margin bottom_margin skip_page_creation
|
70
|
+
compress background info
|
71
|
+
text_formatter print_scaling
|
72
|
+
].freeze
|
71
73
|
|
72
74
|
# Any module added to this array will be included into instances of
|
73
75
|
# Prawn::Document at the per-object level. These will also be inherited by
|
@@ -96,6 +98,7 @@ module Prawn
|
|
96
98
|
|
97
99
|
# @private
|
98
100
|
def self.inherited(base)
|
101
|
+
super
|
99
102
|
extensions.each { |e| base.extensions << e }
|
100
103
|
end
|
101
104
|
|
@@ -153,15 +156,22 @@ module Prawn
|
|
153
156
|
# <tt>:right_margin</tt>:: Sets the right margin in points [0.5 inch]
|
154
157
|
# <tt>:top_margin</tt>:: Sets the top margin in points [0.5 inch]
|
155
158
|
# <tt>:bottom_margin</tt>:: Sets the bottom margin in points [0.5 inch]
|
156
|
-
# <tt>:skip_page_creation</tt>:: Creates a document without starting the
|
157
|
-
#
|
158
|
-
# <tt>:
|
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]
|
159
165
|
# <tt>:background_scale</tt>:: Backgound image scale [1] [nil]
|
160
|
-
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties
|
161
|
-
#
|
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]
|
162
171
|
#
|
163
|
-
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will
|
164
|
-
# of 100 points on every side except for the left, where
|
172
|
+
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will
|
173
|
+
# result in margins of 100 points on every side except for the left, where
|
174
|
+
# it will be 50.
|
165
175
|
#
|
166
176
|
# The :margin can also be an array much like CSS shorthand:
|
167
177
|
#
|
@@ -172,8 +182,8 @@ module Prawn
|
|
172
182
|
# # Top is 10, right is 20, bottom is 30, left is 40.
|
173
183
|
# :margin => [10, 20, 30, 40]
|
174
184
|
#
|
175
|
-
# Additionally, :page_size can be specified as a simple two value array
|
176
|
-
# the width and height of the document you need in PDF Points.
|
185
|
+
# Additionally, :page_size can be specified as a simple two value array
|
186
|
+
# giving the width and height of the document you need in PDF Points.
|
177
187
|
#
|
178
188
|
# Usage:
|
179
189
|
#
|
@@ -181,13 +191,15 @@ module Prawn
|
|
181
191
|
# pdf = Prawn::Document.new
|
182
192
|
#
|
183
193
|
# # New document, A4 paper, landscaped
|
184
|
-
# pdf = Prawn::Document.new(:
|
194
|
+
# pdf = Prawn::Document.new(page_size: "A4", page_layout: :landscape)
|
185
195
|
#
|
186
196
|
# # New document, Custom size
|
187
|
-
# pdf = Prawn::Document.new(:
|
197
|
+
# pdf = Prawn::Document.new(page_size: [200, 300])
|
188
198
|
#
|
189
199
|
# # New document, with background
|
190
|
-
# pdf = Prawn::Document.new(
|
200
|
+
# pdf = Prawn::Document.new(
|
201
|
+
# background: "#{Prawn::DATADIR}/images/pigs.jpg"
|
202
|
+
# )
|
191
203
|
#
|
192
204
|
def initialize(options = {}, &block)
|
193
205
|
options = options.dup
|
@@ -199,21 +211,22 @@ module Prawn
|
|
199
211
|
|
200
212
|
self.class.extensions.reverse_each { |e| extend e }
|
201
213
|
self.state = PDF::Core::DocumentState.new(options)
|
202
|
-
|
214
|
+
state.populate_pages_from_store(self)
|
203
215
|
renderer.min_version(state.store.min_version) if state.store.min_version
|
204
216
|
|
205
217
|
renderer.min_version(1.6) if options[:print_scaling] == :none
|
206
218
|
|
207
219
|
@background = options[:background]
|
208
220
|
@background_scale = options[:background_scale] || 1
|
209
|
-
@font_size
|
221
|
+
@font_size = 12
|
210
222
|
|
211
|
-
@bounding_box
|
212
|
-
@margin_box
|
223
|
+
@bounding_box = nil
|
224
|
+
@margin_box = nil
|
213
225
|
|
214
226
|
@page_number = 0
|
215
227
|
|
216
|
-
@text_formatter = options.delete(:text_formatter) ||
|
228
|
+
@text_formatter = options.delete(:text_formatter) ||
|
229
|
+
Text::Formatted::Parser
|
217
230
|
|
218
231
|
options[:size] = options.delete(:page_size)
|
219
232
|
options[:layout] = options.delete(:page_layout)
|
@@ -240,24 +253,28 @@ module Prawn
|
|
240
253
|
# pdf.start_new_page(:margin => 100)
|
241
254
|
#
|
242
255
|
def start_new_page(options = {})
|
243
|
-
|
244
|
-
|
245
|
-
|
256
|
+
last_page = state.page
|
257
|
+
if last_page
|
258
|
+
last_page_size = last_page.size
|
259
|
+
last_page_layout = last_page.layout
|
246
260
|
last_page_margins = last_page.margins.dup
|
247
261
|
end
|
248
262
|
|
249
263
|
page_options = {
|
250
|
-
:
|
251
|
-
:
|
252
|
-
:
|
264
|
+
size: options[:size] || last_page_size,
|
265
|
+
layout: options[:layout] || last_page_layout,
|
266
|
+
margins: last_page_margins
|
253
267
|
}
|
254
268
|
if last_page
|
255
|
-
|
269
|
+
if last_page.graphic_state
|
270
|
+
new_graphic_state = last_page.graphic_state.dup
|
271
|
+
end
|
256
272
|
|
257
|
-
# erase the color space so that it gets reset on new page for fussy
|
258
|
-
|
273
|
+
# erase the color space so that it gets reset on new page for fussy
|
274
|
+
# pdf-readers
|
275
|
+
new_graphic_state&.color_space = {}
|
259
276
|
|
260
|
-
page_options
|
277
|
+
page_options[:graphic_state] = new_graphic_state
|
261
278
|
end
|
262
279
|
|
263
280
|
state.page = PDF::Core::Page.new(self, page_options)
|
@@ -277,7 +294,11 @@ module Prawn
|
|
277
294
|
state.insert_page(state.page, @page_number)
|
278
295
|
@page_number += 1
|
279
296
|
|
280
|
-
|
297
|
+
if @background
|
298
|
+
canvas do
|
299
|
+
image(@background, scale: @background_scale, at: bounds.top_left)
|
300
|
+
end
|
301
|
+
end
|
281
302
|
@y = @bounding_box.absolute_top
|
282
303
|
|
283
304
|
float do
|
@@ -286,6 +307,26 @@ module Prawn
|
|
286
307
|
end
|
287
308
|
end
|
288
309
|
|
310
|
+
# Remove page of the document by index
|
311
|
+
#
|
312
|
+
# pdf = Prawn::Document.new
|
313
|
+
# pdf.page_count #=> 1
|
314
|
+
# 3.times { pdf.start_new_page }
|
315
|
+
# pdf.page_count #=> 4
|
316
|
+
# pdf.delete_page(-1)
|
317
|
+
# pdf.page_count #=> 3
|
318
|
+
#
|
319
|
+
def delete_page(index)
|
320
|
+
return false if index.abs > (state.pages.count - 1)
|
321
|
+
|
322
|
+
state.pages.delete_at(index)
|
323
|
+
|
324
|
+
state.store.pages.data[:Kids].delete_at(index)
|
325
|
+
state.store.pages.data[:Count] -= 1
|
326
|
+
@page_number -= 1
|
327
|
+
true
|
328
|
+
end
|
329
|
+
|
289
330
|
# Returns the number of pages in the document
|
290
331
|
#
|
291
332
|
# pdf = Prawn::Document.new
|
@@ -302,9 +343,9 @@ module Prawn
|
|
302
343
|
#
|
303
344
|
# See Prawn::Document#number_pages for a sample usage of this capability.
|
304
345
|
#
|
305
|
-
def go_to_page(
|
306
|
-
@page_number =
|
307
|
-
state.page = state.pages[
|
346
|
+
def go_to_page(page_number)
|
347
|
+
@page_number = page_number
|
348
|
+
state.page = state.pages[page_number - 1]
|
308
349
|
generate_margin_box
|
309
350
|
@y = @bounding_box.absolute_top
|
310
351
|
end
|
@@ -351,13 +392,13 @@ module Prawn
|
|
351
392
|
# Renders the PDF document to string.
|
352
393
|
# Pass an open file descriptor to render to file.
|
353
394
|
#
|
354
|
-
def render(*
|
395
|
+
def render(*arguments, &block)
|
355
396
|
(1..page_count).each do |i|
|
356
397
|
go_to_page i
|
357
398
|
repeaters.each { |r| r.run(i) }
|
358
399
|
end
|
359
400
|
|
360
|
-
renderer.render(*
|
401
|
+
renderer.render(*arguments, &block)
|
361
402
|
end
|
362
403
|
|
363
404
|
# Renders the PDF document to file.
|
@@ -365,7 +406,7 @@ module Prawn
|
|
365
406
|
# pdf.render_file "foo.pdf"
|
366
407
|
#
|
367
408
|
def render_file(filename)
|
368
|
-
File.open(filename,
|
409
|
+
File.open(filename, 'wb') { |f| render(f) }
|
369
410
|
end
|
370
411
|
|
371
412
|
# The bounds method returns the current bounding box you are currently in,
|
@@ -374,14 +415,15 @@ module Prawn
|
|
374
415
|
# block, the box defined by that call will be returned instead of the
|
375
416
|
# document margin box.
|
376
417
|
#
|
377
|
-
# Another important point about bounding boxes is that all x and
|
378
|
-
# within a bounding box code block are relative to the bottom
|
379
|
-
# bounding box.
|
418
|
+
# Another important point about bounding boxes is that all x and
|
419
|
+
# y measurements within a bounding box code block are relative to the bottom
|
420
|
+
# left corner of the bounding box.
|
380
421
|
#
|
381
422
|
# For example:
|
382
423
|
#
|
383
424
|
# Prawn::Document.new do
|
384
|
-
# # In the default "margin box" of a Prawn document of 0.5in along each
|
425
|
+
# # In the default "margin box" of a Prawn document of 0.5in along each
|
426
|
+
# # edge
|
385
427
|
#
|
386
428
|
# # Draw a border around the page (the manual way)
|
387
429
|
# stroke do
|
@@ -408,8 +450,8 @@ module Prawn
|
|
408
450
|
|
409
451
|
# Sets Document#bounds to the BoundingBox provided. See above for a brief
|
410
452
|
# description of what a bounding box is. This function is useful if you
|
411
|
-
# really need to change the bounding box manually, but usually, just
|
412
|
-
# and exiting bounding box code blocks is good enough.
|
453
|
+
# really need to change the bounding box manually, but usually, just
|
454
|
+
# entering and exiting bounding box code blocks is good enough.
|
413
455
|
#
|
414
456
|
def bounds=(bounding_box)
|
415
457
|
@bounding_box = bounding_box
|
@@ -418,15 +460,15 @@ module Prawn
|
|
418
460
|
# Moves up the document by n points relative to the current position inside
|
419
461
|
# the current bounding box.
|
420
462
|
#
|
421
|
-
def move_up(
|
422
|
-
self.y +=
|
463
|
+
def move_up(amount)
|
464
|
+
self.y += amount
|
423
465
|
end
|
424
466
|
|
425
|
-
# Moves down the document by n points relative to the current position
|
426
|
-
# the current bounding box.
|
467
|
+
# Moves down the document by n points relative to the current position
|
468
|
+
# inside the current bounding box.
|
427
469
|
#
|
428
|
-
def move_down(
|
429
|
-
self.y -=
|
470
|
+
def move_down(amount)
|
471
|
+
self.y -= amount
|
430
472
|
end
|
431
473
|
|
432
474
|
# Moves down the document and then executes a block.
|
@@ -486,50 +528,55 @@ module Prawn
|
|
486
528
|
bounds.indent(left, right, &block)
|
487
529
|
end
|
488
530
|
|
489
|
-
# Places a text box on specified pages for page numbering. This should be
|
490
|
-
# towards the end of document creation, after all your content is
|
491
|
-
# place. In your template string, <page> refers to the current
|
492
|
-
# <total> refers to the total amount of pages in the document.
|
493
|
-
# occur at the end of your Prawn::Document.generate
|
494
|
-
# through existing pages after they are
|
531
|
+
# Places a text box on specified pages for page numbering. This should be
|
532
|
+
# 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
|
536
|
+
# block because the method iterates through existing pages after they are
|
537
|
+
# created.
|
495
538
|
#
|
496
539
|
# Parameters are:
|
497
540
|
#
|
498
541
|
# <tt>string</tt>:: Template string for page number wording.
|
499
542
|
# Should include '<page>' and, optionally, '<total>'.
|
500
543
|
# <tt>options</tt>:: A hash for page numbering and text box options.
|
501
|
-
# <tt>:page_filter</tt>:: A filter to specify which pages to place page
|
502
|
-
# Refer to the method 'page_match?'
|
544
|
+
# <tt>:page_filter</tt>:: A filter to specify which pages to place page
|
545
|
+
# numbers on. Refer to the method 'page_match?'
|
503
546
|
# <tt>:start_count_at</tt>:: The starting count to increment pages from.
|
504
|
-
# <tt>:total_pages</tt>:: If provided, will replace <total> with the
|
505
|
-
# Useful to override the total
|
506
|
-
# the start_count_at
|
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.
|
507
551
|
# <tt>:color</tt>:: Text fill color.
|
508
552
|
#
|
509
|
-
# Please refer to Prawn::Text::text_box for additional options
|
510
|
-
# formatting and placement.
|
511
|
-
#
|
512
|
-
# Example: Print page numbers on every page except for the first. Start counting from
|
513
|
-
# five.
|
553
|
+
# Please refer to Prawn::Text::text_box for additional options
|
554
|
+
# concerning text formatting and placement.
|
514
555
|
#
|
515
|
-
#
|
516
|
-
#
|
517
|
-
#
|
518
|
-
#
|
519
|
-
#
|
520
|
-
#
|
521
|
-
#
|
522
|
-
#
|
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
|
523
569
|
#
|
524
570
|
def number_pages(string, options = {})
|
525
571
|
opts = options.dup
|
526
572
|
start_count_at = opts.delete(:start_count_at).to_i
|
527
573
|
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
574
|
+
page_filter =
|
575
|
+
if opts.key?(:page_filter)
|
576
|
+
opts.delete(:page_filter)
|
577
|
+
else
|
578
|
+
:all
|
579
|
+
end
|
533
580
|
|
534
581
|
total_pages = opts.delete(:total_pages)
|
535
582
|
txtcolor = opts.delete(:color)
|
@@ -540,21 +587,24 @@ module Prawn
|
|
540
587
|
pseudopage = 0
|
541
588
|
(1..page_count).each do |p|
|
542
589
|
unless start_count
|
543
|
-
pseudopage =
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
590
|
+
pseudopage =
|
591
|
+
case start_count_at
|
592
|
+
when 0
|
593
|
+
1
|
594
|
+
else
|
595
|
+
start_count_at.to_i
|
596
|
+
end
|
549
597
|
end
|
550
598
|
if page_match?(page_filter, p)
|
551
599
|
go_to_page(p)
|
552
|
-
# have to use fill_color here otherwise text reverts back to default
|
600
|
+
# have to use fill_color here otherwise text reverts back to default
|
601
|
+
# fill color
|
553
602
|
fill_color txtcolor unless txtcolor.nil?
|
554
603
|
total_pages = total_pages.nil? ? page_count : total_pages
|
555
|
-
str = string.gsub(
|
604
|
+
str = string.gsub('<page>', pseudopage.to_s)
|
605
|
+
.gsub('<total>', total_pages.to_s)
|
556
606
|
text_box str, opts
|
557
|
-
start_count = true
|
607
|
+
start_count = true # increment page count as soon as first match found
|
558
608
|
end
|
559
609
|
pseudopage += 1 if start_count
|
560
610
|
end
|
@@ -572,21 +622,21 @@ module Prawn
|
|
572
622
|
# the current page or column.
|
573
623
|
#
|
574
624
|
# @private
|
575
|
-
def group(*
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
625
|
+
def group(*_arguments)
|
626
|
+
raise NotImplementedError,
|
627
|
+
'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'
|
581
631
|
end
|
582
632
|
|
583
633
|
# @private
|
584
634
|
def transaction
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
635
|
+
raise NotImplementedError,
|
636
|
+
'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'
|
590
640
|
end
|
591
641
|
|
592
642
|
# Provides a way to execute a block of code repeatedly based on a
|
@@ -617,20 +667,20 @@ module Prawn
|
|
617
667
|
# @private
|
618
668
|
|
619
669
|
def mask(*fields)
|
620
|
-
# Stores the current state of the named attributes, executes the block,
|
621
|
-
# then restores the original values after the block has executed.
|
670
|
+
# Stores the current state of the named attributes, executes the block,
|
671
|
+
# and then restores the original values after the block has executed.
|
622
672
|
# -- I will remove the nodoc if/when this feature is a little less hacky
|
623
673
|
stored = {}
|
624
|
-
fields.each { |f| stored[f] =
|
674
|
+
fields.each { |f| stored[f] = public_send(f) }
|
625
675
|
yield
|
626
|
-
fields.each { |f|
|
676
|
+
fields.each { |f| public_send("#{f}=", stored[f]) }
|
627
677
|
end
|
628
678
|
|
629
679
|
# @group Extension API
|
630
680
|
|
631
681
|
def initialize_first_page(options)
|
632
682
|
if options[:skip_page_creation]
|
633
|
-
start_new_page(options.merge(:
|
683
|
+
start_new_page(options.merge(orphan: true))
|
634
684
|
else
|
635
685
|
start_new_page(options)
|
636
686
|
end
|
@@ -648,11 +698,11 @@ module Prawn
|
|
648
698
|
|
649
699
|
private
|
650
700
|
|
651
|
-
# setting override_settings to true ensures that a new graphic state does
|
652
|
-
# previous settings.
|
701
|
+
# setting override_settings to true ensures that a new graphic state does
|
702
|
+
# not end up using previous settings.
|
653
703
|
def use_graphic_settings(override_settings = false)
|
654
|
-
set_fill_color if current_fill_color !=
|
655
|
-
set_stroke_color if current_stroke_color !=
|
704
|
+
set_fill_color if current_fill_color != '000000' || override_settings
|
705
|
+
set_stroke_color if current_stroke_color != '000000' || override_settings
|
656
706
|
write_line_width if line_width != 1 || override_settings
|
657
707
|
write_stroke_cap_style if cap_style != :butt || override_settings
|
658
708
|
write_stroke_join_style if join_style != :miter || override_settings
|
@@ -661,14 +711,16 @@ module Prawn
|
|
661
711
|
|
662
712
|
def generate_margin_box
|
663
713
|
old_margin_box = @margin_box
|
664
|
-
page
|
714
|
+
page = state.page
|
665
715
|
|
666
716
|
@margin_box = BoundingBox.new(
|
667
717
|
self,
|
668
|
-
nil,
|
669
|
-
[
|
670
|
-
:
|
671
|
-
|
718
|
+
nil, # margin box has no parent
|
719
|
+
[page.margins[:left], page.dimensions[-1] - page.margins[:top]],
|
720
|
+
width: page.dimensions[-2] -
|
721
|
+
(page.margins[:left] + page.margins[:right]),
|
722
|
+
height: page.dimensions[-1] -
|
723
|
+
(page.margins[:top] + page.margins[:bottom])
|
672
724
|
)
|
673
725
|
|
674
726
|
# This check maintains indentation settings across page breaks
|
@@ -679,25 +731,25 @@ module Prawn
|
|
679
731
|
|
680
732
|
# we must update bounding box if not flowing from the previous page
|
681
733
|
#
|
682
|
-
@bounding_box = @margin_box unless @bounding_box
|
734
|
+
@bounding_box = @margin_box unless @bounding_box&.parent
|
683
735
|
end
|
684
736
|
|
685
737
|
def apply_margin_options(options)
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
[
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
738
|
+
sides = %i[top right bottom left]
|
739
|
+
margin = Array(options[:margin])
|
740
|
+
|
741
|
+
# Treat :margin as CSS shorthand with 1-4 values.
|
742
|
+
positions = {
|
743
|
+
4 => [0, 1, 2, 3],
|
744
|
+
3 => [0, 1, 2, 1],
|
745
|
+
2 => [0, 1, 0, 1],
|
746
|
+
1 => [0, 0, 0, 0],
|
747
|
+
0 => []
|
748
|
+
}[margin.length]
|
749
|
+
|
750
|
+
sides.zip(positions).each do |side, pos|
|
751
|
+
new_margin = options[:"#{side}_margin"] || (margin[pos] if pos)
|
752
|
+
state.page.margins[side] = new_margin if new_margin
|
701
753
|
end
|
702
754
|
end
|
703
755
|
|