combine_pdf 1.0.21 → 1.0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +9 -1
- data/README.md +1 -1
- data/Rakefile +8 -1
- data/combine_pdf.gemspec +2 -0
- data/lib/combine_pdf/parser.rb +5 -3
- data/lib/combine_pdf/pdf_public.rb +13 -6
- data/lib/combine_pdf/version.rb +1 -1
- data/test/automated +46 -46
- 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 +41 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94a057a85d5c2709211baa3ed7d7deaf73fe93d6bb39ef76e0441a166fb36926
|
4
|
+
data.tar.gz: c7dc7060c7abd51d84ee871b5f818d6e23a797eb424a8a7a963b0ae7f7324921
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 110074ae751586009d436dd4dc997c7d6bb71480d782270fe67834458cecc7479b58effc8102745a437c718426c97ca78d9ea3d2941355ba1ce8fc6f34ab2b8a
|
7
|
+
data.tar.gz: 4cf409946ba651fd474f7ff8a3dbf56442afd96b35fe73b68013a9a863e01e9d766a516ea4ddd4f5af7f2c47192abc0619321a6bc01c5a4e0dcd0e192701d168
|
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
language: ruby
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
|
3
|
+
#### Change log v.1.0.23 (2023-03-04)
|
4
|
+
|
5
|
+
**Feature**: merged PR #177 for the `raise_on_encrypted: true` option support. Credit to @leviwilson and @kimyu92 for the PR.
|
6
|
+
|
7
|
+
#### Change log v.1.0.22
|
8
|
+
|
9
|
+
**Fix**: fix `fonts` dereferencing issue (#203), credit to @MarcWeber (Marc Weber) for identifying the issue.
|
10
|
+
|
11
|
+
**Fix**: fix `metrix` dependency, credit to @casperisfine (Jean byroot Boussier) for PR #195.
|
4
12
|
|
5
13
|
#### Change log v.1.0.21
|
6
14
|
|
data/README.md
CHANGED
@@ -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
@@ -19,8 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency 'ruby-rc4', '>= 0.1.5'
|
22
|
+
spec.add_runtime_dependency 'matrix'
|
22
23
|
|
23
24
|
# spec.add_development_dependency "bundler", ">= 1.7"
|
24
25
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
25
26
|
spec.add_development_dependency "minitest"
|
27
|
+
spec.add_development_dependency "minitest-around"
|
26
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
|
@@ -360,8 +362,8 @@ module CombinePDF
|
|
360
362
|
@scanner.pos += 1 if @scanner.peek(1) == "\n".freeze && @scanner.matched[-1] != "\n".freeze
|
361
363
|
# advance by the publshed stream length (if any)
|
362
364
|
old_pos = @scanner.pos
|
363
|
-
if(out.last.is_a?(Hash) && out.last[:Length].is_a?(Integer) && out.last[:Length]
|
364
|
-
@scanner.pos += out.last[:Length]
|
365
|
+
if(out.last.is_a?(Hash) && out.last[:Length].is_a?(Integer) && out.last[:Length] > 2)
|
366
|
+
@scanner.pos += out.last[:Length] - 2
|
365
367
|
end
|
366
368
|
|
367
369
|
# the following was dicarded because some PDF files didn't have an EOL marker as required
|
@@ -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
|
@@ -257,12 +258,18 @@ module CombinePDF
|
|
257
258
|
def fonts(limit_to_type0 = false)
|
258
259
|
fonts_array = []
|
259
260
|
pages.each do |pg|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
261
|
+
r = pg[:Resources]
|
262
|
+
next if !r
|
263
|
+
r = r[:referenced_object] if r[:referenced_object]
|
264
|
+
r = r[:Font]
|
265
|
+
next if !r
|
266
|
+
r = r[:referenced_object] if r[:referenced_object]
|
267
|
+
r.values.each do |f|
|
268
|
+
next if f.class != Hash
|
269
|
+
f = f[:referenced_object] if f[:referenced_object]
|
270
|
+
next if f.class != Hash
|
271
|
+
if (limit_to_type0 || f[:Subtype] == :Type0) && f[:Type] == :Font && !fonts_array.include?(f)
|
272
|
+
fonts_array << f
|
266
273
|
end
|
267
274
|
end
|
268
275
|
end
|
data/lib/combine_pdf/version.rb
CHANGED
data/test/automated
CHANGED
@@ -5,7 +5,7 @@ $VERBOSE = true
|
|
5
5
|
require 'benchmark'
|
6
6
|
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
7
7
|
require 'combine_pdf'
|
8
|
-
require 'bundler/setup'
|
8
|
+
# require 'bundler/setup'
|
9
9
|
|
10
10
|
# You can add fixtures and/or initialization code here to make experimenting
|
11
11
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -14,54 +14,54 @@ require 'bundler/setup'
|
|
14
14
|
# require "pry"
|
15
15
|
# Pry.start
|
16
16
|
|
17
|
-
pdf = CombinePDF.load "
|
17
|
+
pdf = CombinePDF.load "../../test\ pdfs/filled_form.pdf"
|
18
18
|
pdf.save '01_check_radio_buttuns.pdf'
|
19
|
-
pdf = CombinePDF.load "
|
20
|
-
pdf << CombinePDF.load("
|
21
|
-
pdf << CombinePDF.load("
|
19
|
+
pdf = CombinePDF.load "../../test\ pdfs/filled_form.pdf"
|
20
|
+
pdf << CombinePDF.load("../../test\ pdfs/empty_form.pdf")
|
21
|
+
pdf << CombinePDF.load("../../test\ pdfs/filled_form.pdf")
|
22
22
|
pdf.save '02_check_form_unification_middle_is_empty.pdf'
|
23
23
|
|
24
|
-
pdf = CombinePDF.load "
|
24
|
+
pdf = CombinePDF.load "../../test\ pdfs/check_form_data__objstreams_w_versions.pdf"
|
25
25
|
pdf.save '02_01_check_form_data_ordering_issue.pdf'
|
26
26
|
|
27
27
|
|
28
|
-
pdf = CombinePDF.load '
|
29
|
-
pdf2 = CombinePDF.load '
|
28
|
+
pdf = CombinePDF.load '../../test pdfs/share-font-background.pdf'
|
29
|
+
pdf2 = CombinePDF.load '../../test pdfs/share-font-foreground.pdf'
|
30
30
|
i = 0
|
31
31
|
pdf.pages.each { |pg| pg << pdf2.pages[i] }
|
32
32
|
pdf.save '03_check_font_conflict.pdf'
|
33
33
|
|
34
|
-
pdf = CombinePDF.load '
|
35
|
-
pdf2 = CombinePDF.load '
|
34
|
+
pdf = CombinePDF.load '../../test pdfs/nil_1.pdf'
|
35
|
+
pdf2 = CombinePDF.load '../../test pdfs/nil_2.pdf'
|
36
36
|
pdf << pdf2
|
37
37
|
pdf.save '03_01_nil_value_conflict.pdf'
|
38
38
|
|
39
|
-
pdf = CombinePDF.load '
|
39
|
+
pdf = CombinePDF.load '../../test pdfs/space_after_streram_keyword.pdf'
|
40
40
|
pdf.save '03_02_extra_space_after_stream_keyword.pdf'
|
41
41
|
|
42
|
-
pdf = CombinePDF.load '
|
42
|
+
pdf = CombinePDF.load '../../test pdfs/nested_difference.pdf'
|
43
43
|
pdf.save '03_03_nested_difference.pdf'
|
44
44
|
|
45
|
-
pdf = CombinePDF.load '
|
46
|
-
pdf << CombinePDF.load('
|
45
|
+
pdf = CombinePDF.load '../../test pdfs/names_go_haywire_0.pdf'
|
46
|
+
pdf << CombinePDF.load('../../test pdfs/names_go_haywire_1.pdf')
|
47
47
|
pdf.save '04_check_view_and_names_reference.pdf'
|
48
48
|
|
49
|
-
pdf = CombinePDF.load('
|
49
|
+
pdf = CombinePDF.load('../../test pdfs/outlines/self_merge_err.pdf')
|
50
50
|
pdf.save '05_x1_scribus_test.pdf'
|
51
|
-
pdf = CombinePDF.load('
|
52
|
-
pdf << CombinePDF.load('
|
51
|
+
pdf = CombinePDF.load('../../test pdfs/outlines/self_merge_err.pdf')
|
52
|
+
pdf << CombinePDF.load('../../test pdfs/outlines/self_merge_err.pdf')
|
53
53
|
pdf.save '05_x2_scribus_test.pdf'
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
pdf << CombinePDF.load('
|
54
|
+
pdf = CombinePDF.load "../../test pdfs/outlines/named_dest.pdf";nil
|
55
|
+
pdf.save '05_check_named_dest_links.pdf' # this will take a while
|
56
|
+
pdf = CombinePDF.load "../../test pdfs/outlines/named_dest.pdf";nil
|
57
|
+
pdf << CombinePDF.load('../../test pdfs/outlines/named_dest.pdf'); nil
|
58
58
|
pdf.save '05_1_timeless_check_named_dest_links.pdf' # never ends... :-(
|
59
59
|
|
60
|
-
pdf = CombinePDF.load '
|
61
|
-
pdf << CombinePDF.load('
|
60
|
+
pdf = CombinePDF.load '../../test pdfs/outline_small.pdf'
|
61
|
+
pdf << CombinePDF.load('../../test pdfs/outline_small.pdf')
|
62
62
|
pdf.save '06_check_links_to_second_copy.pdf'
|
63
63
|
|
64
|
-
lists = %w(
|
64
|
+
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
65
|
|
66
66
|
i = 0
|
67
67
|
lists.each do |n|
|
@@ -92,19 +92,19 @@ pdf.number_pages(start_at: 1,
|
|
92
92
|
|
93
93
|
pdf.save('07_named destinations_numbered.pdf')
|
94
94
|
|
95
|
-
CombinePDF.load("
|
96
|
-
CombinePDF.load("
|
97
|
-
CombinePDF.load("
|
98
|
-
CombinePDF.load("
|
99
|
-
CombinePDF.load("
|
95
|
+
CombinePDF.load("../../test\ pdfs/Scribus-unknown_err.pdf").save '08_1-unknown-err-empty-str.pdf'
|
96
|
+
CombinePDF.load("../../test\ pdfs/Scribus-unknown_err2.pdf").save '08_2-unknown-err-empty-str.pdf'
|
97
|
+
CombinePDF.load("../../test\ pdfs/Scribus-unknown_err3.pdf").save '08_3-unknown-err-empty-str.pdf'
|
98
|
+
CombinePDF.load("../../test\ pdfs/xref_in_middle.pdf").save '08_4-xref-in-middle.pdf'
|
99
|
+
CombinePDF.load("../../test\ pdfs/xref_split.pdf").save '08_5-xref-fragmented.pdf'
|
100
100
|
|
101
|
-
CombinePDF.load("
|
101
|
+
CombinePDF.load("../../test\ pdfs/nil_object.pdf").save('09_nil_in_parsed_array.pdf')
|
102
102
|
|
103
|
-
encrypted = [ "
|
104
|
-
"
|
105
|
-
"
|
106
|
-
"
|
107
|
-
"
|
103
|
+
encrypted = [ "../../test\ pdfs/pdf-reader/encrypted_version4_revision4_128bit_aes_user_pass_apples_enc_metadata.pdf",
|
104
|
+
"../../test\ pdfs/AESv2\ encrypted.pdf",
|
105
|
+
"../../test\ pdfs/pdf-reader/encrypted_version2_revision3_128bit_rc4_blank_user_pass.pdf",
|
106
|
+
"../../test\ pdfs/AES\ enc.pdf",
|
107
|
+
"../../test\ pdfs/RC4\ enc.pdf"]
|
108
108
|
|
109
109
|
encrypted.length.times do |i|
|
110
110
|
fname = File.basename encrypted[i]
|
@@ -132,17 +132,17 @@ pdf.save('11_AcrobatReader_is_unique_page.pdf')
|
|
132
132
|
|
133
133
|
puts GC.stat.inspect
|
134
134
|
# unify = [
|
135
|
-
# "
|
136
|
-
# "
|
137
|
-
# "
|
138
|
-
# "
|
139
|
-
# "
|
140
|
-
# "
|
141
|
-
# "
|
142
|
-
# "
|
143
|
-
# "
|
144
|
-
# "
|
145
|
-
# "
|
135
|
+
# "../../test\ pdfs/AESv2\ encrypted.pdf",
|
136
|
+
# "../../test\ pdfs/data-in-comment.pdf",
|
137
|
+
# "../../test\ pdfs/file_name.pdf",
|
138
|
+
# "../../test\ pdfs/garbage_after_eof.pdf",
|
139
|
+
# "../../test\ pdfs/Many\ comments.pdf",
|
140
|
+
# "../../test\ pdfs/nested\ contents\ array.PDF",
|
141
|
+
# "../../test\ pdfs/nested_resources.pdf",
|
142
|
+
# "../../test\ pdfs/original-missing-endobje.pdf",
|
143
|
+
# "../../test\ pdfs/original-multi-issue.pdf",
|
144
|
+
# "../../test\ pdfs/page_stap_nil_secure.pdf",
|
145
|
+
# "../../test\ pdfs/referenced\ decryption.pdf",
|
146
146
|
# '',
|
147
147
|
# '',
|
148
148
|
# '',
|
@@ -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.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-rc4
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.1.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: matrix
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
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'
|
55
83
|
description: A nifty gem, in pure Ruby, to parse PDF files and combine (merge) them
|
56
84
|
with other PDF files, number the pages, watermark them or stamp them, create tables,
|
57
85
|
add basic text objects etc` (all using the PDF file format).
|
@@ -62,6 +90,7 @@ extensions: []
|
|
62
90
|
extra_rdoc_files: []
|
63
91
|
files:
|
64
92
|
- ".gitignore"
|
93
|
+
- ".travis.yml"
|
65
94
|
- CHANGELOG.md
|
66
95
|
- Gemfile
|
67
96
|
- LICENSE.txt
|
@@ -82,14 +111,17 @@ files:
|
|
82
111
|
- lib/combine_pdf/renderer.rb
|
83
112
|
- lib/combine_pdf/version.rb
|
84
113
|
- test/automated
|
114
|
+
- test/combine_pdf/load_test.rb
|
85
115
|
- test/combine_pdf/renderer_test.rb
|
86
116
|
- test/console
|
117
|
+
- test/fixtures/files/sample_encrypted_pdf.pdf
|
118
|
+
- test/fixtures/files/sample_pdf.pdf
|
87
119
|
- test/named_dest
|
88
120
|
homepage: https://github.com/boazsegev/combine_pdf
|
89
121
|
licenses:
|
90
122
|
- MIT
|
91
123
|
metadata: {}
|
92
|
-
post_install_message:
|
124
|
+
post_install_message:
|
93
125
|
rdoc_options: []
|
94
126
|
require_paths:
|
95
127
|
- lib
|
@@ -104,12 +136,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
136
|
- !ruby/object:Gem::Version
|
105
137
|
version: '0'
|
106
138
|
requirements: []
|
107
|
-
rubygems_version: 3.
|
108
|
-
signing_key:
|
139
|
+
rubygems_version: 3.3.26
|
140
|
+
signing_key:
|
109
141
|
specification_version: 4
|
110
142
|
summary: Combine, stamp and watermark PDF files in pure Ruby.
|
111
143
|
test_files:
|
112
144
|
- test/automated
|
145
|
+
- test/combine_pdf/load_test.rb
|
113
146
|
- test/combine_pdf/renderer_test.rb
|
114
147
|
- test/console
|
148
|
+
- test/fixtures/files/sample_encrypted_pdf.pdf
|
149
|
+
- test/fixtures/files/sample_pdf.pdf
|
115
150
|
- test/named_dest
|