acro_that 0.1.8 → 1.0.1
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 +4 -4
- data/CHANGELOG.md +1 -4
- data/Gemfile.lock +1 -1
- data/README.md +86 -3
- data/docs/clear_fields.md +10 -10
- data/lib/acro_that/actions/add_field.rb +33 -448
- data/lib/acro_that/actions/update_field.rb +168 -38
- data/lib/acro_that/dict_scan.rb +26 -0
- data/lib/acro_that/document.rb +33 -12
- data/lib/acro_that/fields/base.rb +371 -0
- data/lib/acro_that/fields/checkbox.rb +164 -0
- data/lib/acro_that/fields/radio.rb +220 -0
- data/lib/acro_that/{actions/add_signature_appearance.rb → fields/signature.rb} +64 -93
- data/lib/acro_that/fields/text.rb +31 -0
- data/lib/acro_that/version.rb +1 -1
- data/lib/acro_that.rb +10 -2
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 35e82f82af4a5ad469ce89111633daea2b86ca0f9a965282824c03bd5f9b8af6
|
|
4
|
+
data.tar.gz: 47e8c25c2f8d1a9243ed9c6e5c85ba6f65aa1cc52b8abe62c3fdaed3a72f8361
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d20594b2b72776e4eea071d87036e2151cfcbb5a36f09d1b11ecd4d055168a613ba1d8fcd308b1748706b30c4ea6cc84742e2f895a21f594ef6c9a79351f5cc1
|
|
7
|
+
data.tar.gz: fb36a88b91eced4f62b027f920e5233e626f4d469087fe7c46419091020324b9d92d0f5a70d55479064c93bd787513950b2ce84bbcb185834a706c7f83fa9555
|
data/CHANGELOG.md
CHANGED
|
@@ -8,10 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
## [0.1.8] - 2025-11-04
|
|
9
9
|
|
|
10
10
|
### Fixed
|
|
11
|
-
- Fixed PDF parsing error when PDFs are wrapped in multipart form data. PDFs uploaded via web forms (with boundary markers like `------WebKitFormBoundary...`) are now automatically extracted before processing, ensuring correct offset calculations.
|
|
12
|
-
- Fixed xref stream parsing to properly validate objects are actually xref streams before attempting to parse them. Added fallback logic to find classic xref tables nearby when xref stream parsing fails.
|
|
13
|
-
- Fixed annotation removal to preserve non-widget annotations (such as highlighting, comments, etc.) when clearing fields. Only widget annotations associated with form fields are now removed.
|
|
14
|
-
- Improved PDF trailer Size calculation to handle object number gaps correctly.
|
|
11
|
+
- Fixed PDF parsing error when PDFs are wrapped in multipart form data. PDFs uploaded via web forms (with boundary markers like `------WebKitFormBoundary...`) are now automatically extracted before processing, ensuring correct offset calculations for xref tables and streams.
|
|
15
12
|
|
|
16
13
|
## [0.1.5] - 2025-11-01
|
|
17
14
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -175,6 +175,84 @@ doc.write("form_with_signature.pdf")
|
|
|
175
175
|
|
|
176
176
|
**Note**: PNG image processing requires the `chunky_png` gem, which is included as a dependency. JPEG images can be processed without any additional dependencies.
|
|
177
177
|
|
|
178
|
+
#### Radio Buttons
|
|
179
|
+
|
|
180
|
+
Radio buttons allow users to select a single option from a group of mutually exclusive choices. Radio buttons in AcroThat are created using the `:radio` type and require a `group_id` to group related buttons together.
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
doc = AcroThat::Document.new("form.pdf")
|
|
184
|
+
|
|
185
|
+
# Create a radio button group with multiple options
|
|
186
|
+
# All buttons in the same group must share the same group_id
|
|
187
|
+
|
|
188
|
+
# First radio button in the group (creates the parent field)
|
|
189
|
+
doc.add_field("Option1",
|
|
190
|
+
type: :radio,
|
|
191
|
+
group_id: "my_radio_group",
|
|
192
|
+
value: "option1", # Export value for this button
|
|
193
|
+
x: 100,
|
|
194
|
+
y: 500,
|
|
195
|
+
width: 20,
|
|
196
|
+
height: 20,
|
|
197
|
+
page: 1,
|
|
198
|
+
selected: true # This button will be selected by default
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# Second radio button in the same group
|
|
202
|
+
doc.add_field("Option2",
|
|
203
|
+
type: :radio,
|
|
204
|
+
group_id: "my_radio_group", # Same group_id as above
|
|
205
|
+
value: "option2",
|
|
206
|
+
x: 100,
|
|
207
|
+
y: 470,
|
|
208
|
+
width: 20,
|
|
209
|
+
height: 20,
|
|
210
|
+
page: 1
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# Third radio button in the same group
|
|
214
|
+
doc.add_field("Option3",
|
|
215
|
+
type: :radio,
|
|
216
|
+
group_id: "my_radio_group", # Same group_id
|
|
217
|
+
value: "option3",
|
|
218
|
+
x: 100,
|
|
219
|
+
y: 440,
|
|
220
|
+
width: 20,
|
|
221
|
+
height: 20,
|
|
222
|
+
page: 1
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Write the PDF with radio buttons
|
|
226
|
+
doc.write("form_with_radio.pdf")
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Key Points:**
|
|
230
|
+
- **`group_id`**: Required. All radio buttons that should be mutually exclusive must share the same `group_id`. This can be any string or identifier.
|
|
231
|
+
- **`type: :radio`**: Required. Specifies that this is a radio button field.
|
|
232
|
+
- **`value`**: The export value for this specific button. This is what gets returned when the button is selected. If not provided, a unique value will be generated automatically.
|
|
233
|
+
- **`selected`**: Optional boolean (`true` or `false`, or string `"true"`). If set to `true`, this button will be selected by default. Only one button in a group should have `selected: true`. If not specified, the button defaults to unselected.
|
|
234
|
+
- **Positioning**: Each radio button needs its own `x`, `y`, `width`, `height`, and `page` values to position it on the form.
|
|
235
|
+
|
|
236
|
+
**Example with multiple groups:**
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
doc = AcroThat::Document.new("form.pdf")
|
|
240
|
+
|
|
241
|
+
# First radio button group (e.g., "Gender")
|
|
242
|
+
doc.add_field("Male", type: :radio, group_id: "gender", value: "male", x: 100, y: 500, width: 20, height: 20, page: 1, selected: true)
|
|
243
|
+
doc.add_field("Female", type: :radio, group_id: "gender", value: "female", x: 100, y: 470, width: 20, height: 20, page: 1)
|
|
244
|
+
doc.add_field("Other", type: :radio, group_id: "gender", value: "other", x: 100, y: 440, width: 20, height: 20, page: 1)
|
|
245
|
+
|
|
246
|
+
# Second radio button group (e.g., "Age Range")
|
|
247
|
+
doc.add_field("18-25", type: :radio, group_id: "age", value: "18-25", x: 200, y: 500, width: 20, height: 20, page: 1)
|
|
248
|
+
doc.add_field("26-35", type: :radio, group_id: "age", value: "26-35", x: 200, y: 470, width: 20, height: 20, page: 1, selected: true)
|
|
249
|
+
doc.add_field("36+", type: :radio, group_id: "age", value: "36+", x: 200, y: 440, width: 20, height: 20, page: 1)
|
|
250
|
+
|
|
251
|
+
doc.write("form_with_multiple_groups.pdf")
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Note:** Radio buttons are automatically configured with the correct PDF flags to enable mutual exclusivity within a group. When a user selects one radio button, all others in the same group are automatically deselected.
|
|
255
|
+
|
|
178
256
|
#### Flattening PDFs
|
|
179
257
|
|
|
180
258
|
```ruby
|
|
@@ -269,8 +347,10 @@ Adds a new form field to the document. Options include:
|
|
|
269
347
|
- `height`: Field height (Integer, default: 20)
|
|
270
348
|
- `page`: Page number to add the field to (Integer, default: 1)
|
|
271
349
|
- `type`: Field type (Symbol or String, default: `"/Tx"`). Options:
|
|
272
|
-
- Symbol keys: `:text`, `:button`, `:choice`, `:signature`
|
|
350
|
+
- Symbol keys: `:text`, `:button`, `:choice`, `:signature`, `:radio`
|
|
273
351
|
- PDF type strings: `"/Tx"`, `"/Btn"`, `"/Ch"`, `"/Sig"`
|
|
352
|
+
- `group_id`: Required for radio buttons. String or identifier to group radio buttons together. All radio buttons in the same group must share the same `group_id`.
|
|
353
|
+
- `selected`: Optional for radio buttons. Boolean (`true` or `false`, or string `"true"`). If set to `true`, this radio button will be selected by default.
|
|
274
354
|
|
|
275
355
|
Returns a `Field` object if successful.
|
|
276
356
|
|
|
@@ -280,6 +360,9 @@ field = doc.add_field("NewField", value: "Value", x: 100, y: 500, width: 200, he
|
|
|
280
360
|
|
|
281
361
|
# Using PDF type strings
|
|
282
362
|
field = doc.add_field("ButtonField", type: "/Btn", x: 100, y: 500, width: 20, height: 20, page: 1)
|
|
363
|
+
|
|
364
|
+
# Radio button example
|
|
365
|
+
field = doc.add_field("Option1", type: :radio, group_id: "my_group", value: "option1", x: 100, y: 500, width: 20, height: 20, page: 1, selected: true)
|
|
283
366
|
```
|
|
284
367
|
|
|
285
368
|
#### `#update_field(name, new_value, new_name: nil)`
|
|
@@ -351,8 +434,8 @@ doc.clear!(remove_pattern: /^text-/)
|
|
|
351
434
|
# Keep only specific fields
|
|
352
435
|
doc.clear!(keep_fields: ["Name", "Email"])
|
|
353
436
|
|
|
354
|
-
# Use block to filter fields
|
|
355
|
-
doc.clear! { |
|
|
437
|
+
# Use block to filter fields (return true to remove)
|
|
438
|
+
doc.clear! { |field| field.name.match?(/^[a-f0-9-]{30,}/) }
|
|
356
439
|
```
|
|
357
440
|
|
|
358
441
|
**Note:** This completely rewrites the PDF (like `flatten`), so it's more efficient than using `remove_field` multiple times. See [Clearing Fields Documentation](docs/cleaning_fields.md) for detailed information.
|
data/docs/clear_fields.md
CHANGED
|
@@ -75,11 +75,11 @@ doc.clear!(remove_fields: ["OldField1", "OldField2", "GeneratedField3"])
|
|
|
75
75
|
### Complex Selection with Block
|
|
76
76
|
|
|
77
77
|
```ruby
|
|
78
|
-
# Remove
|
|
79
|
-
doc.clear! do |
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
# Remove fields matching certain criteria
|
|
79
|
+
doc.clear! do |field|
|
|
80
|
+
# Remove fields that look generated
|
|
81
|
+
field.name.start_with?("text-") ||
|
|
82
|
+
field.name.match?(/^[a-f0-9]{20,}/)
|
|
83
83
|
end
|
|
84
84
|
```
|
|
85
85
|
|
|
@@ -179,11 +179,11 @@ require 'acro_that'
|
|
|
179
179
|
doc = AcroThat::Document.new("messy_form.pdf")
|
|
180
180
|
|
|
181
181
|
# Remove all generated/UUID-like fields
|
|
182
|
-
doc.clear! { |
|
|
183
|
-
#
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
182
|
+
doc.clear! { |field|
|
|
183
|
+
# Remove fields that look generated or temporary
|
|
184
|
+
field.name.match?(/^[a-f0-9-]{30,}/) || # UUID-like
|
|
185
|
+
field.name.start_with?("temp_") || # Temporary
|
|
186
|
+
field.name.empty? # Empty name
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
# Add new fields
|