combine_pdf 1.0.22 → 1.0.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +28 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +17 -1
- data/README.md +11 -11
- data/Rakefile +8 -1
- data/combine_pdf.gemspec +2 -1
- data/lib/combine_pdf/parser.rb +5 -3
- data/lib/combine_pdf/pdf_public.rb +12 -5
- data/lib/combine_pdf/version.rb +1 -1
- data/test/automated +65 -64
- data/test/combine_pdf/load_test.rb +48 -0
- data/test/combine_pdf/renderer_test.rb +0 -2
- data/test/fixtures/files/sample_encrypted_pdf.pdf +0 -0
- data/test/fixtures/files/sample_pdf.pdf +0 -0
- metadata +26 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc482ee9da31ce7fc01e92da3936e44407e4879c7058817bb4a57ba0fc0a4165
|
4
|
+
data.tar.gz: 1dd52423ee639783510a9ad9aa347e9597e2e14d38a11914d05a03b5116006f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6ac66c289762c5f2b6473f450e8808e79d9ca9f927b68f083204a93b7f213a433a6fc4076cd3241ff1a17ac7c08297087ab1bf76e58b0dad12e7a0eebc34628
|
7
|
+
data.tar.gz: a39c619af345d61d7d40ba0d0b0a32438caace2b05512273afe1f21b737de6324dcc483f34234c5123c9ed0508a0db481b4bf90ffc06fce2484922f2c6c7abe0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
name: Main
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
tests:
|
7
|
+
name: Tests
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
strategy:
|
10
|
+
fail-fast: false
|
11
|
+
matrix:
|
12
|
+
ruby: ["2.7", "3.0", "3.1", "3.2"]
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- name: Checkout code
|
16
|
+
uses: actions/checkout@v3
|
17
|
+
|
18
|
+
- name: Setup Ruby
|
19
|
+
uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
bundler-cache: true
|
23
|
+
|
24
|
+
- name: Generate lockfile
|
25
|
+
run: bundle lock
|
26
|
+
|
27
|
+
- name: Run tests
|
28
|
+
run: bundle exec rake test
|
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
language: ruby
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
|
3
|
+
#### Change log v.1.0.26 (2023-12-22)
|
4
|
+
|
5
|
+
**Performance**: possible performance bump. Credit to @denislavski (Denislav Naydenov) for opening PR #235.
|
6
|
+
|
7
|
+
#### Change log v.1.0.25 (2023-12-19)
|
8
|
+
|
9
|
+
**Fix**: possible improve memory usage. Credit to @denislavski (Denislav Naydenov) for opening PR #233 and suggesting this change.
|
10
|
+
|
11
|
+
#### Change log v.1.0.24 (2023-10-19)
|
12
|
+
|
13
|
+
**Fix**: possible `nil` in loop. Credit to @jkowens for PR #231 and adding a quick fix using a simple guard.
|
14
|
+
|
15
|
+
**Fix**: preserve file creation date metadata where relevant.
|
16
|
+
|
17
|
+
#### Change log v.1.0.23 (2023-04-04)
|
18
|
+
|
19
|
+
**Feature**: merged PR #177 for the `raise_on_encrypted: true` option support. Credit to @leviwilson and @kimyu92 for the PR.
|
4
20
|
|
5
21
|
#### Change log v.1.0.22
|
6
22
|
|
data/README.md
CHANGED
@@ -7,23 +7,23 @@
|
|
7
7
|
|
8
8
|
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).
|
9
9
|
|
10
|
-
##
|
10
|
+
## Unmaintained - Help Wanted(!)
|
11
11
|
|
12
|
-
|
12
|
+
I decided to stop maintaining this gem and hope someone could take over the PR reviews and maintenance of this gem (or simply open a successful fork).
|
13
13
|
|
14
|
-
|
15
|
-
gem install combine_pdf
|
16
|
-
```
|
14
|
+
I wrote this gem because I needed to solve an issue with bates-numbering existing PDF documents.
|
17
15
|
|
18
|
-
|
16
|
+
However, since 2014 I have been maintaining the gem for free and for no reason at all, except that I enjoyed sharing it with the community.
|
19
17
|
|
20
|
-
I
|
18
|
+
I love this gem, but I cannot keep maintaining it as I have my own projects to focus own and I need both the time and (more importantly) the mindspace.
|
21
19
|
|
22
|
-
|
20
|
+
## Install
|
23
21
|
|
24
|
-
|
22
|
+
Install with ruby gems:
|
25
23
|
|
26
|
-
|
24
|
+
```ruby
|
25
|
+
gem install combine_pdf
|
26
|
+
```
|
27
27
|
|
28
28
|
## Known Limitations
|
29
29
|
|
@@ -39,7 +39,7 @@ Quick rundown:
|
|
39
39
|
|
40
40
|
Some links will be lost when ripping pages out of PDF files and merging them with another PDF.
|
41
41
|
|
42
|
-
* Some encrypted PDF files (usually the ones you can't view without a password) will fail quietly instead of noisily.
|
42
|
+
* Some encrypted PDF files (usually the ones you can't view without a password) will fail quietly instead of noisily. If you prefer to choose the noisy route, you can specify the `raise_on_encrypted` option using `CombinePDF.load(pdf_file, raise_on_encrypted: true)` which will raise a `CombinePDF::EncryptionError`.
|
43
43
|
|
44
44
|
* Sometimes the CombinePDF will raise an exception even if the PDF could be parsed (i.e., when PDF optional content exists)... I find it better to err on the side of caution, although for optional content PDFs an exception is avoidable using `CombinePDF.load(pdf_file, allow_optional_content: true)`.
|
45
45
|
|
data/Rakefile
CHANGED
data/combine_pdf.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "combine_pdf"
|
8
8
|
spec.version = CombinePDF::VERSION
|
9
9
|
spec.authors = ["Boaz Segev"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["bo@bowild.com"]
|
11
11
|
spec.summary = %q{Combine, stamp and watermark PDF files in pure Ruby.}
|
12
12
|
spec.description = %q{A nifty gem, in pure Ruby, to parse PDF files and combine (merge) them with other PDF files, number the pages, watermark them or stamp them, create tables, add basic text objects etc` (all using the PDF file format).}
|
13
13
|
spec.homepage = "https://github.com/boazsegev/combine_pdf"
|
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
|
|
24
24
|
# spec.add_development_dependency "bundler", ">= 1.7"
|
25
25
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
26
26
|
spec.add_development_dependency "minitest"
|
27
|
+
spec.add_development_dependency "minitest-around"
|
27
28
|
end
|
data/lib/combine_pdf/parser.rb
CHANGED
@@ -33,7 +33,7 @@ module CombinePDF
|
|
33
33
|
# they are mainly to used to know if the file is (was) encrypted and to get more details.
|
34
34
|
attr_reader :info_object, :root_object, :names_object, :forms_object, :outlines_object, :metadata
|
35
35
|
|
36
|
-
attr_reader :allow_optional_content
|
36
|
+
attr_reader :allow_optional_content, :raise_on_encrypted
|
37
37
|
# when creating a parser, it is important to set the data (String) we wish to parse.
|
38
38
|
#
|
39
39
|
# <b>the data is required and it is not possible to set the data at a later stage</b>
|
@@ -58,6 +58,7 @@ module CombinePDF
|
|
58
58
|
@version = nil
|
59
59
|
@scanner = nil
|
60
60
|
@allow_optional_content = options[:allow_optional_content]
|
61
|
+
@raise_on_encrypted = options[:raise_on_encrypted]
|
61
62
|
end
|
62
63
|
|
63
64
|
# parse the data in the new parser (the data already set through the initialize / new method)
|
@@ -96,6 +97,7 @@ module CombinePDF
|
|
96
97
|
end
|
97
98
|
|
98
99
|
if @root_object[:Encrypt]
|
100
|
+
raise EncryptionError, 'the file is encrypted' if @raise_on_encrypted
|
99
101
|
# change_references_to_actual_values @root_object
|
100
102
|
warn 'PDF is Encrypted! Attempting to decrypt - not yet fully supported.'
|
101
103
|
decryptor = PDFDecrypt.new @parsed, @root_object
|
@@ -321,8 +323,8 @@ module CombinePDF
|
|
321
323
|
str << 12
|
322
324
|
when 48..57 # octal notation for byte?
|
323
325
|
rep -= 48
|
324
|
-
rep = (rep << 3) + (str_bytes.shift-48) if str_bytes[0]
|
325
|
-
rep = (rep << 3) + (str_bytes.shift-48) if str_bytes[0]
|
326
|
+
rep = (rep << 3) + (str_bytes.shift-48) if str_bytes[0]&.between?(48, 57)
|
327
|
+
rep = (rep << 3) + (str_bytes.shift-48) if str_bytes[0]&.between?(48, 57) && (((rep << 3) + (str_bytes[0] - 48)) <= 255)
|
326
328
|
str << rep
|
327
329
|
when 10 # new line, ignore
|
328
330
|
str_bytes.shift if str_bytes[0] == 13
|
@@ -96,6 +96,7 @@ module CombinePDF
|
|
96
96
|
parser ||= PDFParser.new('')
|
97
97
|
raise TypeError, "initialization error, expecting CombinePDF::PDFParser or nil, but got #{parser.class.name}" unless parser.is_a? PDFParser
|
98
98
|
@objects = parser.parse
|
99
|
+
|
99
100
|
# remove any existing id's
|
100
101
|
remove_old_ids
|
101
102
|
# set data from parser
|
@@ -174,8 +175,12 @@ module CombinePDF
|
|
174
175
|
def to_pdf(options = {})
|
175
176
|
# reset version if not specified
|
176
177
|
@version = 1.5 if @version.to_f == 0.0
|
178
|
+
|
177
179
|
# set info for merged file
|
178
|
-
@info[:
|
180
|
+
unless(@info[:CreationDate].is_a?(String))
|
181
|
+
@info[:CreationDate] = Time.now unless @info[:CreationDate].is_a?(Time)
|
182
|
+
@info[:CreationDate] = @info[:CreationDate].getgm.strftime("D:%Y%m%d%H%M%S%:::z'00")
|
183
|
+
end
|
179
184
|
@info[:Subject] = options[:subject] if options[:subject]
|
180
185
|
@info[:Producer] = options[:producer] if options[:producer]
|
181
186
|
# rebuild_catalog
|
@@ -201,9 +206,9 @@ module CombinePDF
|
|
201
206
|
xref_location = loc
|
202
207
|
# xref_location = 0
|
203
208
|
# out.each { |line| xref_location += line.bytesize + 1}
|
204
|
-
out << "xref\n0 #{indirect_object_count}\n0000000000 65535 f
|
205
|
-
xref.each { |offset| out << (
|
206
|
-
out <<
|
209
|
+
out << "xref\n0 #{indirect_object_count}\n0000000000 65535 f "
|
210
|
+
xref.each { |offset| out << ("%010d 00000 n ".freeze % offset) }
|
211
|
+
out << 'trailer'.freeze
|
207
212
|
out << "<<\n/Root #{false || "#{catalog[:indirect_reference_id]} #{catalog[:indirect_generation_number]} R"}"
|
208
213
|
out << "/Size #{indirect_object_count}"
|
209
214
|
out << "/Info #{@info[:indirect_reference_id]} #{@info[:indirect_generation_number]} R"
|
@@ -261,10 +266,12 @@ module CombinePDF
|
|
261
266
|
next if !r
|
262
267
|
r = r[:referenced_object] if r[:referenced_object]
|
263
268
|
r = r[:Font]
|
264
|
-
next if !r
|
269
|
+
next if !r
|
265
270
|
r = r[:referenced_object] if r[:referenced_object]
|
266
271
|
r.values.each do |f|
|
272
|
+
next if f.class != Hash
|
267
273
|
f = f[:referenced_object] if f[:referenced_object]
|
274
|
+
next if f.class != Hash
|
268
275
|
if (limit_to_type0 || f[:Subtype] == :Type0) && f[:Type] == :Font && !fonts_array.include?(f)
|
269
276
|
fonts_array << f
|
270
277
|
end
|
data/lib/combine_pdf/version.rb
CHANGED
data/test/automated
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
$VERBOSE = true
|
4
4
|
|
5
5
|
require 'benchmark'
|
6
|
-
|
6
|
+
Dir.chdir File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
7
|
+
$LOAD_PATH.unshift Dir.pwd
|
7
8
|
require 'combine_pdf'
|
8
|
-
require 'bundler/setup'
|
9
|
+
# require 'bundler/setup'
|
9
10
|
|
10
11
|
# You can add fixtures and/or initialization code here to make experimenting
|
11
12
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -14,54 +15,54 @@ require 'bundler/setup'
|
|
14
15
|
# require "pry"
|
15
16
|
# Pry.start
|
16
17
|
|
17
|
-
pdf = CombinePDF.load "
|
18
|
-
pdf.save '01_check_radio_buttuns.pdf'
|
19
|
-
pdf = CombinePDF.load "
|
20
|
-
pdf << CombinePDF.load("
|
21
|
-
pdf << CombinePDF.load("
|
22
|
-
pdf.save '02_check_form_unification_middle_is_empty.pdf'
|
18
|
+
pdf = CombinePDF.load "../../test\ pdfs/filled_form.pdf"
|
19
|
+
pdf.save '../tmp/01_check_radio_buttuns.pdf'
|
20
|
+
pdf = CombinePDF.load "../../test\ pdfs/filled_form.pdf"
|
21
|
+
pdf << CombinePDF.load("../../test\ pdfs/empty_form.pdf")
|
22
|
+
pdf << CombinePDF.load("../../test\ pdfs/filled_form.pdf")
|
23
|
+
pdf.save '../tmp/02_check_form_unification_middle_is_empty.pdf'
|
23
24
|
|
24
|
-
pdf = CombinePDF.load "
|
25
|
-
pdf.save '02_01_check_form_data_ordering_issue.pdf'
|
25
|
+
pdf = CombinePDF.load "../../test\ pdfs/check_form_data__objstreams_w_versions.pdf"
|
26
|
+
pdf.save '../tmp/02_01_check_form_data_ordering_issue.pdf'
|
26
27
|
|
27
28
|
|
28
|
-
pdf = CombinePDF.load '
|
29
|
-
pdf2 = CombinePDF.load '
|
29
|
+
pdf = CombinePDF.load '../../test pdfs/share-font-background.pdf'
|
30
|
+
pdf2 = CombinePDF.load '../../test pdfs/share-font-foreground.pdf'
|
30
31
|
i = 0
|
31
32
|
pdf.pages.each { |pg| pg << pdf2.pages[i] }
|
32
|
-
pdf.save '03_check_font_conflict.pdf'
|
33
|
+
pdf.save '../tmp/03_check_font_conflict.pdf'
|
33
34
|
|
34
|
-
pdf = CombinePDF.load '
|
35
|
-
pdf2 = CombinePDF.load '
|
35
|
+
pdf = CombinePDF.load '../../test pdfs/nil_1.pdf'
|
36
|
+
pdf2 = CombinePDF.load '../../test pdfs/nil_2.pdf'
|
36
37
|
pdf << pdf2
|
37
|
-
pdf.save '03_01_nil_value_conflict.pdf'
|
38
|
+
pdf.save '../tmp/03_01_nil_value_conflict.pdf'
|
38
39
|
|
39
|
-
pdf = CombinePDF.load '
|
40
|
-
pdf.save '03_02_extra_space_after_stream_keyword.pdf'
|
40
|
+
pdf = CombinePDF.load '../../test pdfs/space_after_streram_keyword.pdf'
|
41
|
+
pdf.save '../tmp/03_02_extra_space_after_stream_keyword.pdf'
|
41
42
|
|
42
|
-
pdf = CombinePDF.load '
|
43
|
-
pdf.save '03_03_nested_difference.pdf'
|
43
|
+
pdf = CombinePDF.load '../../test pdfs/nested_difference.pdf'
|
44
|
+
pdf.save '../tmp/03_03_nested_difference.pdf'
|
44
45
|
|
45
|
-
pdf = CombinePDF.load '
|
46
|
-
pdf << CombinePDF.load('
|
47
|
-
pdf.save '04_check_view_and_names_reference.pdf'
|
46
|
+
pdf = CombinePDF.load '../../test pdfs/names_go_haywire_0.pdf'
|
47
|
+
pdf << CombinePDF.load('../../test pdfs/names_go_haywire_1.pdf')
|
48
|
+
pdf.save '../tmp/04_check_view_and_names_reference.pdf'
|
48
49
|
|
49
|
-
pdf = CombinePDF.load('
|
50
|
-
pdf.save '05_x1_scribus_test.pdf'
|
51
|
-
pdf = CombinePDF.load('
|
52
|
-
pdf << CombinePDF.load('
|
53
|
-
pdf.save '05_x2_scribus_test.pdf'
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
pdf << CombinePDF.load('
|
58
|
-
pdf.save '05_1_timeless_check_named_dest_links.pdf' # never ends... :-(
|
50
|
+
pdf = CombinePDF.load('../../test pdfs/outlines/self_merge_err.pdf')
|
51
|
+
pdf.save '../tmp/05_x1_scribus_test.pdf'
|
52
|
+
pdf = CombinePDF.load('../../test pdfs/outlines/self_merge_err.pdf')
|
53
|
+
pdf << CombinePDF.load('../../test pdfs/outlines/self_merge_err.pdf')
|
54
|
+
pdf.save '../tmp/05_x2_scribus_test.pdf'
|
55
|
+
pdf = CombinePDF.load "../../test pdfs/outlines/named_dest.pdf";nil
|
56
|
+
pdf.save '../tmp/05_check_named_dest_links.pdf' # this will take a while
|
57
|
+
pdf = CombinePDF.load "../../test pdfs/outlines/named_dest.pdf";nil
|
58
|
+
pdf << CombinePDF.load('../../test pdfs/outlines/named_dest.pdf'); nil
|
59
|
+
pdf.save '../tmp/05_1_timeless_check_named_dest_links.pdf' # never ends... :-(
|
59
60
|
|
60
|
-
pdf = CombinePDF.load '
|
61
|
-
pdf << CombinePDF.load('
|
62
|
-
pdf.save '06_check_links_to_second_copy.pdf'
|
61
|
+
pdf = CombinePDF.load '../../test pdfs/outline_small.pdf'
|
62
|
+
pdf << CombinePDF.load('../../test pdfs/outline_small.pdf')
|
63
|
+
pdf.save '../tmp/06_check_links_to_second_copy.pdf'
|
63
64
|
|
64
|
-
lists = %w(
|
65
|
+
lists = %w(../../test\ pdfs/outlines/self_merge_err.pdf ../../test\ pdfs/outlines/big_toc.pdf ../../test\ pdfs/outlines/bigger_toc.pdf ../../test\ pdfs/outlines/named_dest_no_toc.pdf ../../test\ pdfs/outlines/named_dest_no_toc2.pdf ../../test\ pdfs/outlines/named_dest.pdf ../../test\ pdfs/outlines/named_dest2.pdf)
|
65
66
|
|
66
67
|
i = 0
|
67
68
|
lists.each do |n|
|
@@ -76,7 +77,7 @@ lists.each do |n|
|
|
76
77
|
end
|
77
78
|
pdf = CombinePDF.new
|
78
79
|
lists.each { |n| pdf << CombinePDF.load(n) }
|
79
|
-
pdf.save('07_named destinations.pdf')
|
80
|
+
pdf.save('../tmp/07_named destinations.pdf')
|
80
81
|
|
81
82
|
pdf = CombinePDF.new
|
82
83
|
lists.each { |n| pdf << CombinePDF.load(n) }
|
@@ -90,26 +91,26 @@ pdf.number_pages(start_at: 1,
|
|
90
91
|
number_location: [:top, :bottom],
|
91
92
|
opacity: 0.75)
|
92
93
|
|
93
|
-
pdf.save('07_named destinations_numbered.pdf')
|
94
|
+
pdf.save('../tmp/07_named destinations_numbered.pdf')
|
94
95
|
|
95
|
-
CombinePDF.load("
|
96
|
-
CombinePDF.load("
|
97
|
-
CombinePDF.load("
|
98
|
-
CombinePDF.load("
|
99
|
-
CombinePDF.load("
|
96
|
+
CombinePDF.load("../../test\ pdfs/Scribus-unknown_err.pdf").save '../tmp/08_1-unknown-err-empty-str.pdf'
|
97
|
+
CombinePDF.load("../../test\ pdfs/Scribus-unknown_err2.pdf").save '../tmp/08_2-unknown-err-empty-str.pdf'
|
98
|
+
CombinePDF.load("../../test\ pdfs/Scribus-unknown_err3.pdf").save '../tmp/08_3-unknown-err-empty-str.pdf'
|
99
|
+
CombinePDF.load("../../test\ pdfs/xref_in_middle.pdf").save '../tmp/08_4-xref-in-middle.pdf'
|
100
|
+
CombinePDF.load("../../test\ pdfs/xref_split.pdf").save '../tmp/08_5-xref-fragmented.pdf'
|
100
101
|
|
101
|
-
CombinePDF.load("
|
102
|
+
CombinePDF.load("../../test\ pdfs/nil_object.pdf").save('../tmp/09_nil_in_parsed_array.pdf')
|
102
103
|
|
103
|
-
encrypted = [ "
|
104
|
-
"
|
105
|
-
"
|
106
|
-
"
|
107
|
-
"
|
104
|
+
encrypted = [ "../../test\ pdfs/pdf-reader/encrypted_version4_revision4_128bit_aes_user_pass_apples_enc_metadata.pdf",
|
105
|
+
"../../test\ pdfs/AESv2\ encrypted.pdf",
|
106
|
+
"../../test\ pdfs/pdf-reader/encrypted_version2_revision3_128bit_rc4_blank_user_pass.pdf",
|
107
|
+
"../../test\ pdfs/AES\ enc.pdf",
|
108
|
+
"../../test\ pdfs/RC4\ enc.pdf"]
|
108
109
|
|
109
110
|
encrypted.length.times do |i|
|
110
111
|
fname = File.basename encrypted[i]
|
111
112
|
begin
|
112
|
-
CombinePDF.load(encrypted[i]).save "10_#{i}_#{fname}"
|
113
|
+
CombinePDF.load(encrypted[i]).save "../tmp/10_#{i}_#{fname}"
|
113
114
|
rescue => e
|
114
115
|
puts e.class.name, e.message
|
115
116
|
if(i == 0)
|
@@ -125,24 +126,24 @@ IO.binwrite '11_prawn.pdf', (Prawn::Document.new { text 'Hello World!' }).render
|
|
125
126
|
page = CombinePDF.parse((Prawn::Document.new { text 'Hello World!' }).render)
|
126
127
|
pdf = CombinePDF.new
|
127
128
|
pdf << page
|
128
|
-
pdf.save '11_parsed_from_prawn.pdf'
|
129
|
+
pdf.save '../tmp/11_parsed_from_prawn.pdf'
|
129
130
|
pdf = CombinePDF.new
|
130
131
|
pdf << page << page
|
131
|
-
pdf.save('11_AcrobatReader_is_unique_page.pdf')
|
132
|
+
pdf.save('../tmp/11_AcrobatReader_is_unique_page.pdf')
|
132
133
|
|
133
134
|
puts GC.stat.inspect
|
134
135
|
# unify = [
|
135
|
-
# "
|
136
|
-
# "
|
137
|
-
# "
|
138
|
-
# "
|
139
|
-
# "
|
140
|
-
# "
|
141
|
-
# "
|
142
|
-
# "
|
143
|
-
# "
|
144
|
-
# "
|
145
|
-
# "
|
136
|
+
# "../../test\ pdfs/AESv2\ encrypted.pdf",
|
137
|
+
# "../../test\ pdfs/data-in-comment.pdf",
|
138
|
+
# "../../test\ pdfs/file_name.pdf",
|
139
|
+
# "../../test\ pdfs/garbage_after_eof.pdf",
|
140
|
+
# "../../test\ pdfs/Many\ comments.pdf",
|
141
|
+
# "../../test\ pdfs/nested\ contents\ array.PDF",
|
142
|
+
# "../../test\ pdfs/nested_resources.pdf",
|
143
|
+
# "../../test\ pdfs/original-missing-endobje.pdf",
|
144
|
+
# "../../test\ pdfs/original-multi-issue.pdf",
|
145
|
+
# "../../test\ pdfs/page_stap_nil_secure.pdf",
|
146
|
+
# "../../test\ pdfs/referenced\ decryption.pdf",
|
146
147
|
# '',
|
147
148
|
# '',
|
148
149
|
# '',
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'minitest/around/spec'
|
4
|
+
require 'combine_pdf'
|
5
|
+
|
6
|
+
describe 'CombinePDF.load' do
|
7
|
+
let(:options) { {} }
|
8
|
+
|
9
|
+
subject { CombinePDF.load "test/fixtures/files/#{file}", options }
|
10
|
+
|
11
|
+
describe 'raise_on_encrypted option' do
|
12
|
+
let(:file) { 'sample_encrypted_pdf.pdf' }
|
13
|
+
let(:options) { { raise_on_encrypted: raise_on_encrypted } }
|
14
|
+
|
15
|
+
describe 'when raise_on_encrypted: true' do
|
16
|
+
let(:raise_on_encrypted) { true }
|
17
|
+
|
18
|
+
describe 'with encrypted file' do
|
19
|
+
it('raises an CombinePDF::EncryptionError') do
|
20
|
+
error = assert_raises(CombinePDF::EncryptionError) { subject }
|
21
|
+
assert_match 'the file is encrypted', error.message
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'with unencrypted file' do
|
26
|
+
let(:file) { 'sample_pdf.pdf' }
|
27
|
+
|
28
|
+
it('has a PDF') { assert_instance_of CombinePDF::PDF, subject }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'when raise_on_encrypted: false' do
|
33
|
+
let(:raise_on_encrypted) { false }
|
34
|
+
|
35
|
+
describe 'with encrypted file' do
|
36
|
+
it('does not raise an CombinePDF::EncryptionError') do
|
37
|
+
assert_instance_of CombinePDF::PDF, subject
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'with unencrypted file' do
|
42
|
+
let(:file) { 'sample_pdf.pdf' }
|
43
|
+
|
44
|
+
it('has a PDF') { assert_instance_of CombinePDF::PDF, subject }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
Binary file
|
Binary file
|
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: 1.0.
|
4
|
+
version: 1.0.26
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-rc4
|
@@ -66,16 +66,32 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-around
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: A nifty gem, in pure Ruby, to parse PDF files and combine (merge) them
|
70
84
|
with other PDF files, number the pages, watermark them or stamp them, create tables,
|
71
85
|
add basic text objects etc` (all using the PDF file format).
|
72
86
|
email:
|
73
|
-
-
|
87
|
+
- bo@bowild.com
|
74
88
|
executables: []
|
75
89
|
extensions: []
|
76
90
|
extra_rdoc_files: []
|
77
91
|
files:
|
92
|
+
- ".github/workflows/main.yml"
|
78
93
|
- ".gitignore"
|
94
|
+
- ".travis.yml"
|
79
95
|
- CHANGELOG.md
|
80
96
|
- Gemfile
|
81
97
|
- LICENSE.txt
|
@@ -96,8 +112,11 @@ files:
|
|
96
112
|
- lib/combine_pdf/renderer.rb
|
97
113
|
- lib/combine_pdf/version.rb
|
98
114
|
- test/automated
|
115
|
+
- test/combine_pdf/load_test.rb
|
99
116
|
- test/combine_pdf/renderer_test.rb
|
100
117
|
- test/console
|
118
|
+
- test/fixtures/files/sample_encrypted_pdf.pdf
|
119
|
+
- test/fixtures/files/sample_pdf.pdf
|
101
120
|
- test/named_dest
|
102
121
|
homepage: https://github.com/boazsegev/combine_pdf
|
103
122
|
licenses:
|
@@ -118,12 +137,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
137
|
- !ruby/object:Gem::Version
|
119
138
|
version: '0'
|
120
139
|
requirements: []
|
121
|
-
rubygems_version: 3.
|
140
|
+
rubygems_version: 3.3.26
|
122
141
|
signing_key:
|
123
142
|
specification_version: 4
|
124
143
|
summary: Combine, stamp and watermark PDF files in pure Ruby.
|
125
144
|
test_files:
|
126
145
|
- test/automated
|
146
|
+
- test/combine_pdf/load_test.rb
|
127
147
|
- test/combine_pdf/renderer_test.rb
|
128
148
|
- test/console
|
149
|
+
- test/fixtures/files/sample_encrypted_pdf.pdf
|
150
|
+
- test/fixtures/files/sample_pdf.pdf
|
129
151
|
- test/named_dest
|