combine_pdf 0.2.17 → 0.2.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +13 -1
- data/lib/combine_pdf/parser.rb +3 -1
- data/lib/combine_pdf/pdf_protected.rb +16 -5
- data/lib/combine_pdf/pdf_public.rb +15 -5
- data/lib/combine_pdf/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cc0e0274387687766335c52fd25e98da231ded0
|
4
|
+
data.tar.gz: 809c6a2af4d5eb56857845560205ad222d2cfc88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 072bec00cf0b1837017145b528c9e3b290f3dcb958385d1e7efd9d8b879c78724b775e568cbdc5bee93ca72c2f955ff0dd343e290530db9e689123f1e2b260a4
|
7
|
+
data.tar.gz: 21a123a20265221396df344ade4587b80ecba769b770ec5015e1960f2f899abbf3fac2d7df4c9fed59a2bbc7fa4a7bc8d8aa439559e4ff96562f983929f43151
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
Change log v.0.2.20
|
6
|
+
|
7
|
+
**Fix**: fix for issue #56, discovered by @LeptonHeavy, regarding errors caused by the new PDF form support feature.
|
8
|
+
|
9
|
+
***
|
10
|
+
|
11
|
+
Change log v.0.2.19 (yanked)
|
12
|
+
|
13
|
+
**Partial fix**: unconfirmed fix for issue #56, discovered by @LeptonHeavy, regarding errors caused by the new PDF form support feature.
|
14
|
+
|
15
|
+
***
|
16
|
+
|
17
|
+
Change log v.0.2.18 (yanked)
|
18
|
+
|
19
|
+
**Feature**: added minor (read: initial and incomplete) PDF forms support, in an attempt to preserve form data when combining PDF files.
|
20
|
+
|
21
|
+
***
|
22
|
+
|
5
23
|
Change log v.0.2.17
|
6
24
|
|
7
25
|
**Feature**: added the `page#crop` method to easily crop a PDF file in accordance with the GWG industry association recommendations (updating the `MediaBox` property rather then the `CropBox`). Credit to @wingleungchoi for this feature.
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
CombinePDF is a nifty model, written in pure Ruby, to parse PDF files and combine (merge) them with other PDF files, watermark them or stamp them (all using the PDF file format and pure Ruby code).
|
6
6
|
|
7
|
-
|
7
|
+
## Install
|
8
8
|
|
9
9
|
Install with ruby gems:
|
10
10
|
|
@@ -12,6 +12,18 @@ Install with ruby gems:
|
|
12
12
|
gem install combine_pdf
|
13
13
|
```
|
14
14
|
|
15
|
+
## Known Limitations
|
16
|
+
|
17
|
+
CombinePDF is written natively in Ruby and should (presumably) work on all Ruby platforms that follow Ruby 2.0 compatibility.
|
18
|
+
|
19
|
+
However, PDF files are quite complex creatures and no guaranty is provided.
|
20
|
+
|
21
|
+
For example, PDF Forms are known to have issues and form data might be lost when attempting to combine PDFs with filled form data (also, forms are global objects, not page specific, so one should combine the whole of the PDF for any data to have any chance of being preserved).
|
22
|
+
|
23
|
+
The same applies to PDF links and the table of contents, which all have global attributes and could be corrupted or lost when combining PDF data.
|
24
|
+
|
25
|
+
If this library causes loss of data or burns down your house, I'm not to blame - as pointed to by the MIT license. That being said, I'm using the library happily after testing against different solutions.
|
26
|
+
|
15
27
|
## Combine/Merge PDF files or Pages
|
16
28
|
|
17
29
|
To combine PDF files (or data):
|
data/lib/combine_pdf/parser.rb
CHANGED
@@ -36,7 +36,7 @@ module CombinePDF
|
|
36
36
|
# the info and root objects, as found (if found) in the PDF file.
|
37
37
|
#
|
38
38
|
# they are mainly to used to know if the file is (was) encrypted and to get more details.
|
39
|
-
attr_reader :info_object, :root_object, :names_object
|
39
|
+
attr_reader :info_object, :root_object, :names_object, :forms_object
|
40
40
|
|
41
41
|
# when creating a parser, it is important to set the data (String) we wish to parse.
|
42
42
|
#
|
@@ -54,6 +54,7 @@ module CombinePDF
|
|
54
54
|
@root_object = {}
|
55
55
|
@info_object = {}
|
56
56
|
@names_object = {}
|
57
|
+
@forms_object = {}
|
57
58
|
@strings_dictionary = {} # all strings are one string
|
58
59
|
@version = nil
|
59
60
|
@scanner = nil
|
@@ -470,6 +471,7 @@ module CombinePDF
|
|
470
471
|
when :Pages
|
471
472
|
catalog_pages(catalogs[:Kids], inheritance_hash.dup ) unless catalogs[:Kids].nil?
|
472
473
|
when :Catalog
|
474
|
+
@forms_object.update( (catalogs[:AcroForm][:referenced_object] || catalogs[:AcroForm]), &self.class.method(:hash_update_proc_for_new) ) if catalogs[:AcroForm]
|
473
475
|
@names_object.update( (catalogs[:Names][:referenced_object] || catalogs[:Names]), &self.class.method(:hash_update_proc_for_new) ) if catalogs[:Names]
|
474
476
|
catalog_pages(catalogs[:Pages], inheritance_hash.dup ) unless catalogs[:Pages].nil?
|
475
477
|
end
|
@@ -27,7 +27,7 @@ module CombinePDF
|
|
27
27
|
# this is used for internal operations, such as injectng data using the << operator.
|
28
28
|
def add_referenced(object, dup_pages = true)
|
29
29
|
# add references but not root
|
30
|
-
case
|
30
|
+
case
|
31
31
|
when object.is_a?(Array)
|
32
32
|
object.each {|it| add_referenced(it, dup_pages)}
|
33
33
|
return true
|
@@ -58,8 +58,8 @@ module CombinePDF
|
|
58
58
|
|
59
59
|
end
|
60
60
|
object.each do |k, v|
|
61
|
-
add_referenced(v, dup_pages) unless k == :Parent
|
62
|
-
end
|
61
|
+
add_referenced(v, dup_pages) unless k == :Parent
|
62
|
+
end
|
63
63
|
else
|
64
64
|
return false
|
65
65
|
end
|
@@ -88,9 +88,18 @@ module CombinePDF
|
|
88
88
|
# rebuild/rename the names dictionary
|
89
89
|
rebuild_names
|
90
90
|
# build new Catalog object
|
91
|
-
catalog_object = {Type: :Catalog, Pages: {referenced_object: pages_object, is_reference_only: true}, Names: {referenced_object: @names, is_reference_only: true}
|
91
|
+
catalog_object = {Type: :Catalog, Pages: {referenced_object: pages_object, is_reference_only: true}, Names: {referenced_object: @names, is_reference_only: true}}
|
92
92
|
catalog_object[:ViewerPreferences] = @viewer_preferences unless @viewer_preferences.empty?
|
93
93
|
|
94
|
+
# rebuild/rename the forms dictionary
|
95
|
+
if @forms_data.nil? || @forms_data.empty?
|
96
|
+
@forms_data = nil
|
97
|
+
else
|
98
|
+
@forms_data = {referenced_object: actual_value(@forms_data), is_reference_only: true}
|
99
|
+
catalog_object[:AcroForm] = @forms_data
|
100
|
+
end
|
101
|
+
|
102
|
+
|
94
103
|
# point old Pages pointers to new Pages object
|
95
104
|
## first point known pages objects - enough?
|
96
105
|
pages.each {|p| p[:Parent] = { referenced_object: pages_object, is_reference_only: true} }
|
@@ -110,6 +119,9 @@ module CombinePDF
|
|
110
119
|
def names_object
|
111
120
|
@names
|
112
121
|
end
|
122
|
+
def forms_data
|
123
|
+
@forms_data
|
124
|
+
end
|
113
125
|
|
114
126
|
# @private
|
115
127
|
# this is an alternative to the rebuild_catalog catalog method
|
@@ -213,4 +225,3 @@ module CombinePDF
|
|
213
225
|
|
214
226
|
end
|
215
227
|
end
|
216
|
-
|
@@ -104,6 +104,7 @@ module CombinePDF
|
|
104
104
|
@version = parser.version if parser.version.is_a? Float
|
105
105
|
@info = parser.info_object || {}
|
106
106
|
@names = parser.names_object || {}
|
107
|
+
@forms_data = parser.forms_object || {}
|
107
108
|
|
108
109
|
# general globals
|
109
110
|
@set_start_id = 1
|
@@ -146,9 +147,13 @@ module CombinePDF
|
|
146
147
|
def author=(new_author = nil)
|
147
148
|
@info[:Author] = new_author
|
148
149
|
end
|
150
|
+
# Clears any existing form data.
|
151
|
+
def clear_forms_data
|
152
|
+
@forms_data.nil? || @forms_data.clear
|
153
|
+
end
|
149
154
|
|
150
155
|
# Save the PDF to file.
|
151
|
-
#
|
156
|
+
#
|
152
157
|
# file_name:: is a string or path object for the output.
|
153
158
|
#
|
154
159
|
# **Notice!** if the file exists, it **WILL** be overwritten.
|
@@ -294,7 +299,13 @@ module CombinePDF
|
|
294
299
|
if data.is_a? PDF
|
295
300
|
@version = [@version, data.version].max
|
296
301
|
pages_to_add = data.pages
|
297
|
-
@names.update data.names_object, &self.class.method(:hash_merge_new_no_page)
|
302
|
+
actual_value(@names).update actual_value(data.names_object), &self.class.method(:hash_merge_new_no_page)
|
303
|
+
if actual_value(@forms_data)
|
304
|
+
actual_value(@forms_data).update actual_value(data.forms_data), &self.class.method(:hash_merge_new_no_page) if data.forms_data
|
305
|
+
else
|
306
|
+
@forms_data = data.forms_data
|
307
|
+
end
|
308
|
+
warn "Form data might be lost when combining PDF forms (possible conflicts)." unless data.forms_data.nil? || data.forms_data.empty?
|
298
309
|
elsif data.is_a?(Array) && (data.select {|o| !(o.is_a?(Hash) && o[:Type] == :Page) } ).empty?
|
299
310
|
pages_to_add = data
|
300
311
|
elsif data.is_a?(Hash) && data[:Type] == :Page
|
@@ -403,7 +414,7 @@ module CombinePDF
|
|
403
414
|
right_position = page_width - from_side - box_width
|
404
415
|
top_position = page_height - from_height
|
405
416
|
bottom_position = from_height + box_height
|
406
|
-
|
417
|
+
|
407
418
|
if opt[:location].include? :top
|
408
419
|
page.textbox text, {x: center_position, y: top_position }.merge(add_opt)
|
409
420
|
end
|
@@ -444,7 +455,7 @@ module CombinePDF
|
|
444
455
|
options[:location] ||= [:center]
|
445
456
|
number_pages({number_format: stamp}.merge(options))
|
446
457
|
when Page_Methods
|
447
|
-
# stamp = stamp.copy(true)
|
458
|
+
# stamp = stamp.copy(true)
|
448
459
|
if options[:underlay]
|
449
460
|
(options[:page_range] ? pages[options[:page_range]] : pages).each {|p| p >> stamp}
|
450
461
|
else
|
@@ -458,4 +469,3 @@ module CombinePDF
|
|
458
469
|
end
|
459
470
|
|
460
471
|
end
|
461
|
-
|
data/lib/combine_pdf/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: combine_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-rc4
|