origamindee 3.0.0 → 3.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/bin/shell/console.rb +128 -128
- data/lib/origami/page.rb +130 -34
- data/lib/origami/version.rb +3 -1
- data/test/dataset/3_pages.pdf +0 -0
- data/test/dataset/image_only.pdf +0 -0
- data/test/dataset/invoice.pdf +0 -0
- data/test/test_pages.rb +25 -2
- data/test/test_pdf_parse.rb +3 -10
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40b6702a0d5d7660322722b8a4a14ca8cf216cebe42aaebeb7355d41a66bd83a
|
|
4
|
+
data.tar.gz: 3c33400d7d5b8db653770eb1d1ca4d8e2ee5919267b3089b12ca02b6f4d889f7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e7395d76443c6ad6a354f291eb0d3a02b898dc39d448144558fbbf755bb2fc01cd9bb4dd12724ba7d315f14f401588bab1a2036c2c00e392b6fd51556c51b3f
|
|
7
|
+
data.tar.gz: 5e18ca5e74f693c424c206ff92d786346dab5162687ee012646359147858968c218db24ca8832be6d3cb50fb2b6ed90352306b2c5230e4a67eb2399bd617a7b4
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Origami is able to parse PDF, FDF and PPKLite (Adobe certificate store) files.
|
|
|
27
27
|
|
|
28
28
|
Requirements
|
|
29
29
|
------------
|
|
30
|
-
The following Ruby versions are tested and supported: 2.6, 2.7, 3.0, 3.1
|
|
30
|
+
The following Ruby versions are tested and supported: 2.6, 2.7, 3.0, 3.1, 3.2
|
|
31
31
|
|
|
32
32
|
Some optional features require additional gems:
|
|
33
33
|
|
data/bin/shell/console.rb
CHANGED
|
@@ -1,128 +1,128 @@
|
|
|
1
|
-
=begin
|
|
2
|
-
|
|
3
|
-
This file is part of Origami, PDF manipulation framework for Ruby
|
|
4
|
-
Copyright (C) 2016 Guillaume Delugré.
|
|
5
|
-
|
|
6
|
-
Origami is free software: you can redistribute it and/or modify
|
|
7
|
-
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
-
(at your option) any later version.
|
|
10
|
-
|
|
11
|
-
Origami is distributed in the hope that it will be useful,
|
|
12
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
-
GNU Lesser General Public License for more details.
|
|
15
|
-
|
|
16
|
-
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
-
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
-
|
|
19
|
-
=end
|
|
20
|
-
|
|
21
|
-
require 'tempfile'
|
|
22
|
-
require 'hexdump'
|
|
23
|
-
require 'colorize'
|
|
24
|
-
|
|
25
|
-
String.disable_colorization(false)
|
|
26
|
-
|
|
27
|
-
module Origami
|
|
28
|
-
module Object
|
|
29
|
-
def inspect
|
|
30
|
-
to_s
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class Stream
|
|
35
|
-
def edit(editor = ENV['EDITOR'])
|
|
36
|
-
Tempfile.open("origami") do |tmpfile|
|
|
37
|
-
tmpfile.write(self.data)
|
|
38
|
-
tmpfile.flush
|
|
39
|
-
|
|
40
|
-
Process.wait Kernel.spawn "#{editor} #{tmpfile.path}"
|
|
41
|
-
|
|
42
|
-
self.data = File.read(tmpfile.path)
|
|
43
|
-
tmpfile.unlink
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
true
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def inspect
|
|
50
|
-
self.data.hexdump
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
class Page < Dictionary
|
|
55
|
-
def edit
|
|
56
|
-
each_content_stream do |stream|
|
|
57
|
-
stream.edit
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
class PDF
|
|
63
|
-
if defined?(PDF::JavaScript::Engine)
|
|
64
|
-
class JavaScript::Engine
|
|
65
|
-
def shell
|
|
66
|
-
loop do
|
|
67
|
-
print "js > ".magenta
|
|
68
|
-
break if (line = gets).nil?
|
|
69
|
-
|
|
70
|
-
begin
|
|
71
|
-
puts exec(line)
|
|
72
|
-
rescue V8::JSError => e
|
|
73
|
-
puts "Error: #{e.message}"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
class Revision
|
|
81
|
-
def to_s
|
|
82
|
-
puts "---------- Body ----------".white.bold
|
|
83
|
-
@body.each_value do |obj|
|
|
84
|
-
print "#{obj.reference.to_s.rjust(8,' ')}".ljust(10).magenta
|
|
85
|
-
puts "#{obj.type}".yellow
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
puts "---------- Trailer ---------".white.bold
|
|
89
|
-
if not @trailer.dictionary
|
|
90
|
-
puts " [x] No trailer found.".blue
|
|
91
|
-
else
|
|
92
|
-
@trailer.dictionary.each_pair do |entry, value|
|
|
93
|
-
print " [*] ".magenta
|
|
94
|
-
print "#{entry}: ".yellow
|
|
95
|
-
puts "#{value}".red
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
print " [+] ".magenta
|
|
99
|
-
print "startxref: ".yellow
|
|
100
|
-
puts "#{@trailer.startxref}".red
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def inspect
|
|
105
|
-
to_s
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def to_s
|
|
110
|
-
puts
|
|
111
|
-
|
|
112
|
-
puts "---------- Header ----------".white.bold
|
|
113
|
-
print " [+] ".magenta
|
|
114
|
-
print "Version: ".yellow
|
|
115
|
-
puts "#{@header.major_version}.#{@header.minor_version}".red
|
|
116
|
-
|
|
117
|
-
@revisions.each do |revision|
|
|
118
|
-
revision.to_s
|
|
119
|
-
end
|
|
120
|
-
puts
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def inspect
|
|
124
|
-
to_s
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
end
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
|
5
|
+
|
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Lesser General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
=end
|
|
20
|
+
|
|
21
|
+
require 'tempfile'
|
|
22
|
+
require 'hexdump'
|
|
23
|
+
require 'colorize'
|
|
24
|
+
|
|
25
|
+
String.disable_colorization(false)
|
|
26
|
+
|
|
27
|
+
module Origami
|
|
28
|
+
module Object
|
|
29
|
+
def inspect
|
|
30
|
+
to_s
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class Stream
|
|
35
|
+
def edit(editor = ENV['EDITOR'])
|
|
36
|
+
Tempfile.open("origami") do |tmpfile|
|
|
37
|
+
tmpfile.write(self.data)
|
|
38
|
+
tmpfile.flush
|
|
39
|
+
|
|
40
|
+
Process.wait Kernel.spawn "#{editor} #{tmpfile.path}"
|
|
41
|
+
|
|
42
|
+
self.data = File.read(tmpfile.path)
|
|
43
|
+
tmpfile.unlink
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def inspect
|
|
50
|
+
self.data.hexdump
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class Page < Dictionary
|
|
55
|
+
def edit
|
|
56
|
+
each_content_stream do |stream|
|
|
57
|
+
stream.edit
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class PDF
|
|
63
|
+
if defined?(PDF::JavaScript::Engine)
|
|
64
|
+
class JavaScript::Engine
|
|
65
|
+
def shell
|
|
66
|
+
loop do
|
|
67
|
+
print "js > ".magenta
|
|
68
|
+
break if (line = gets).nil?
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
puts exec(line)
|
|
72
|
+
rescue V8::JSError => e
|
|
73
|
+
puts "Error: #{e.message}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class Revision
|
|
81
|
+
def to_s
|
|
82
|
+
puts "---------- Body ----------".white.bold
|
|
83
|
+
@body.each_value do |obj|
|
|
84
|
+
print "#{obj.reference.to_s.rjust(8,' ')}".ljust(10).magenta
|
|
85
|
+
puts "#{obj.type}".yellow
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
puts "---------- Trailer ---------".white.bold
|
|
89
|
+
if not @trailer.dictionary
|
|
90
|
+
puts " [x] No trailer found.".blue
|
|
91
|
+
else
|
|
92
|
+
@trailer.dictionary.each_pair do |entry, value|
|
|
93
|
+
print " [*] ".magenta
|
|
94
|
+
print "#{entry}: ".yellow
|
|
95
|
+
puts "#{value}".red
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
print " [+] ".magenta
|
|
99
|
+
print "startxref: ".yellow
|
|
100
|
+
puts "#{@trailer.startxref}".red
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def inspect
|
|
105
|
+
to_s
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def to_s
|
|
110
|
+
puts
|
|
111
|
+
|
|
112
|
+
puts "---------- Header ----------".white.bold
|
|
113
|
+
print " [+] ".magenta
|
|
114
|
+
print "Version: ".yellow
|
|
115
|
+
puts "#{@header.major_version}.#{@header.minor_version}".red
|
|
116
|
+
|
|
117
|
+
@revisions.each do |revision|
|
|
118
|
+
revision.to_s
|
|
119
|
+
end
|
|
120
|
+
puts
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def inspect
|
|
124
|
+
to_s
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
data/lib/origami/page.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
=begin
|
|
2
4
|
|
|
3
5
|
This file is part of Origami, PDF manipulation framework for Ruby
|
|
@@ -57,6 +59,28 @@ module Origami
|
|
|
57
59
|
self
|
|
58
60
|
end
|
|
59
61
|
|
|
62
|
+
#
|
|
63
|
+
# Deletes a page at position _index_ from the document.
|
|
64
|
+
# _index_:: Page index (starting from one).
|
|
65
|
+
#
|
|
66
|
+
def delete_page_at(index)
|
|
67
|
+
init_page_tree
|
|
68
|
+
|
|
69
|
+
self.Catalog.Pages.delete_page_at(index)
|
|
70
|
+
self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Deletes a page at position _index_ from the document.
|
|
75
|
+
# _index_:: Page index (starting from one).
|
|
76
|
+
#
|
|
77
|
+
def delete_pages_at(delete_idx)
|
|
78
|
+
init_page_tree
|
|
79
|
+
|
|
80
|
+
self.Catalog.Pages.delete_pages_at(delete_idx)
|
|
81
|
+
self
|
|
82
|
+
end
|
|
83
|
+
|
|
60
84
|
#
|
|
61
85
|
# Returns an Enumerator of Page
|
|
62
86
|
#
|
|
@@ -107,7 +131,7 @@ module Origami
|
|
|
107
131
|
end
|
|
108
132
|
|
|
109
133
|
unless self.Catalog.Pages.is_a?(PageTreeNode)
|
|
110
|
-
raise InvalidPageTreeError,
|
|
134
|
+
raise InvalidPageTreeError, 'Root page node is not a PageTreeNode'
|
|
111
135
|
end
|
|
112
136
|
end
|
|
113
137
|
end
|
|
@@ -250,11 +274,11 @@ module Origami
|
|
|
250
274
|
field EXTGSTATE, :Type => Dictionary
|
|
251
275
|
field COLORSPACE, :Type => Dictionary
|
|
252
276
|
field PATTERN, :Type => Dictionary
|
|
253
|
-
field SHADING, :Type => Dictionary, :Version =>
|
|
277
|
+
field SHADING, :Type => Dictionary, :Version => '1.3'
|
|
254
278
|
field XOBJECT, :Type => Dictionary
|
|
255
279
|
field FONT, :Type => Dictionary
|
|
256
280
|
field :ProcSet, :Type => Array.of(Name)
|
|
257
|
-
field PROPERTIES, :Type => Dictionary, :Version =>
|
|
281
|
+
field PROPERTIES, :Type => Dictionary, :Version => '1.2'
|
|
258
282
|
|
|
259
283
|
def pre_build
|
|
260
284
|
add_font(Font::Type1::Standard::Helvetica.new.pre_build) unless self.Font
|
|
@@ -294,11 +318,11 @@ module Origami
|
|
|
294
318
|
# Inserts a page into the node at a specified position (starting from 1).
|
|
295
319
|
#
|
|
296
320
|
def insert_page(n, page)
|
|
297
|
-
raise IndexError,
|
|
321
|
+
raise IndexError, 'Page numbers are referenced starting from 1' if n < 1
|
|
298
322
|
|
|
299
323
|
kids = self.Kids
|
|
300
324
|
unless kids.is_a?(Array)
|
|
301
|
-
raise InvalidPageTreeError,
|
|
325
|
+
raise InvalidPageTreeError, 'Kids must be an Array'
|
|
302
326
|
end
|
|
303
327
|
|
|
304
328
|
count = 0
|
|
@@ -323,15 +347,87 @@ module Origami
|
|
|
323
347
|
return self
|
|
324
348
|
end
|
|
325
349
|
else
|
|
326
|
-
raise InvalidPageTreeError,
|
|
350
|
+
raise InvalidPageTreeError, 'not a Page or PageTreeNode'
|
|
327
351
|
end
|
|
328
352
|
end
|
|
329
353
|
|
|
330
|
-
raise IndexError,
|
|
354
|
+
raise IndexError, 'Out of order page index' unless count + 1 == n
|
|
331
355
|
|
|
332
356
|
self.append_page(page)
|
|
333
357
|
end
|
|
334
358
|
|
|
359
|
+
#
|
|
360
|
+
# Delete a page in the node at the specified position (starting from 1).
|
|
361
|
+
#
|
|
362
|
+
def delete_page_at(n)
|
|
363
|
+
raise IndexError, 'Page numbers are referenced starting from 1' if n < 1
|
|
364
|
+
|
|
365
|
+
kids = self.Kids
|
|
366
|
+
unless kids.is_a?(Array)
|
|
367
|
+
raise InvalidPageTreeError, 'Kids must be an Array'
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
count = 0
|
|
371
|
+
kids.each_with_index do |kid, index|
|
|
372
|
+
node = kid.solve
|
|
373
|
+
|
|
374
|
+
case node
|
|
375
|
+
when Page
|
|
376
|
+
count = count + 1
|
|
377
|
+
if count == n
|
|
378
|
+
kids.delete_at(index)
|
|
379
|
+
self.Count -= 1
|
|
380
|
+
return self
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
when PageTreeNode
|
|
384
|
+
count = count + node.Count
|
|
385
|
+
if count >= n
|
|
386
|
+
node.delete_page_at(n - count + node.Count)
|
|
387
|
+
self.Count -= 1
|
|
388
|
+
return self
|
|
389
|
+
end
|
|
390
|
+
else
|
|
391
|
+
raise InvalidPageTreeError, 'not a Page or PageTreeNode'
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
raise IndexError, 'Out of order page index' unless count + 1 == n
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
#
|
|
399
|
+
# Delete a set of page in the node at the specified positions (starting from 0).
|
|
400
|
+
#
|
|
401
|
+
def delete_pages_at(delete_idx, offset = 0)
|
|
402
|
+
kids = self.Kids
|
|
403
|
+
unless kids.is_a?(Array)
|
|
404
|
+
raise InvalidPageTreeError, 'Kids must be an Array'
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
deleted = 0
|
|
408
|
+
kids.delete_if.with_index do |kid, idx|
|
|
409
|
+
node = kid.solve
|
|
410
|
+
idx = idx + offset
|
|
411
|
+
|
|
412
|
+
case node
|
|
413
|
+
when Page
|
|
414
|
+
if delete_idx.include?(idx)
|
|
415
|
+
deleted += 1
|
|
416
|
+
true
|
|
417
|
+
else
|
|
418
|
+
false
|
|
419
|
+
end
|
|
420
|
+
when PageTreeNode
|
|
421
|
+
deleted += node.delete_pages_at(delete_idx, idx)
|
|
422
|
+
false
|
|
423
|
+
else
|
|
424
|
+
raise InvalidPageTreeError, 'not a Page or PageTreeNode'
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
self.Count -= deleted
|
|
428
|
+
deleted
|
|
429
|
+
end
|
|
430
|
+
|
|
335
431
|
#
|
|
336
432
|
# Returns an Array of Pages inheriting this tree node.
|
|
337
433
|
#
|
|
@@ -346,11 +442,11 @@ module Origami
|
|
|
346
442
|
return enum_for(__method__) { self.Count.to_i } unless block_given?
|
|
347
443
|
|
|
348
444
|
if browsed_nodes.any?{|node| node.equal?(self)}
|
|
349
|
-
raise InvalidPageTreeError,
|
|
445
|
+
raise InvalidPageTreeError, 'Cyclic tree graph detected'
|
|
350
446
|
end
|
|
351
447
|
|
|
352
448
|
unless self.Kids.is_a?(Array)
|
|
353
|
-
raise InvalidPageTreeError,
|
|
449
|
+
raise InvalidPageTreeError, 'Kids must be an Array'
|
|
354
450
|
end
|
|
355
451
|
|
|
356
452
|
browsed_nodes.push(self)
|
|
@@ -363,7 +459,7 @@ module Origami
|
|
|
363
459
|
when PageTreeNode then node.each_page(browsed_nodes: browsed_nodes, &block)
|
|
364
460
|
when Page then yield(node)
|
|
365
461
|
else
|
|
366
|
-
raise InvalidPageTreeError,
|
|
462
|
+
raise InvalidPageTreeError, 'not a Page or PageTreeNode'
|
|
367
463
|
end
|
|
368
464
|
end
|
|
369
465
|
end
|
|
@@ -375,10 +471,10 @@ module Origami
|
|
|
375
471
|
# Get the n-th Page object in this node, starting from 1.
|
|
376
472
|
#
|
|
377
473
|
def get_page(n)
|
|
378
|
-
raise IndexError,
|
|
379
|
-
raise IndexError,
|
|
474
|
+
raise IndexError, 'Page numbers are referenced starting from 1' if n < 1
|
|
475
|
+
raise IndexError, 'Page not found' if n > self.Count.to_i
|
|
380
476
|
|
|
381
|
-
self.each_page.lazy.drop(n - 1).first or raise IndexError,
|
|
477
|
+
self.each_page.lazy.drop(n - 1).first or raise IndexError, 'Page not found'
|
|
382
478
|
end
|
|
383
479
|
|
|
384
480
|
#
|
|
@@ -481,8 +577,8 @@ module Origami
|
|
|
481
577
|
class AdditionalActions < Dictionary
|
|
482
578
|
include StandardObject
|
|
483
579
|
|
|
484
|
-
field :O, :Type => Dictionary, :Version =>
|
|
485
|
-
field :C, :Type => Dictionary, :Version =>
|
|
580
|
+
field :O, :Type => Dictionary, :Version => '1.2' # Page Open
|
|
581
|
+
field :C, :Type => Dictionary, :Version => '1.2' # Page Close
|
|
486
582
|
end
|
|
487
583
|
|
|
488
584
|
module Format
|
|
@@ -513,34 +609,34 @@ module Origami
|
|
|
513
609
|
|
|
514
610
|
field :Type, :Type => Name, :Default => :Page, :Required => true
|
|
515
611
|
field :Parent, :Type => PageTreeNode, :Required => true
|
|
516
|
-
field :LastModified, :Type => String, :Version =>
|
|
612
|
+
field :LastModified, :Type => String, :Version => '1.3'
|
|
517
613
|
field :Resources, :Type => Resources, :Required => true
|
|
518
614
|
field :MediaBox, :Type => Rectangle, :Default => Format::A4, :Required => true
|
|
519
615
|
field :CropBox, :Type => Rectangle
|
|
520
|
-
field :BleedBox, :Type => Rectangle, :Version =>
|
|
521
|
-
field :TrimBox, :Type => Rectangle, :Version =>
|
|
522
|
-
field :ArtBox, :Type => Rectangle, :Version =>
|
|
523
|
-
field :BoxColorInfo, :Type => BoxColorInformation, :Version =>
|
|
616
|
+
field :BleedBox, :Type => Rectangle, :Version => '1.3'
|
|
617
|
+
field :TrimBox, :Type => Rectangle, :Version => '1.3'
|
|
618
|
+
field :ArtBox, :Type => Rectangle, :Version => '1.3'
|
|
619
|
+
field :BoxColorInfo, :Type => BoxColorInformation, :Version => '1.4'
|
|
524
620
|
field :Contents, :Type => [ ContentStream, Array.of(ContentStream) ]
|
|
525
621
|
field :Rotate, :Type => Integer, :Default => 0
|
|
526
|
-
field :Group, :Type => Dictionary, :Version =>
|
|
622
|
+
field :Group, :Type => Dictionary, :Version => '1.4'
|
|
527
623
|
field :Thumb, :Type => Graphics::ImageXObject
|
|
528
|
-
field :B, :Type => Array, :Version =>
|
|
529
|
-
field :Dur, :Type => Integer, :Version =>
|
|
530
|
-
field :Trans, :Type => Dictionary, :Version =>
|
|
624
|
+
field :B, :Type => Array, :Version => '1.1'
|
|
625
|
+
field :Dur, :Type => Integer, :Version => '1.1'
|
|
626
|
+
field :Trans, :Type => Dictionary, :Version => '1.1'
|
|
531
627
|
field :Annots, :Type => Array.of(Annotation)
|
|
532
|
-
field :AA, :Type => AdditionalActions, :Version =>
|
|
533
|
-
field :Metadata, :Type => MetadataStream, :Version =>
|
|
534
|
-
field :PieceInfo, :Type => Dictionary, :Version =>
|
|
535
|
-
field :StructParents, :Type => Integer, :Version =>
|
|
628
|
+
field :AA, :Type => AdditionalActions, :Version => '1.2'
|
|
629
|
+
field :Metadata, :Type => MetadataStream, :Version => '1.4'
|
|
630
|
+
field :PieceInfo, :Type => Dictionary, :Version => '1.2'
|
|
631
|
+
field :StructParents, :Type => Integer, :Version => '1.3'
|
|
536
632
|
field :ID, :Type => String
|
|
537
633
|
field :PZ, :Type => Number
|
|
538
|
-
field :SeparationInfo, :Type => Dictionary, :Version =>
|
|
539
|
-
field :Tabs, :Type => Name, :Version =>
|
|
540
|
-
field :TemplateAssociated, :Type => Name, :Version =>
|
|
541
|
-
field :PresSteps, :Type => NavigationNode, :Version =>
|
|
542
|
-
field :UserUnit, :Type => Number, :Default => 1.0, :Version =>
|
|
543
|
-
field :VP, :Type => Dictionary, :Version =>
|
|
634
|
+
field :SeparationInfo, :Type => Dictionary, :Version => '1.3'
|
|
635
|
+
field :Tabs, :Type => Name, :Version => '1.5'
|
|
636
|
+
field :TemplateAssociated, :Type => Name, :Version => '1.5'
|
|
637
|
+
field :PresSteps, :Type => NavigationNode, :Version => '1.5'
|
|
638
|
+
field :UserUnit, :Type => Number, :Default => 1.0, :Version => '1.6'
|
|
639
|
+
field :VP, :Type => Dictionary, :Version => '1.6'
|
|
544
640
|
|
|
545
641
|
def initialize(hash = {}, parser = nil)
|
|
546
642
|
super(hash, parser)
|
data/lib/origami/version.rb
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/test/test_pages.rb
CHANGED
|
@@ -51,10 +51,33 @@ class TestPages < Minitest::Test
|
|
|
51
51
|
assert_raises(IndexError) { @target.insert_page(1000, Page.new) }
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
def
|
|
54
|
+
def test_example_write_delete_page
|
|
55
55
|
@target.append_page
|
|
56
|
-
@target.pages.
|
|
56
|
+
@target.pages.last.write 'Hello, page 1 world!', size: 30
|
|
57
|
+
@target.append_page
|
|
58
|
+
@target.pages.last.write 'Hello, page 2 world!', size: 30
|
|
59
|
+
@target.save(@output)
|
|
60
|
+
assert_equal @target.Catalog.Pages.Count, 2
|
|
61
|
+
|
|
62
|
+
@target.delete_page_at(1)
|
|
57
63
|
@target.save(@output)
|
|
58
64
|
assert_equal @target.Catalog.Pages.Count, 1
|
|
59
65
|
end
|
|
66
|
+
|
|
67
|
+
def test_delete_pages_generated
|
|
68
|
+
to_append = [Page.new, Page.new, Page.new, PageTreeNode.new, Page.new, Page.new, Page.new]
|
|
69
|
+
to_append.each { |page| @target.append_page(page) }
|
|
70
|
+
to_del = [0,1]
|
|
71
|
+
assert_equal @target.Catalog.Pages.Count, to_append.length
|
|
72
|
+
@target.delete_pages_at(to_del)
|
|
73
|
+
assert_equal @target.Catalog.Pages.Count, to_append.length - to_del.length
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_delete_pages_parsed
|
|
77
|
+
file = File.join(__dir__, 'dataset', '3_pages.pdf')
|
|
78
|
+
pdf = PDF.read(file, ignore_errors: false, verbosity: Parser::VERBOSE_QUIET)
|
|
79
|
+
assert_equal pdf.Catalog.Pages.Count, 3
|
|
80
|
+
pdf.delete_pages_at([0,2])
|
|
81
|
+
assert_equal pdf.Catalog.Pages.Count, 1
|
|
82
|
+
end
|
|
60
83
|
end
|
data/test/test_pdf_parse.rb
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
require 'minitest/autorun'
|
|
2
2
|
|
|
3
3
|
class TestPDFParser < Minitest::Test
|
|
4
|
-
def setup
|
|
5
|
-
@files =
|
|
6
|
-
%w{
|
|
7
|
-
dataset/empty.pdf
|
|
8
|
-
dataset/calc.pdf
|
|
9
|
-
dataset/crypto.pdf
|
|
10
|
-
}
|
|
11
|
-
end
|
|
12
4
|
|
|
13
5
|
def test_parse_pdf
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
dir = File.join(__dir__, 'dataset')
|
|
7
|
+
Dir.children(dir).each do | filename |
|
|
8
|
+
pdf = PDF.read(File.join(dir, filename), ignore_errors: false, verbosity: Parser::VERBOSE_QUIET)
|
|
16
9
|
|
|
17
10
|
assert_instance_of PDF, pdf
|
|
18
11
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: origamindee
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Guillaume Delugré
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2023-01-12 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rainbow
|
|
@@ -232,9 +232,12 @@ files:
|
|
|
232
232
|
- lib/origami/xfa/xfdf.rb
|
|
233
233
|
- lib/origami/xfa/xmpmeta.rb
|
|
234
234
|
- lib/origami/xreftable.rb
|
|
235
|
+
- test/dataset/3_pages.pdf
|
|
235
236
|
- test/dataset/calc.pdf
|
|
236
237
|
- test/dataset/crypto.pdf
|
|
237
238
|
- test/dataset/empty.pdf
|
|
239
|
+
- test/dataset/image_only.pdf
|
|
240
|
+
- test/dataset/invoice.pdf
|
|
238
241
|
- test/test_actions.rb
|
|
239
242
|
- test/test_annotations.rb
|
|
240
243
|
- test/test_forms.rb
|