combine_pdf 1.0.13 → 1.0.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +2 -0
- data/combine_pdf.gemspec +2 -2
- data/lib/combine_pdf.rb +1 -0
- data/lib/combine_pdf/api.rb +1 -1
- data/lib/combine_pdf/fonts.rb +1 -1
- data/lib/combine_pdf/page_methods.rb +8 -8
- data/lib/combine_pdf/parser.rb +28 -2
- data/lib/combine_pdf/pdf_protected.rb +41 -11
- data/lib/combine_pdf/pdf_public.rb +4 -4
- data/lib/combine_pdf/version.rb +1 -1
- metadata +7 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95f44419c731c5b1e7625589d159c608ab6948004e347db9ee2380611e10dd6f
|
4
|
+
data.tar.gz: d2ee8cf53e111cdf4051886262ad2a4fa216eca36aaaf1b45b7782379f793642
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cac17e8c080e0eba10f19efa90c5eb6252f12811218ff5ad8f330ec8977abec677628d6cfaf70d9abc5e2b754e711e9024315cad0de2f32286f1d7dbeabec87
|
7
|
+
data.tar.gz: 7e60b19afafa071a6d21ce73da4be142501c0becc4aede5e579706789d0c276903a8193661d0ffa16d0c4c906d0fa6136124011d1de3a8c968a3c1334804d476
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,26 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
#### Change log v.1.0.18
|
6
|
+
|
7
|
+
**Fix**: fixed issue with the 1.0.17 release where `ProcSet` PDF Arrays should have been expected but where ignored and a PDF Object was assumed instead (issue #171) - credit to @chuchiperriman (Jesús Barbero Rodríguez).
|
8
|
+
|
9
|
+
#### Change log v.1.0.17
|
10
|
+
|
11
|
+
**Fix**: fixed issue where nested structure equality tests might provide false positives, resulting in lost data (issue #166) - credit to @cschilbe (Conrad Schilbe).
|
12
|
+
|
13
|
+
#### Change log v.1.0.16
|
14
|
+
|
15
|
+
**Fix**: some documentation typos were fixed (PR #147) - credit to @djhopper01 (Derek Hopper).
|
16
|
+
|
17
|
+
#### Change log v.1.0.15
|
18
|
+
|
19
|
+
**Fix**: An attempt to fix JRuby compatibility concerns (issue #127).
|
20
|
+
|
21
|
+
#### Change log v.1.0.14
|
22
|
+
|
23
|
+
**Fix**: Fixed an issue related to PDF XRef table data, where a malformed EOL marker would cause the parser to fail. Credit to @dangerous (David Rainsford) for exposing this issue in a comment to issue #140.
|
24
|
+
|
5
25
|
#### Change log v.1.0.13
|
6
26
|
|
7
27
|
**Fix**: Fixed an issue related to PDF object streams (version 1.6) where a numerical object at the beginning of the stream might be mis-parsed as an object reference number rather than an object. Credit to @Defoncesko for reporting issue #141.
|
data/README.md
CHANGED
@@ -41,6 +41,8 @@ Quick rundown:
|
|
41
41
|
|
42
42
|
* 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)`.
|
43
43
|
|
44
|
+
* The CombinePDF gem runs recursive code to both parse and format the PDF files. Hence, PDF files that have heavily nested objects, as well as those that where combined in a way that results in cyclic nesting, might explode the stack - resulting in an exception or program failure.
|
45
|
+
|
44
46
|
CombinePDF is written natively in Ruby and should (presumably) work on all Ruby platforms that follow Ruby 2.0 compatibility.
|
45
47
|
|
46
48
|
However, PDF files are quite complex creatures and no guaranty is provided.
|
data/combine_pdf.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_runtime_dependency 'ruby-rc4', '>= 0.1.5'
|
22
22
|
|
23
|
-
spec.add_development_dependency "bundler", "
|
24
|
-
spec.add_development_dependency "rake", "
|
23
|
+
# spec.add_development_dependency "bundler", ">= 1.7"
|
24
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
25
25
|
spec.add_development_dependency "minitest"
|
26
26
|
end
|
data/lib/combine_pdf.rb
CHANGED
data/lib/combine_pdf/api.rb
CHANGED
@@ -140,7 +140,7 @@ module CombinePDF
|
|
140
140
|
# this function enables plug-ins to expend the font functionality of CombinePDF.
|
141
141
|
#
|
142
142
|
# font_name:: a Symbol with the name of the font. if the fonts exists in the library, it will be overwritten!
|
143
|
-
# font_metrics:: a Hash of font metrics, of the format char => {wx: char_width, boundingbox: [left_x,
|
143
|
+
# font_metrics:: a Hash of font metrics, of the format char => {wx: char_width, boundingbox: [left_x, bottom_y, right_x, top_y]} where char == character itself (i.e. " " for space). The Hash should contain a special value :missing for the metrics of missing characters. an optional :wy might be supported in the future, for up to down fonts.
|
144
144
|
# font_pdf_object:: a Hash in the internal format recognized by CombinePDF, that represents the font object.
|
145
145
|
# font_cmap:: a CMap dictionary Hash) which maps unicode characters to the hex CID for the font (i.e. {"a" => "61", "z" => "7a" }).
|
146
146
|
def register_font(font_name, font_metrics, font_pdf_object, font_cmap = nil)
|
data/lib/combine_pdf/fonts.rb
CHANGED
@@ -100,7 +100,7 @@ module CombinePDF
|
|
100
100
|
|
101
101
|
# adds a correctly formatted font object to the font library.
|
102
102
|
# font_name:: a Symbol with the name of the font. if the fonts name exists, the font will be overwritten!
|
103
|
-
# font_metrics:: a Hash of ont metrics, of the format char => {wx: char_width, boundingbox: [left_x,
|
103
|
+
# font_metrics:: a Hash of ont metrics, of the format char => {wx: char_width, boundingbox: [left_x, bottom_y, right_x, top_y]} where i == character code (i.e. 32 for space). The Hash should contain a special value :missing for the metrics of missing characters. an optional :wy will be supported in the future, for up to down fonts.
|
104
104
|
# font_pdf_object:: a Hash in the internal format recognized by CombinePDF, that represents the font object.
|
105
105
|
# font_cmap:: a CMap dictionary Hash) which maps unicode characters to the hex CID for the font (i.e. {"a" => "61", "z" => "7a" }).
|
106
106
|
def register_font(font_name, font_metrics, font_pdf_object, font_cmap = nil)
|
@@ -94,7 +94,7 @@ module CombinePDF
|
|
94
94
|
# end
|
95
95
|
|
96
96
|
# set ProcSet to recommended value
|
97
|
-
resources[:ProcSet]
|
97
|
+
resources[:ProcSet] ||= [:PDF, :Text, :ImageB, :ImageC, :ImageI] # this was recommended by the ISO. 32000-1:2008
|
98
98
|
|
99
99
|
if top # if this is a stamp (overlay)
|
100
100
|
insert_content CONTENT_CONTAINER_START, 0
|
@@ -147,15 +147,15 @@ module CombinePDF
|
|
147
147
|
|
148
148
|
# This method adds a simple text box to the Page represented by the PDFWriter class.
|
149
149
|
# This function takes two values:
|
150
|
-
# text:: the text to
|
150
|
+
# text:: the text to write in the box.
|
151
151
|
# properties:: a Hash of box properties.
|
152
152
|
# the symbols and values in the properties Hash could be any or all of the following:
|
153
153
|
# x:: the left position of the box.
|
154
|
-
# y:: the
|
154
|
+
# y:: the BOTTOM position of the box.
|
155
155
|
# width:: the width/length of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
|
156
156
|
# height:: the height of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
|
157
157
|
# text_align:: symbol for horizontal text alignment, can be ":center" (default), ":right", ":left"
|
158
|
-
# text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ":
|
158
|
+
# text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ":bottom"
|
159
159
|
# text_padding:: a Float between 0 and 1, setting the padding for the text. defaults to 0.05 (5%).
|
160
160
|
# font:: a registered font name or an Array of names. defaults to ":Helvetica". The 14 standard fonts names are:
|
161
161
|
# - :"Times-Roman"
|
@@ -244,8 +244,8 @@ module CombinePDF
|
|
244
244
|
half_radius = (radius.to_f / 2).round 4
|
245
245
|
## set starting point
|
246
246
|
box_stream << "#{options[:x] + radius} #{options[:y]} m\n"
|
247
|
-
##
|
248
|
-
box_stream << "#{options[:x] + options[:width] - radius} #{options[:y]} l\n" #
|
247
|
+
## bottom and right corner - first line and first corner
|
248
|
+
box_stream << "#{options[:x] + options[:width] - radius} #{options[:y]} l\n" # bottom
|
249
249
|
if options[:box_radius] != 0 # make first corner, if not straight.
|
250
250
|
box_stream << "#{options[:x] + options[:width] - half_radius} #{options[:y]} "
|
251
251
|
box_stream << "#{options[:x] + options[:width]} #{options[:y] + half_radius} "
|
@@ -265,7 +265,7 @@ module CombinePDF
|
|
265
265
|
box_stream << "#{options[:x]} #{options[:y] + options[:height] - half_radius} "
|
266
266
|
box_stream << "#{options[:x]} #{options[:y] + options[:height] - radius} c\n"
|
267
267
|
end
|
268
|
-
## left and
|
268
|
+
## left and bottom-left corner
|
269
269
|
box_stream << "#{options[:x]} #{options[:y] + radius} l\n"
|
270
270
|
if options[:box_radius] != 0
|
271
271
|
box_stream << "#{options[:x]} #{options[:y] + half_radius} "
|
@@ -287,7 +287,7 @@ module CombinePDF
|
|
287
287
|
end
|
288
288
|
contents << box_stream
|
289
289
|
|
290
|
-
# reset x,y by text alignment - x,y are calculated from the
|
290
|
+
# reset x,y by text alignment - x,y are calculated from the bottom left
|
291
291
|
# each unit (1) is 1/72 Inch
|
292
292
|
# create text stream
|
293
293
|
text_stream = ''
|
data/lib/combine_pdf/parser.rb
CHANGED
@@ -233,16 +233,18 @@ module CombinePDF
|
|
233
233
|
# all characters that aren't white space or special: /[^\x00\x09\x0a\x0c\x0d\x20\x28\x29\x3c\x3e\x5b\x5d\x7b\x7d\x2f\x25]+
|
234
234
|
elsif str = @scanner.scan(/\/[^\x00\x09\x0a\x0c\x0d\x20\x28\x29\x3c\x3e\x5b\x5d\x7b\x7d\x2f\x25]*/)
|
235
235
|
out << (str[1..-1].gsub(/\#[0-9a-fA-F]{2}/) { |a| a[1..2].hex.chr }).to_sym
|
236
|
+
# warn "CombinePDF detected name: #{out.last.to_s}"
|
236
237
|
##########################################
|
237
238
|
## Parse a Number
|
238
239
|
##########################################
|
239
240
|
elsif str = @scanner.scan(/[\+\-\.\d]+/)
|
240
241
|
str =~ /\./ ? (out << str.to_f) : (out << str.to_i)
|
242
|
+
# warn "CombinePDF detected number: #{out.last.to_s}"
|
241
243
|
##########################################
|
242
244
|
## parse a Hex String
|
243
245
|
##########################################
|
244
246
|
elsif str = @scanner.scan(/\<[0-9a-fA-F]*\>/)
|
245
|
-
# warn "Found a hex string"
|
247
|
+
# warn "Found a hex string #{str}"
|
246
248
|
str = str.slice(1..-2).force_encoding(Encoding::ASCII_8BIT)
|
247
249
|
# str = "0#{str}" if str.length.odd?
|
248
250
|
out << unify_string([str].pack('H*').force_encoding(Encoding::ASCII_8BIT))
|
@@ -336,6 +338,7 @@ module CombinePDF
|
|
336
338
|
end
|
337
339
|
end
|
338
340
|
out << unify_string(str.pack('C*').force_encoding(Encoding::ASCII_8BIT))
|
341
|
+
# warn "Found Literal String: #{out.last}"
|
339
342
|
##########################################
|
340
343
|
## parse a Dictionary
|
341
344
|
##########################################
|
@@ -348,6 +351,7 @@ module CombinePDF
|
|
348
351
|
## return content of array or dictionary
|
349
352
|
##########################################
|
350
353
|
elsif @scanner.scan(/\]/) || @scanner.scan(/>>/)
|
354
|
+
# warn "Dictionary / Array ended with #{@scanner.peek(5)}"
|
351
355
|
return out
|
352
356
|
##########################################
|
353
357
|
## parse a Stream
|
@@ -364,6 +368,8 @@ module CombinePDF
|
|
364
368
|
raise ParsingError, "Parsing Error: PDF file error - a stream object wasn't properly closed using 'endstream'!"
|
365
369
|
end
|
366
370
|
|
371
|
+
# warn "CombinePDF parser: detected Stream #{str.length} bytes long #{str[0..3]}...#{str[-4..-1]}"
|
372
|
+
|
367
373
|
# need to remove end of stream
|
368
374
|
if out.last.is_a? Hash
|
369
375
|
# out.last[:raw_stream_content] = str[0...-10] #cuts only one EON char (\n or \r)
|
@@ -418,7 +424,7 @@ module CombinePDF
|
|
418
424
|
##########################################
|
419
425
|
elsif @scanner.scan(/xref/)
|
420
426
|
# skip list indetifier lines or list lines ([\d] [\d][\r\n]) ot ([\d] [\d] [nf][\r\n])
|
421
|
-
while @scanner.scan(/[\s]*[\d]+[ \t]+[\d]+[ \t
|
427
|
+
while @scanner.scan(/[\s]*[\d]+[ \t]+[\d]+[ \t]*[\n\r]+/) || @scanner.scan(/[ \t]*[\d]+[ \t]+[\d]+[ \t]+[nf][\s]*/)
|
422
428
|
nil
|
423
429
|
end
|
424
430
|
##########################################
|
@@ -528,6 +534,14 @@ module CombinePDF
|
|
528
534
|
inheritance_hash[:Resources] ||= { referenced_object: {}, is_reference_only: true }.dup
|
529
535
|
(inheritance_hash[:Resources][:referenced_object] || inheritance_hash[:Resources]).update((catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &HASH_UPDATE_PROC_FOR_OLD)
|
530
536
|
end
|
537
|
+
if catalogs[:ProcSet].is_a?(Array)
|
538
|
+
if(inheritance_hash[:ProcSet])
|
539
|
+
inheritance_hash[:ProcSet][:referenced_object].concat(catalogs[:ProcSet])
|
540
|
+
inheritance_hash[:ProcSet][:referenced_object].uniq!
|
541
|
+
else
|
542
|
+
inheritance_hash[:ProcSet] ||= { referenced_object: catalogs[:ProcSet], is_reference_only: true }.dup
|
543
|
+
end
|
544
|
+
end
|
531
545
|
if catalogs[:ColorSpace]
|
532
546
|
inheritance_hash[:ColorSpace] ||= { referenced_object: {}, is_reference_only: true }.dup
|
533
547
|
(inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]).update((catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
|
@@ -556,6 +570,18 @@ module CombinePDF
|
|
556
570
|
catalogs[:ColorSpace] = { referenced_object: catalogs[:ColorSpace], is_reference_only: true } unless catalogs[:ColorSpace][:referenced_object]
|
557
571
|
catalogs[:ColorSpace][:referenced_object].update((inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
|
558
572
|
end
|
573
|
+
if inheritance_hash[:ProcSet]
|
574
|
+
if(catalogs[:ProcSet])
|
575
|
+
if catalogs[:ProcSet].is_a?(Array)
|
576
|
+
catalogs[:ProcSet] = { referenced_object: catalogs[:ProcSet], is_reference_only: true }
|
577
|
+
end
|
578
|
+
catalogs[:ProcSet][:referenced_object].concat(inheritance_hash[:ProcSet][:referenced_object])
|
579
|
+
catalogs[:ProcSet][:referenced_object].uniq!
|
580
|
+
else
|
581
|
+
catalogs[:ProcSet] = { is_reference_only: true }.dup
|
582
|
+
catalogs[:ProcSet][:referenced_object] = catalogs[:ProcSet][:referenced_object].dup
|
583
|
+
end
|
584
|
+
end
|
559
585
|
# (catalogs[:ColorSpace] ||= {}).update(inheritance_hash[:ColorSpace], &HASH_UPDATE_PROC_FOR_OLD) if inheritance_hash[:ColorSpace]
|
560
586
|
# catalogs[:Order] ||= inheritance_hash[:Order] if inheritance_hash[:Order]
|
561
587
|
# catalogs[:AS] ||= inheritance_hash[:AS] if inheritance_hash[:AS]
|
@@ -232,15 +232,42 @@ module CombinePDF
|
|
232
232
|
# @private
|
233
233
|
# this method reviews a Hash and updates it by merging Hash data,
|
234
234
|
# preffering the new over the old.
|
235
|
-
def self.hash_merge_new_no_page(_key, old_data, new_data)
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
235
|
+
# def self.hash_merge_new_no_page(_key = nil, old_data = nil, new_data = nil)
|
236
|
+
# return old_data unless new_data
|
237
|
+
# return new_data unless old_data
|
238
|
+
# if old_data.is_a?(Hash) && new_data.is_a?(Hash)
|
239
|
+
# return old_data if (old_data[:Type] == :Page)
|
240
|
+
# old_data.merge(new_data, &(@hash_merge_new_no_page_proc ||= method(:hash_merge_new_no_page)))
|
241
|
+
# elsif old_data.is_a? Array
|
242
|
+
# return old_data + new_data if new_data.is_a?(Array)
|
243
|
+
# return old_data.dup << new_data
|
244
|
+
# elsif new_data.is_a? Array
|
245
|
+
# new_data + [old_data]
|
246
|
+
# else
|
247
|
+
# new_data
|
248
|
+
# end
|
249
|
+
# end
|
250
|
+
|
251
|
+
# @private
|
252
|
+
# JRuby Alternative this method reviews a Hash and updates it by merging Hash data,
|
253
|
+
# preffering the new over the old.
|
254
|
+
HASH_MERGE_NEW_NO_PAGE = Proc.new do |_key = nil, old_data = nil, new_data = nil|
|
255
|
+
if !new_data
|
256
|
+
old_data
|
257
|
+
elsif !old_data
|
258
|
+
new_data
|
259
|
+
elsif old_data.is_a?(Hash) && new_data.is_a?(Hash)
|
260
|
+
if (old_data[:Type] == :Page)
|
261
|
+
old_data
|
262
|
+
else
|
263
|
+
old_data.merge(new_data, &HASH_MERGE_NEW_NO_PAGE)
|
264
|
+
end
|
241
265
|
elsif old_data.is_a? Array
|
242
|
-
|
243
|
-
|
266
|
+
if new_data.is_a?(Array)
|
267
|
+
old_data + new_data
|
268
|
+
else
|
269
|
+
old_data.dup << new_data
|
270
|
+
end
|
244
271
|
elsif new_data.is_a? Array
|
245
272
|
new_data + [old_data]
|
246
273
|
else
|
@@ -346,16 +373,19 @@ module CombinePDF
|
|
346
373
|
private
|
347
374
|
|
348
375
|
def equal_layers obj1, obj2, layer = CombinePDF.eq_depth_limit
|
349
|
-
return true if(layer == 0)
|
350
376
|
return true if obj1.object_id == obj2.object_id
|
351
377
|
if obj1.is_a? Hash
|
352
378
|
return false unless obj2.is_a? Hash
|
379
|
+
return false unless obj1.length == obj2.length
|
353
380
|
keys = obj1.keys;
|
354
|
-
|
381
|
+
keys2 = obj2.keys;
|
382
|
+
return false if (keys - keys2).any? || (keys2 - keys).any?
|
383
|
+
return (warn("CombinePDF nesting limit reached") || true) if(layer == 0)
|
355
384
|
keys.each {|k| return false unless equal_layers( obj1[k], obj2[k], layer-1) }
|
356
385
|
elsif obj1.is_a? Array
|
357
386
|
return false unless obj2.is_a? Array
|
358
|
-
|
387
|
+
return false unless obj1.length == obj2.length
|
388
|
+
(obj1-obj2).any? || (obj2-obj1).any?
|
359
389
|
else
|
360
390
|
obj1 == obj2
|
361
391
|
end
|
@@ -306,10 +306,10 @@ module CombinePDF
|
|
306
306
|
if data.is_a? PDF
|
307
307
|
@version = [@version, data.version].max
|
308
308
|
pages_to_add = data.pages
|
309
|
-
actual_value(@names ||= {}.dup).update data.names, &
|
309
|
+
actual_value(@names ||= {}.dup).update data.names, &HASH_MERGE_NEW_NO_PAGE
|
310
310
|
merge_outlines((@outlines ||= {}.dup), actual_value(data.outlines), location) unless actual_value(data.outlines).empty?
|
311
311
|
if actual_value(@forms_data)
|
312
|
-
actual_value(@forms_data).update actual_value(data.forms_data), &
|
312
|
+
actual_value(@forms_data).update actual_value(data.forms_data), &HASH_MERGE_NEW_NO_PAGE if data.forms_data
|
313
313
|
else
|
314
314
|
@forms_data = data.forms_data
|
315
315
|
end
|
@@ -358,9 +358,9 @@ module CombinePDF
|
|
358
358
|
#
|
359
359
|
# options:: a Hash of options setting the behavior and format of the page numbers:
|
360
360
|
# - :number_format a string representing the format for page number. defaults to ' - %s - ' (allows for letter numbering as well, such as "a", "b"...).
|
361
|
-
# - :location an Array containing the location for the page numbers, can be :top, :
|
361
|
+
# - :location an Array containing the location for the page numbers, can be :top, :bottom, :top_left, :top_right, :bottom_left, :bottom_right or :center (:center == full page). defaults to [:top, :bottom].
|
362
362
|
# - :start_at an Integer that sets the number for first page number. also accepts a letter ("a") for letter numbering. defaults to 1.
|
363
|
-
# - :margin_from_height a number (PDF points) for the top and
|
363
|
+
# - :margin_from_height a number (PDF points) for the top and bottom margins. defaults to 45.
|
364
364
|
# - :margin_from_side a number (PDF points) for the left and right margins. defaults to 15.
|
365
365
|
# - :page_range a range of pages to be numbered (i.e. (2..-1) ) defaults to all the pages (nil). Remember to set the :start_at to the correct value.
|
366
366
|
# the options Hash can also take all the options for {Page_Methods#textbox}.
|
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: 1.0.
|
4
|
+
version: 1.0.18
|
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: 2020-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-rc4
|
@@ -24,34 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.1.5
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.7'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.7'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- - "
|
31
|
+
- - ">="
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
33
|
+
version: 12.3.3
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- - "
|
38
|
+
- - ">="
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
40
|
+
version: 12.3.3
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: minitest
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
104
|
- !ruby/object:Gem::Version
|
119
105
|
version: '0'
|
120
106
|
requirements: []
|
121
|
-
|
122
|
-
rubygems_version: 2.7.6
|
107
|
+
rubygems_version: 3.1.2
|
123
108
|
signing_key:
|
124
109
|
specification_version: 4
|
125
110
|
summary: Combine, stamp and watermark PDF files in pure Ruby.
|