PyPDFForm 2.2.6__tar.gz → 2.3.0__tar.gz
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.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PKG-INFO +1 -10
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/__init__.py +1 -1
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/filler.py +8 -6
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/patterns.py +14 -18
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/template.py +5 -6
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/utils.py +5 -2
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/watermark.py +2 -2
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/base.py +2 -2
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/signature.py +2 -2
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/wrapper.py +7 -3
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm.egg-info/PKG-INFO +1 -10
- {pypdfform-2.2.6 → pypdfform-2.3.0}/README.md +0 -9
- {pypdfform-2.2.6 → pypdfform-2.3.0}/LICENSE +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/adapter.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/constants.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/coordinate.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/font.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/image.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/__init__.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/base.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/checkbox.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/dropdown.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/image.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/radio.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/signature.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/middleware/text.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/__init__.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/bedrock.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/checkbox.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/dropdown.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/image.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/radio.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm/widgets/text.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/pyproject.toml +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/setup.cfg +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_adobe_mode.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_create_widget.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_dropdown.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_dropdown_simple.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_fill_max_length_text_field_simple.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_fill_method.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_functional.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_functional_simple.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_paragraph.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_paragraph_simple.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_preview.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_signature.py +0 -0
- {pypdfform-2.2.6 → pypdfform-2.3.0}/tests/test_use_full_widget_name.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPDFForm
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: The Python library for PDF forms.
|
|
5
5
|
Author: Jinge Li
|
|
6
6
|
License-Expression: MIT
|
|
@@ -49,15 +49,6 @@ Dynamic: license-file
|
|
|
49
49
|
<a href="https://pypistats.org/packages/pypdfform"><img src="https://img.shields.io/pypi/dm/pypdfform?logo=pypi&logoColor=white&label=downloads&labelColor=black&color=blue&style=for-the-badge"></a>
|
|
50
50
|
</p>
|
|
51
51
|
|
|
52
|
-
## Important Announcements
|
|
53
|
-
|
|
54
|
-
Hello fellow Python developers! With the release of v2.0.0, there are some important changes I'm making to the library:
|
|
55
|
-
|
|
56
|
-
* Since I started developing the library, versioning releases has been quite unorthodox, and there isn't any convention I followed. Starting with v2.0.0, PyPDFForm will version releases following the conventions defined by [Semantic Versioning](https://semver.org/).
|
|
57
|
-
* PyPDFForm now renders PDF form widgets! Ever since its ancestral stage, the library has only been able to render the data you filled into a PDF form. Now if you fill a PDF form using `PdfWrapper`, the result will render the whole widget instead of just the value that got filled. If you would like to disable this behavior, please refer to the docs [here](https://chinapandaman.github.io/PyPDFForm/fill/#disable-rendering-widgets).
|
|
58
|
-
|
|
59
|
-
Happy hacking!
|
|
60
|
-
|
|
61
52
|
## Introduction
|
|
62
53
|
|
|
63
54
|
PyPDFForm is a free and open source pure-Python 3 library for PDF form processing. It contains the essential
|
|
@@ -38,7 +38,7 @@ from .patterns import (WIDGET_KEY_PATTERNS, simple_flatten_generic,
|
|
|
38
38
|
simple_flatten_radio, simple_update_checkbox_value,
|
|
39
39
|
simple_update_dropdown_value, simple_update_radio_value,
|
|
40
40
|
simple_update_text_value)
|
|
41
|
-
from .template import get_widgets_by_page
|
|
41
|
+
from .template import get_widget_full_key, get_widgets_by_page
|
|
42
42
|
from .utils import (checkbox_radio_to_draw, extract_widget_property,
|
|
43
43
|
stream_to_io)
|
|
44
44
|
from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
|
|
@@ -220,6 +220,7 @@ def get_drawn_stream(to_draw: dict, stream: bytes, action: str) -> bytes:
|
|
|
220
220
|
def fill(
|
|
221
221
|
template_stream: bytes,
|
|
222
222
|
widgets: Dict[str, WIDGET_TYPES],
|
|
223
|
+
use_full_widget_name: bool,
|
|
223
224
|
) -> bytes:
|
|
224
225
|
"""Fills a PDF form using watermark technique for complex rendering.
|
|
225
226
|
|
|
@@ -231,6 +232,7 @@ def fill(
|
|
|
231
232
|
Args:
|
|
232
233
|
template_stream: Input PDF form as bytes
|
|
233
234
|
widgets: Dictionary mapping field names to widget middleware
|
|
235
|
+
use_full_widget_name: If True, uses the full widget name as the key in the widgets dictionary
|
|
234
236
|
|
|
235
237
|
Returns:
|
|
236
238
|
bytes: Filled PDF form as bytes
|
|
@@ -253,6 +255,8 @@ def fill(
|
|
|
253
255
|
line_borders_to_draw[page] = []
|
|
254
256
|
for widget_dict in widget_dicts:
|
|
255
257
|
key = extract_widget_property(widget_dict, WIDGET_KEY_PATTERNS, None, str)
|
|
258
|
+
if use_full_widget_name:
|
|
259
|
+
key = get_widget_full_key(widget_dict)
|
|
256
260
|
text_needs_to_be_drawn = False
|
|
257
261
|
to_draw = x = y = None
|
|
258
262
|
|
|
@@ -329,10 +333,8 @@ def enable_adobe_mode(reader: PdfReader, writer: PdfWriter, adobe_mode: bool) ->
|
|
|
329
333
|
writer.root_object.update(
|
|
330
334
|
{NameObject(AcroForm): IndirectObject(len(writer.root_object), 0, writer)}
|
|
331
335
|
)
|
|
332
|
-
writer.root_object[AcroForm][NameObject(NeedAppearances)] = BooleanObject(
|
|
333
|
-
|
|
334
|
-
)
|
|
335
|
-
writer.root_object[AcroForm][NameObject(Fields)] = ArrayObject() # noqa
|
|
336
|
+
writer.root_object[AcroForm][NameObject(NeedAppearances)] = BooleanObject(True)
|
|
337
|
+
writer.root_object[AcroForm][NameObject(Fields)] = ArrayObject()
|
|
336
338
|
|
|
337
339
|
|
|
338
340
|
def simple_fill(
|
|
@@ -366,7 +368,7 @@ def simple_fill(
|
|
|
366
368
|
radio_button_tracker = {}
|
|
367
369
|
|
|
368
370
|
for page in out.pages:
|
|
369
|
-
for annot in page.get(Annots, []):
|
|
371
|
+
for annot in page.get(Annots, []):
|
|
370
372
|
annot = cast(DictionaryObject, annot.get_object())
|
|
371
373
|
key = extract_widget_property(
|
|
372
374
|
annot.get_object(), WIDGET_KEY_PATTERNS, None, str
|
|
@@ -149,7 +149,7 @@ def simple_update_checkbox_value(annot: DictionaryObject, check: bool = False) -
|
|
|
149
149
|
check: Whether the checkbox should be checked (True) or unchecked (False)
|
|
150
150
|
"""
|
|
151
151
|
|
|
152
|
-
for each in annot[AP][N]:
|
|
152
|
+
for each in annot[AP][N]:
|
|
153
153
|
if (check and str(each) != Off) or (not check and str(each) == Off):
|
|
154
154
|
annot[NameObject(AS)] = NameObject(each)
|
|
155
155
|
annot[NameObject(V)] = NameObject(each)
|
|
@@ -169,12 +169,12 @@ def simple_update_radio_value(annot: DictionaryObject) -> None:
|
|
|
169
169
|
"""
|
|
170
170
|
|
|
171
171
|
if Opt in annot[Parent]:
|
|
172
|
-
del annot[Parent][Opt]
|
|
172
|
+
del annot[Parent][Opt]
|
|
173
173
|
|
|
174
|
-
for each in annot[AP][N]:
|
|
174
|
+
for each in annot[AP][N]:
|
|
175
175
|
if str(each) != Off:
|
|
176
176
|
annot[NameObject(AS)] = NameObject(each)
|
|
177
|
-
annot[NameObject(Parent)][NameObject(V)] = NameObject(each)
|
|
177
|
+
annot[NameObject(Parent)][NameObject(V)] = NameObject(each)
|
|
178
178
|
break
|
|
179
179
|
|
|
180
180
|
|
|
@@ -191,7 +191,7 @@ def simple_update_dropdown_value(annot: DictionaryObject, widget: Dropdown) -> N
|
|
|
191
191
|
"""
|
|
192
192
|
|
|
193
193
|
if Parent in annot and T not in annot:
|
|
194
|
-
annot[NameObject(Parent)][NameObject(V)] = TextStringObject(
|
|
194
|
+
annot[NameObject(Parent)][NameObject(V)] = TextStringObject(
|
|
195
195
|
widget.choices[widget.value]
|
|
196
196
|
)
|
|
197
197
|
annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value])
|
|
@@ -214,9 +214,7 @@ def simple_update_text_value(annot: DictionaryObject, widget: Text) -> None:
|
|
|
214
214
|
"""
|
|
215
215
|
|
|
216
216
|
if Parent in annot and T not in annot:
|
|
217
|
-
annot[NameObject(Parent)][NameObject(V)] = TextStringObject(
|
|
218
|
-
widget.value
|
|
219
|
-
)
|
|
217
|
+
annot[NameObject(Parent)][NameObject(V)] = TextStringObject(widget.value)
|
|
220
218
|
annot[NameObject(AP)] = TextStringObject(widget.value)
|
|
221
219
|
else:
|
|
222
220
|
annot[NameObject(V)] = TextStringObject(widget.value)
|
|
@@ -234,8 +232,8 @@ def simple_flatten_radio(annot: DictionaryObject) -> None:
|
|
|
234
232
|
annot: PDF radio button annotation dictionary to flatten
|
|
235
233
|
"""
|
|
236
234
|
|
|
237
|
-
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
238
|
-
int(annot[NameObject(Parent)].get(NameObject(Ff), 0)) | READ_ONLY
|
|
235
|
+
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
236
|
+
int(annot[NameObject(Parent)].get(NameObject(Ff), 0)) | READ_ONLY
|
|
239
237
|
)
|
|
240
238
|
|
|
241
239
|
|
|
@@ -251,12 +249,12 @@ def simple_flatten_generic(annot: DictionaryObject) -> None:
|
|
|
251
249
|
"""
|
|
252
250
|
|
|
253
251
|
if Parent in annot and Ff not in annot:
|
|
254
|
-
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
255
|
-
int(annot.get(NameObject(Ff), 0)) | READ_ONLY
|
|
252
|
+
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
253
|
+
int(annot.get(NameObject(Ff), 0)) | READ_ONLY
|
|
256
254
|
)
|
|
257
255
|
else:
|
|
258
256
|
annot[NameObject(Ff)] = NumberObject(
|
|
259
|
-
int(annot.get(NameObject(Ff), 0)) | READ_ONLY
|
|
257
|
+
int(annot.get(NameObject(Ff), 0)) | READ_ONLY
|
|
260
258
|
)
|
|
261
259
|
|
|
262
260
|
|
|
@@ -272,9 +270,9 @@ def update_annotation_name(annot: DictionaryObject, val: str) -> None:
|
|
|
272
270
|
"""
|
|
273
271
|
|
|
274
272
|
if Parent in annot and T not in annot:
|
|
275
|
-
annot[NameObject(Parent)][NameObject(T)] = TextStringObject(val)
|
|
273
|
+
annot[NameObject(Parent)][NameObject(T)] = TextStringObject(val)
|
|
276
274
|
else:
|
|
277
|
-
annot[NameObject(T)] = TextStringObject(val)
|
|
275
|
+
annot[NameObject(T)] = TextStringObject(val)
|
|
278
276
|
|
|
279
277
|
|
|
280
278
|
def update_created_text_field_alignment(annot: DictionaryObject, val: int) -> None:
|
|
@@ -303,9 +301,7 @@ def update_created_text_field_multiline(annot: DictionaryObject, val: bool) -> N
|
|
|
303
301
|
"""
|
|
304
302
|
|
|
305
303
|
if val:
|
|
306
|
-
annot[NameObject(Ff)] = NumberObject(
|
|
307
|
-
int(annot[NameObject(Ff)]) | MULTILINE # noqa
|
|
308
|
-
)
|
|
304
|
+
annot[NameObject(Ff)] = NumberObject(int(annot[NameObject(Ff)]) | MULTILINE)
|
|
309
305
|
|
|
310
306
|
|
|
311
307
|
NON_ACRO_FORM_PARAM_TO_FUNC = {
|
|
@@ -246,15 +246,14 @@ def get_widgets_by_page(pdf: bytes) -> Dict[int, List[dict]]:
|
|
|
246
246
|
return result
|
|
247
247
|
|
|
248
248
|
|
|
249
|
-
def get_widget_full_key(widget: dict) ->
|
|
249
|
+
def get_widget_full_key(widget: dict) -> str:
|
|
250
250
|
"""Constructs a widget's full hierarchical key including parent names.
|
|
251
251
|
|
|
252
252
|
Args:
|
|
253
253
|
widget: PDF widget dictionary
|
|
254
254
|
|
|
255
255
|
Returns:
|
|
256
|
-
|
|
257
|
-
otherwise None
|
|
256
|
+
str: Full key in format "parent.child" if parent exists, otherwise the widget's key
|
|
258
257
|
"""
|
|
259
258
|
|
|
260
259
|
key = extract_widget_property(widget, WIDGET_KEY_PATTERNS, None, str)
|
|
@@ -264,9 +263,9 @@ def get_widget_full_key(widget: dict) -> Union[str, None]:
|
|
|
264
263
|
and T in widget[Parent].get_object()
|
|
265
264
|
and widget[Parent].get_object()[T] != key
|
|
266
265
|
):
|
|
267
|
-
|
|
266
|
+
key = f"{get_widget_full_key(widget[Parent].get_object())}.{key}"
|
|
268
267
|
|
|
269
|
-
return
|
|
268
|
+
return key
|
|
270
269
|
|
|
271
270
|
|
|
272
271
|
def construct_widget(widget: dict, key: str) -> Union[WIDGET_TYPES, None]:
|
|
@@ -570,7 +569,7 @@ def update_widget_keys(
|
|
|
570
569
|
new_key = new_keys[i]
|
|
571
570
|
tracker = -1
|
|
572
571
|
for page in out.pages:
|
|
573
|
-
for annot in page.get(Annots, []):
|
|
572
|
+
for annot in page.get(Annots, []):
|
|
574
573
|
annot = cast(DictionaryObject, annot.get_object())
|
|
575
574
|
key = extract_widget_property(
|
|
576
575
|
annot.get_object(), WIDGET_KEY_PATTERNS, None, str
|
|
@@ -104,10 +104,13 @@ def checkbox_radio_to_draw(
|
|
|
104
104
|
return new_widget
|
|
105
105
|
|
|
106
106
|
|
|
107
|
-
def preview_widget_to_draw(
|
|
107
|
+
def preview_widget_to_draw(
|
|
108
|
+
widget_name: str, widget: WIDGET_TYPES, with_preview_text: bool
|
|
109
|
+
) -> Text:
|
|
108
110
|
"""Creates preview version of a widget showing field name/location.
|
|
109
111
|
|
|
110
112
|
Args:
|
|
113
|
+
widget_name: Name of the widget to generate preview for
|
|
111
114
|
widget: Widget to generate preview for
|
|
112
115
|
with_preview_text: Whether to include field name in preview
|
|
113
116
|
|
|
@@ -117,7 +120,7 @@ def preview_widget_to_draw(widget: WIDGET_TYPES, with_preview_text: bool) -> Tex
|
|
|
117
120
|
|
|
118
121
|
new_widget = Text(
|
|
119
122
|
name=widget.name,
|
|
120
|
-
value="{" + f" {
|
|
123
|
+
value="{" + f" {widget_name} " + "}" if with_preview_text else None,
|
|
121
124
|
)
|
|
122
125
|
new_widget.font = DEFAULT_FONT
|
|
123
126
|
new_widget.font_size = DEFAULT_FONT_SIZE
|
|
@@ -380,7 +380,7 @@ def copy_watermark_widgets(
|
|
|
380
380
|
watermark_file = PdfReader(stream_to_io(watermark))
|
|
381
381
|
for j, page in enumerate(watermark_file.pages):
|
|
382
382
|
widgets_to_copy_pdf[j] = []
|
|
383
|
-
for annot in page.get(Annots, []):
|
|
383
|
+
for annot in page.get(Annots, []):
|
|
384
384
|
key = extract_widget_property(
|
|
385
385
|
annot.get_object(), WIDGET_KEY_PATTERNS, None, str
|
|
386
386
|
)
|
|
@@ -393,7 +393,7 @@ def copy_watermark_widgets(
|
|
|
393
393
|
for i, page in enumerate(out.pages):
|
|
394
394
|
if i in widgets_to_copy:
|
|
395
395
|
page[NameObject(Annots)] = (
|
|
396
|
-
(page[NameObject(Annots)] + ArrayObject(widgets_to_copy[i]))
|
|
396
|
+
(page[NameObject(Annots)] + ArrayObject(widgets_to_copy[i]))
|
|
397
397
|
if Annots in page
|
|
398
398
|
else ArrayObject(widgets_to_copy[i])
|
|
399
399
|
)
|
|
@@ -83,7 +83,7 @@ class Widget:
|
|
|
83
83
|
)
|
|
84
84
|
self.acro_form_params[param] = value
|
|
85
85
|
elif user_input in self.NONE_DEFAULTS:
|
|
86
|
-
self.acro_form_params[param] = None
|
|
86
|
+
self.acro_form_params[param] = None
|
|
87
87
|
|
|
88
88
|
for each in self.ALLOWED_NON_ACRO_FORM_PARAMS:
|
|
89
89
|
if each in kwargs:
|
|
@@ -154,7 +154,7 @@ def handle_non_acro_form_params(pdf: bytes, key: str, params: list) -> bytes:
|
|
|
154
154
|
out.append(pdf_file)
|
|
155
155
|
|
|
156
156
|
for page in out.pages:
|
|
157
|
-
for annot in page.get(Annots, []):
|
|
157
|
+
for annot in page.get(Annots, []):
|
|
158
158
|
annot = cast(DictionaryObject, annot.get_object())
|
|
159
159
|
_key = extract_widget_property(
|
|
160
160
|
annot.get_object(), WIDGET_KEY_PATTERNS, None, str
|
|
@@ -101,12 +101,12 @@ class SignatureWidget:
|
|
|
101
101
|
|
|
102
102
|
input_pdf = PdfReader(stream_to_io(stream))
|
|
103
103
|
page_count = len(input_pdf.pages)
|
|
104
|
-
pdf = PdfReader(stream_to_io(BEDROCK_PDF))
|
|
104
|
+
pdf = PdfReader(stream_to_io(BEDROCK_PDF))
|
|
105
105
|
out = PdfWriter()
|
|
106
106
|
out.append(pdf)
|
|
107
107
|
|
|
108
108
|
for page in out.pages:
|
|
109
|
-
for annot in page.get(Annots, []):
|
|
109
|
+
for annot in page.get(Annots, []):
|
|
110
110
|
key = extract_widget_property(
|
|
111
111
|
annot.get_object(), WIDGET_KEY_PATTERNS, None, str
|
|
112
112
|
)
|
|
@@ -362,9 +362,10 @@ class PdfWrapper(FormWrapper):
|
|
|
362
362
|
fill(
|
|
363
363
|
self.stream,
|
|
364
364
|
{
|
|
365
|
-
key: preview_widget_to_draw(value, True)
|
|
365
|
+
key: preview_widget_to_draw(key, value, True)
|
|
366
366
|
for key, value in self.widgets.items()
|
|
367
367
|
},
|
|
368
|
+
getattr(self, "use_full_widget_name"),
|
|
368
369
|
)
|
|
369
370
|
)
|
|
370
371
|
|
|
@@ -391,9 +392,10 @@ class PdfWrapper(FormWrapper):
|
|
|
391
392
|
fill(
|
|
392
393
|
self.stream,
|
|
393
394
|
{
|
|
394
|
-
key: preview_widget_to_draw(value, False)
|
|
395
|
+
key: preview_widget_to_draw(key, value, False)
|
|
395
396
|
for key, value in self.widgets.items()
|
|
396
397
|
},
|
|
398
|
+
getattr(self, "use_full_widget_name"),
|
|
397
399
|
)
|
|
398
400
|
),
|
|
399
401
|
color,
|
|
@@ -434,7 +436,9 @@ class PdfWrapper(FormWrapper):
|
|
|
434
436
|
if self.read():
|
|
435
437
|
self.widgets = set_character_x_paddings(self.stream, self.widgets)
|
|
436
438
|
|
|
437
|
-
self.stream = remove_all_widgets(
|
|
439
|
+
self.stream = remove_all_widgets(
|
|
440
|
+
fill(self.stream, self.widgets, getattr(self, "use_full_widget_name"))
|
|
441
|
+
)
|
|
438
442
|
|
|
439
443
|
return self
|
|
440
444
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPDFForm
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: The Python library for PDF forms.
|
|
5
5
|
Author: Jinge Li
|
|
6
6
|
License-Expression: MIT
|
|
@@ -49,15 +49,6 @@ Dynamic: license-file
|
|
|
49
49
|
<a href="https://pypistats.org/packages/pypdfform"><img src="https://img.shields.io/pypi/dm/pypdfform?logo=pypi&logoColor=white&label=downloads&labelColor=black&color=blue&style=for-the-badge"></a>
|
|
50
50
|
</p>
|
|
51
51
|
|
|
52
|
-
## Important Announcements
|
|
53
|
-
|
|
54
|
-
Hello fellow Python developers! With the release of v2.0.0, there are some important changes I'm making to the library:
|
|
55
|
-
|
|
56
|
-
* Since I started developing the library, versioning releases has been quite unorthodox, and there isn't any convention I followed. Starting with v2.0.0, PyPDFForm will version releases following the conventions defined by [Semantic Versioning](https://semver.org/).
|
|
57
|
-
* PyPDFForm now renders PDF form widgets! Ever since its ancestral stage, the library has only been able to render the data you filled into a PDF form. Now if you fill a PDF form using `PdfWrapper`, the result will render the whole widget instead of just the value that got filled. If you would like to disable this behavior, please refer to the docs [here](https://chinapandaman.github.io/PyPDFForm/fill/#disable-rendering-widgets).
|
|
58
|
-
|
|
59
|
-
Happy hacking!
|
|
60
|
-
|
|
61
52
|
## Introduction
|
|
62
53
|
|
|
63
54
|
PyPDFForm is a free and open source pure-Python 3 library for PDF form processing. It contains the essential
|
|
@@ -8,15 +8,6 @@
|
|
|
8
8
|
<a href="https://pypistats.org/packages/pypdfform"><img src="https://img.shields.io/pypi/dm/pypdfform?logo=pypi&logoColor=white&label=downloads&labelColor=black&color=blue&style=for-the-badge"></a>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
-
## Important Announcements
|
|
12
|
-
|
|
13
|
-
Hello fellow Python developers! With the release of v2.0.0, there are some important changes I'm making to the library:
|
|
14
|
-
|
|
15
|
-
* Since I started developing the library, versioning releases has been quite unorthodox, and there isn't any convention I followed. Starting with v2.0.0, PyPDFForm will version releases following the conventions defined by [Semantic Versioning](https://semver.org/).
|
|
16
|
-
* PyPDFForm now renders PDF form widgets! Ever since its ancestral stage, the library has only been able to render the data you filled into a PDF form. Now if you fill a PDF form using `PdfWrapper`, the result will render the whole widget instead of just the value that got filled. If you would like to disable this behavior, please refer to the docs [here](https://chinapandaman.github.io/PyPDFForm/fill/#disable-rendering-widgets).
|
|
17
|
-
|
|
18
|
-
Happy hacking!
|
|
19
|
-
|
|
20
11
|
## Introduction
|
|
21
12
|
|
|
22
13
|
PyPDFForm is a free and open source pure-Python 3 library for PDF form processing. It contains the essential
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|