fillable-pdf 1.1.2 → 1.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6759e7cfdd5a0a97c20a9e98926b6c8e40d5a31b6543407e87cfd574806564d7
4
- data.tar.gz: 59cda9afff539dc1bfb3ef194e4cb6a83c5208d8287dbfc8ed35a15bd5788829
3
+ metadata.gz: 2cdd748940498c34c3e4f19f91f83cfc47fcf34dda1d10eb07e05f7aef9c7d57
4
+ data.tar.gz: a98954a86876c759716a8919a24f54c175ec97eb0eddd19bc2b9aaa844bdd6cb
5
5
  SHA512:
6
- metadata.gz: c6f97c5a48a92f0606bd6121d99b2ce35f1fe7fffe5983ef50332a66b397242f628d306e1cc29d604c15f223747c0e5c5c7229d55e6da7cf0a0712911060c4d7
7
- data.tar.gz: 5a8a6633a6f63b9a931ed3e7964bdb05a3ca0902583fe4e31ce1c3ee7af1c8973e39e2aebfee9a35afe2cec8fc1fef4cd8ea379dd26d5ecbaefef8b16502e177
6
+ metadata.gz: bb4104898a7feb6a16338aae323b3d1285f8fb5dd2458e48d5e936ca17ed27fc407289c68db0a466105bbe06fc1100cfd5a8cfa92873f6f6b731692ee385bfaf
7
+ data.tar.gz: 07430fe63ccbbec3e4c7c5191d6831b767320b87ed6ea0bd0542c11d41e10fe8c7883ce7d396fe7cc31f029d425fb87e055e3af01bd44358cf8d3b99010e17ca
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![JDK](https://img.shields.io/badge/JDK-8%20to%2026-007396?logo=openjdk&logoColor=white)](https://github.com/vkononov/fillable-pdf/blob/main/.github/workflows/test.yml)
7
7
  [![Test Matrix](https://img.shields.io/github/actions/workflow/status/vkononov/fillable-pdf/test.yml?branch=main&label=Test%20Matrix&logo=github)](https://github.com/vkononov/fillable-pdf/actions/workflows/test.yml)
8
8
  [![Lint](https://img.shields.io/github/actions/workflow/status/vkononov/fillable-pdf/lint.yml?branch=main&label=Lint&logo=github)](https://github.com/vkononov/fillable-pdf/actions/workflows/lint.yml)
9
- [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/license/MIT)
10
10
 
11
11
  FillablePDF is an extremely simple and lightweight utility that bridges iText and Ruby in order to fill out fillable PDF forms or extract field values from previously filled out PDF forms.
12
12
 
@@ -231,7 +231,7 @@ An instance of `FillablePDF` has the following methods at its disposal:
231
231
  pdf.set_field('first_name', 'Richard', generate_appearance: false)
232
232
  ```
233
233
 
234
- * `def set_fields(fields, generate_appearance: nil)`
234
+ * `set_fields(fields, generate_appearance: nil)`
235
235
  *Sets the values of multiple fields given a set of unique field names and values, with an optional `generate_appearance` directive.*
236
236
 
237
237
  ```ruby
@@ -319,7 +319,7 @@ An instance of `FillablePDF` has the following methods at its disposal:
319
319
  # result: document is saved in a given path with flattening
320
320
  ```
321
321
 
322
- **NOTE:** Saving the file automatically closes the input file, so you would need to reinitialize the `FillabePDF` class before making any more changes or saving another copy.
322
+ **NOTE:** Saving the file automatically closes the input file, so you would need to reinitialize the `FillablePDF` class before making any more changes or saving another copy.
323
323
 
324
324
  * `save_as!(file_path, flatten: false)`
325
325
  *Saves the filled out PDF document in a given path and flattens it if requested. Raises an error if the path matches the current file (use save() instead).*
@@ -454,15 +454,18 @@ Naturally, there are many downsides (in terms of efficiency, scalability, securi
454
454
 
455
455
  ## Example
456
456
 
457
- The following [example.rb](example/run.rb) with [input.pdf](example/input.pdf) is located in the [example](example) directory. It uses all of the methods that are described above and generates the output files [output.pdf](example/output.pdf) and [output.flat.pdf](example/output.flat.pdf).
457
+ The following [run.rb](example/run.rb) with [input.pdf](example/input.pdf) is located in the [example](example) directory. It uses most of the methods that are described above and generates the output files [output.pdf](example/output.pdf) and [output.flat.pdf](example/output.flat.pdf).
458
458
 
459
459
  ```ruby
460
460
  require_relative '../lib/fillable-pdf'
461
461
 
462
+ # Get the directory where this script is located
463
+ EXAMPLE_DIR = __dir__
464
+
462
465
  BASE64_PHOTO = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' # rubocop:disable Layout/LineLength
463
466
 
464
467
  # opening a fillable PDF
465
- pdf = FillablePDF.new('input.pdf')
468
+ pdf = FillablePDF.new(File.join(EXAMPLE_DIR, 'input.pdf'))
466
469
 
467
470
  # total number of fields
468
471
  if pdf.any_fields?
@@ -475,12 +478,15 @@ puts
475
478
 
476
479
  # setting form fields
477
480
  pdf.set_fields({first_name: 'Richard', last_name: 'Rahl'})
478
- pdf.set_fields({football: 'Yes', baseball: 'Yes', basketball: 'Yes', nascar: 'Yes', hockey: 'Yes', rugby: 'Yes'}, generate_appearance: false)
481
+ pdf.set_fields(
482
+ {football: 'Yes', baseball: 'Yes', basketball: 'Yes', nascar: 'Yes', hockey: 'Yes', rugby: 'Yes'},
483
+ generate_appearance: false
484
+ )
479
485
  pdf.set_field(:date, Time.now.strftime('%B %e, %Y'))
480
486
  pdf.set_field(:newsletter, 'Off') # uncheck the checkbox
481
487
  pdf.set_field(:language, 'dart') # select a radio button option
482
488
  pdf.set_image_base64(:photo, BASE64_PHOTO)
483
- pdf.set_image(:signature, 'signature.png')
489
+ pdf.set_image(:signature, File.join(EXAMPLE_DIR, 'signature.png'))
484
490
 
485
491
  # list of fields
486
492
  puts "Fields hash: #{pdf.fields}"
@@ -517,11 +523,11 @@ pdf.remove_field :marketing
517
523
  puts "Removed field 'marketing'"
518
524
 
519
525
  # saving the filled out PDF in another file
520
- pdf.save_as('output.pdf')
526
+ pdf.save_as(File.join(EXAMPLE_DIR, 'output.pdf'))
521
527
 
522
528
  # saving another copy of the filled out PDF in another file and making it non-editable
523
- pdf = FillablePDF.new('output.pdf')
524
- pdf.save_as 'output.flat.pdf', flatten: true
529
+ pdf = FillablePDF.new(File.join(EXAMPLE_DIR, 'output.pdf'))
530
+ pdf.save_as File.join(EXAMPLE_DIR, 'output.flat.pdf'), flatten: true
525
531
 
526
532
  # closing the document
527
533
  pdf.close
@@ -530,19 +536,19 @@ pdf.close
530
536
  The example above produces the following output and also generates the output file [output.pdf](example/output.pdf).
531
537
 
532
538
  ```text
533
- The form has a total of 16 fields.
539
+ The form has a total of 14 fields.
534
540
 
535
- Fields hash: {:last_name=>"Rahl", :first_name=>"Richard", :football=>"Yes", :baseball=>"Yes", :basketball=>"Yes", :hockey=>"Yes", :date=>"November 16, 2021", :newsletter=>"Off", :nascar=>"Yes", :language=>"dart", :"language.1"=>"dart", :"language.2"=>"dart", :"language.3"=>"dart", :"language.4"=>"dart", :signature=>"", :photo=>""}
541
+ Fields hash: {last_name: "Rahl", first_name: "Richard", football: "Yes", baseball: "Yes", basketball: "Yes", date: "August 12, 2026", newsletter: "Off", nascar: "Yes", language: "dart", signature: "", photo: "", rugby: "Yes", hockey: "Yes", marketing: ""}
536
542
 
537
- Keys: [:last_name, :first_name, :football, :baseball, :basketball, :hockey, :date, :newsletter, :nascar, :language, :"language.1", :"language.2", :"language.3", :"language.4", :signature, :photo]
543
+ Keys: [:last_name, :first_name, :football, :baseball, :basketball, :date, :newsletter, :nascar, :language, :signature, :photo, :rugby, :hockey, :marketing]
538
544
 
539
- Values: ["Rahl", "Richard", "Yes", "Yes", "Yes", "Yes", "November 16, 2021", "Off", "Yes", "dart", "dart", "dart", "dart", "dart", "", ""]
545
+ Values: ["Rahl", "Richard", "Yes", "Yes", "Yes", "August 12, 2026", "Off", "Yes", "dart", "", "", "Yes", "Yes", ""]
540
546
 
541
547
  Field 'football' is of type BUTTON
542
548
 
543
549
  Renamed field 'last_name' to 'surname'
544
550
 
545
- Removed field 'nascar'
551
+ Removed field 'marketing'
546
552
  ```
547
553
 
548
554
  ## Contributing
@@ -556,6 +562,6 @@ Removed field 'nascar'
556
562
 
557
563
  ## License
558
564
 
559
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
565
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/license/MIT).
560
566
 
561
- However, you must also adhere to the [iText License](https://github.com/itext/itext7) when using this gem in your project.
567
+ However, you must also adhere to the [iText License](https://github.com/itext/itext-java) when using this gem in your project.
@@ -1,3 +1,3 @@
1
1
  class FillablePDF
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  end
data/lib/fillable-pdf.rb CHANGED
@@ -128,7 +128,7 @@ class FillablePDF # rubocop:disable Metrics/ClassLength
128
128
  # @param [String|Symbol] key the field name
129
129
  # @param [String|Symbol] file_path the name of the image file or image path
130
130
  # @return [self] returns self for method chaining
131
- # @raise [FileOperationError] if the image file is not found
131
+ # @raise [FileOperationError] if the image file is not found or the field has no visible area
132
132
  # @raise [FieldNotFoundError] if the field does not exist
133
133
  #
134
134
  def set_image(key, file_path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@@ -136,13 +136,7 @@ class FillablePDF # rubocop:disable Metrics/ClassLength
136
136
  raise FileOperationError, "File <#{file_path}> is not found" unless File.exist?(file_path)
137
137
 
138
138
  begin
139
- field = pdf_field(key)
140
- widgets = field.getWidgets
141
- widget_dict = suppress_warnings { widgets.isEmpty ? field.getPdfObject : widgets.get(0).getPdfObject }
142
- orig_rect = widget_dict.getAsRectangle(ITEXT::PdfName.Rect)
143
-
144
- border_style = field.getWidgets.get(0).getBorderStyle
145
- border_width = border_style.nil? ? 0 : border_style.getWidth
139
+ widget_dict, orig_rect, border_width = image_placement(key)
146
140
 
147
141
  bounding_rectangle = ITEXT::Rectangle.new(
148
142
  orig_rect.getWidth - (border_width * 2),
@@ -165,6 +159,8 @@ class FillablePDF # rubocop:disable Metrics/ClassLength
165
159
  widget_dict.put(ITEXT::PdfName.AP, pdf_dict)
166
160
  pdf_dict.put(ITEXT::PdfName.N, pdf_form_x_object.getPdfObject)
167
161
  widget_dict.setModified
162
+ rescue FileOperationError
163
+ raise
168
164
  rescue StandardError => e
169
165
  raise FileOperationError, "Failed to set image for field '#{key}': #{e.message}"
170
166
  end
@@ -393,6 +389,20 @@ class FillablePDF # rubocop:disable Metrics/ClassLength
393
389
  field
394
390
  end
395
391
 
392
+ # Dictionary, rectangle and border width of the field's first widget, falling
393
+ # back to the field itself when it has no widget annotations.
394
+ def image_placement(key)
395
+ field = pdf_field(key)
396
+ widgets = field.getWidgets
397
+ widget = widgets.isEmpty ? nil : widgets.get(0)
398
+ widget_dict = suppress_warnings { (widget || field).getPdfObject }
399
+ rect = widget_dict.getAsRectangle(ITEXT::PdfName.Rect)
400
+ raise FileOperationError, "Field '#{key}' has no visible area to place an image in" if rect.nil?
401
+
402
+ border_style = widget&.getBorderStyle
403
+ [widget_dict, rect, border_style.nil? ? 0 : border_style.getWidth]
404
+ end
405
+
396
406
  def validate_input(key, value)
397
407
  validate_field_name(key)
398
408
  raise InvalidArgumentError, 'Field value cannot be nil' if value.nil?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fillable-pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vadim Kononov
@@ -51,9 +51,9 @@ dependencies:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '1.6'
54
- description: FillablePDF is an extremely simple and lightweight utility that bridges
55
- iText and Ruby in order to fill out fillable PDF forms or extract field values from
56
- previously filled out PDF forms.
54
+ description: Ruby wrapper for iText to work with AcroForm PDFs. Fill and read text
55
+ fields, checkboxes and radio buttons, add images to fields, rename or remove fields,
56
+ and flatten forms.
57
57
  email:
58
58
  - vadim@konoson.com
59
59
  executables: []
@@ -98,5 +98,5 @@ requirements:
98
98
  - JDK >= 8
99
99
  rubygems_version: 4.0.10
100
100
  specification_version: 4
101
- summary: Fill out or extract field values from simple fillable PDF forms using iText.
101
+ summary: Fill, read, flatten and edit PDF form fields in Ruby with the iText engine
102
102
  test_files: []