origami-docspring 2.2.0 → 2.3.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 +18 -0
- data/examples/attachments/attachment.rb +7 -8
- data/examples/attachments/nested_document.rb +6 -5
- data/examples/encryption/encryption.rb +5 -4
- data/examples/events/events.rb +7 -6
- data/examples/flash/flash.rb +10 -9
- data/examples/forms/javascript.rb +14 -13
- data/examples/forms/xfa.rb +67 -66
- data/examples/javascript/hello_world.rb +6 -5
- data/examples/javascript/js_emulation.rb +26 -26
- data/examples/loop/goto.rb +12 -11
- data/examples/loop/named.rb +17 -16
- data/examples/signature/signature.rb +11 -11
- data/examples/uri/javascript.rb +25 -24
- data/examples/uri/open-uri.rb +5 -4
- data/examples/uri/submitform.rb +11 -10
- data/lib/origami/3d.rb +330 -334
- data/lib/origami/acroform.rb +267 -268
- data/lib/origami/actions.rb +266 -278
- data/lib/origami/annotations.rb +659 -670
- data/lib/origami/array.rb +192 -196
- data/lib/origami/boolean.rb +66 -70
- data/lib/origami/catalog.rb +360 -363
- data/lib/origami/collections.rb +132 -133
- data/lib/origami/compound.rb +125 -129
- data/lib/origami/destinations.rb +226 -237
- data/lib/origami/dictionary.rb +155 -154
- data/lib/origami/encryption.rb +967 -923
- data/lib/origami/extensions/fdf.rb +270 -275
- data/lib/origami/extensions/ppklite.rb +323 -328
- data/lib/origami/filespec.rb +170 -173
- data/lib/origami/filters/ascii.rb +162 -167
- data/lib/origami/filters/ccitt/tables.rb +248 -252
- data/lib/origami/filters/ccitt.rb +309 -312
- data/lib/origami/filters/crypt.rb +31 -34
- data/lib/origami/filters/dct.rb +47 -50
- data/lib/origami/filters/flate.rb +57 -60
- data/lib/origami/filters/jbig2.rb +50 -53
- data/lib/origami/filters/jpx.rb +40 -43
- data/lib/origami/filters/lzw.rb +151 -155
- data/lib/origami/filters/predictors.rb +250 -255
- data/lib/origami/filters/runlength.rb +111 -115
- data/lib/origami/filters.rb +319 -325
- data/lib/origami/font.rb +173 -177
- data/lib/origami/functions.rb +62 -66
- data/lib/origami/graphics/colors.rb +203 -208
- data/lib/origami/graphics/instruction.rb +79 -81
- data/lib/origami/graphics/path.rb +141 -144
- data/lib/origami/graphics/patterns.rb +156 -160
- data/lib/origami/graphics/render.rb +51 -47
- data/lib/origami/graphics/state.rb +144 -142
- data/lib/origami/graphics/text.rb +185 -188
- data/lib/origami/graphics/xobject.rb +818 -804
- data/lib/origami/graphics.rb +25 -26
- data/lib/origami/header.rb +63 -65
- data/lib/origami/javascript.rb +718 -651
- data/lib/origami/linearization.rb +284 -285
- data/lib/origami/metadata.rb +156 -135
- data/lib/origami/name.rb +98 -100
- data/lib/origami/null.rb +49 -51
- data/lib/origami/numeric.rb +133 -135
- data/lib/origami/obfuscation.rb +180 -182
- data/lib/origami/object.rb +634 -631
- data/lib/origami/optionalcontent.rb +147 -149
- data/lib/origami/outline.rb +46 -48
- data/lib/origami/outputintents.rb +76 -77
- data/lib/origami/page.rb +637 -596
- data/lib/origami/parser.rb +214 -221
- data/lib/origami/parsers/fdf.rb +44 -45
- data/lib/origami/parsers/pdf/lazy.rb +147 -154
- data/lib/origami/parsers/pdf/linear.rb +104 -109
- data/lib/origami/parsers/pdf.rb +109 -107
- data/lib/origami/parsers/ppklite.rb +44 -46
- data/lib/origami/pdf.rb +886 -896
- data/lib/origami/reference.rb +116 -120
- data/lib/origami/signature.rb +617 -625
- data/lib/origami/stream.rb +560 -558
- data/lib/origami/string.rb +366 -368
- data/lib/origami/template/patterns.rb +50 -52
- data/lib/origami/template/widgets.rb +111 -114
- data/lib/origami/trailer.rb +153 -157
- data/lib/origami/tree.rb +55 -57
- data/lib/origami/version.rb +19 -19
- data/lib/origami/webcapture.rb +87 -90
- data/lib/origami/xfa/config.rb +409 -414
- data/lib/origami/xfa/connectionset.rb +113 -117
- data/lib/origami/xfa/datasets.rb +38 -42
- data/lib/origami/xfa/localeset.rb +33 -37
- data/lib/origami/xfa/package.rb +49 -52
- data/lib/origami/xfa/pdf.rb +54 -59
- data/lib/origami/xfa/signature.rb +33 -37
- data/lib/origami/xfa/sourceset.rb +34 -38
- data/lib/origami/xfa/stylesheet.rb +35 -39
- data/lib/origami/xfa/template.rb +1630 -1634
- data/lib/origami/xfa/xdc.rb +33 -37
- data/lib/origami/xfa/xfa.rb +132 -123
- data/lib/origami/xfa/xfdf.rb +34 -38
- data/lib/origami/xfa/xmpmeta.rb +34 -38
- data/lib/origami/xfa.rb +50 -53
- data/lib/origami/xreftable.rb +462 -462
- data/lib/origami.rb +37 -38
- data/test/test_actions.rb +22 -20
- data/test/test_annotations.rb +54 -52
- data/test/test_forms.rb +23 -21
- data/test/test_native_types.rb +82 -78
- data/test/test_object_tree.rb +25 -24
- data/test/test_pages.rb +43 -41
- data/test/test_pdf.rb +2 -0
- data/test/test_pdf_attachment.rb +23 -21
- data/test/test_pdf_create.rb +16 -15
- data/test/test_pdf_encrypt.rb +69 -66
- data/test/test_pdf_parse.rb +131 -129
- data/test/test_pdf_parse_lazy.rb +53 -53
- data/test/test_pdf_sign.rb +67 -67
- data/test/test_streams.rb +145 -143
- data/test/test_xrefs.rb +46 -45
- metadata +64 -8
data/lib/origami/dictionary.rb
CHANGED
@@ -1,192 +1,193 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# This file is part of Origami, PDF manipulation framework for Ruby
|
5
|
+
# Copyright (C) 2016 Guillaume Delugré.
|
6
|
+
#
|
7
|
+
# Origami is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# Origami is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
2
20
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
21
|
+
module Origami
|
22
|
+
class InvalidDictionaryObjectError < InvalidObjectError # :nodoc:
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Class representing a Dictionary Object.
|
27
|
+
# Dictionaries are containers associating a Name to an embedded Object.
|
28
|
+
#
|
29
|
+
class Dictionary < Hash
|
30
|
+
include CompoundObject
|
31
|
+
include FieldAccessor
|
32
|
+
using TypeConversion
|
33
|
+
extend TypeGuessing
|
34
|
+
|
35
|
+
TOKENS = %w[<< >>] # :nodoc:
|
36
|
+
@@regexp_open = Regexp.new(WHITESPACES + TOKENS.first + WHITESPACES)
|
37
|
+
@@regexp_close = Regexp.new(WHITESPACES + TOKENS.last + WHITESPACES)
|
10
38
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
39
|
+
#
|
40
|
+
# Creates a new Dictionary.
|
41
|
+
# _hash_:: The hash representing the new Dictionary.
|
42
|
+
#
|
43
|
+
def initialize(hash = {}, parser = nil)
|
44
|
+
raise TypeError, "Expected type Hash, received #{hash.class}." unless hash.is_a?(Hash)
|
45
|
+
super()
|
15
46
|
|
16
|
-
|
17
|
-
|
47
|
+
hash.each_pair do |k, v|
|
48
|
+
next if k.nil?
|
18
49
|
|
19
|
-
|
50
|
+
# Turns the values into Objects.
|
51
|
+
key, value = k.to_o, v.to_o
|
20
52
|
|
21
|
-
|
53
|
+
if Origami::OPTIONS[:enable_type_guessing]
|
54
|
+
hint_type = guess_value_type(key, value)
|
22
55
|
|
23
|
-
|
24
|
-
|
56
|
+
if hint_type.is_a?(Class) && (hint_type < value.class)
|
57
|
+
value = value.cast_to(hint_type, parser)
|
58
|
+
end
|
25
59
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
#
|
30
|
-
class Dictionary < Hash
|
31
|
-
include CompoundObject
|
32
|
-
include FieldAccessor
|
33
|
-
using TypeConversion
|
34
|
-
extend TypeGuessing
|
35
|
-
|
36
|
-
TOKENS = %w{ << >> } #:nodoc:
|
37
|
-
@@regexp_open = Regexp.new(WHITESPACES + TOKENS.first + WHITESPACES)
|
38
|
-
@@regexp_close = Regexp.new(WHITESPACES + TOKENS.last + WHITESPACES)
|
39
|
-
|
40
|
-
#
|
41
|
-
# Creates a new Dictionary.
|
42
|
-
# _hash_:: The hash representing the new Dictionary.
|
43
|
-
#
|
44
|
-
def initialize(hash = {}, parser = nil)
|
45
|
-
raise TypeError, "Expected type Hash, received #{hash.class}." unless hash.is_a?(Hash)
|
46
|
-
super()
|
47
|
-
|
48
|
-
hash.each_pair do |k,v|
|
49
|
-
next if k.nil?
|
50
|
-
|
51
|
-
# Turns the values into Objects.
|
52
|
-
key, value = k.to_o, v.to_o
|
53
|
-
|
54
|
-
if Origami::OPTIONS[:enable_type_guessing]
|
55
|
-
hint_type = guess_value_type(key, value)
|
56
|
-
|
57
|
-
if hint_type.is_a?(Class) and hint_type < value.class
|
58
|
-
value = value.cast_to(hint_type, parser)
|
59
|
-
end
|
60
|
-
|
61
|
-
if hint_type and parser and Origami::OPTIONS[:enable_type_propagation]
|
62
|
-
if value.is_a?(Reference)
|
63
|
-
parser.defer_type_cast(value, hint_type)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
self[key] = value
|
60
|
+
if hint_type && parser && Origami::OPTIONS[:enable_type_propagation]
|
61
|
+
if value.is_a?(Reference)
|
62
|
+
parser.defer_type_cast(value, hint_type)
|
69
63
|
end
|
64
|
+
end
|
70
65
|
end
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
self[key] = value
|
68
|
+
end
|
69
|
+
end
|
75
70
|
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
def self.parse(stream, parser = nil) # :nodoc:
|
72
|
+
scanner = Parser.init_scanner(stream)
|
73
|
+
offset = scanner.pos
|
79
74
|
|
80
|
-
|
81
|
-
|
82
|
-
|
75
|
+
if scanner.skip(@@regexp_open).nil?
|
76
|
+
raise InvalidDictionaryObjectError, "No token '#{TOKENS.first}' found"
|
77
|
+
end
|
83
78
|
|
84
|
-
|
85
|
-
|
79
|
+
hash = {}
|
80
|
+
while scanner.skip(@@regexp_close).nil?
|
81
|
+
key = Name.parse(scanner, parser)
|
86
82
|
|
87
|
-
|
88
|
-
|
89
|
-
end
|
83
|
+
type = Object.typeof(scanner)
|
84
|
+
raise InvalidDictionaryObjectError, "Invalid object for field #{key}" if type.nil?
|
90
85
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
dict_type = self
|
95
|
-
end
|
86
|
+
value = type.parse(scanner, parser)
|
87
|
+
hash[key] = value
|
88
|
+
end
|
96
89
|
|
97
|
-
|
98
|
-
|
90
|
+
dict_type = if Origami::OPTIONS[:enable_type_guessing]
|
91
|
+
guess_type(hash)
|
92
|
+
else
|
93
|
+
self
|
94
|
+
end
|
99
95
|
|
100
|
-
|
101
|
-
|
102
|
-
end
|
96
|
+
# Creates the Dictionary.
|
97
|
+
dict = dict_type.new(hash, parser)
|
103
98
|
|
104
|
-
|
105
|
-
|
106
|
-
|
99
|
+
dict.file_offset = offset
|
100
|
+
dict
|
101
|
+
end
|
107
102
|
|
108
|
-
|
109
|
-
|
110
|
-
|
103
|
+
def to_s(indent: 1, tab: "\t", eol: $/) # :nodoc:
|
104
|
+
nl = eol
|
105
|
+
tab, nl = '', '' if indent == 0
|
111
106
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
else
|
116
|
-
value.to_s(eol: eol)
|
117
|
-
end
|
107
|
+
content = TOKENS.first + nl
|
108
|
+
each_pair do |key, value|
|
109
|
+
content << "#{tab * indent}#{key} "
|
118
110
|
|
119
|
-
|
120
|
-
|
111
|
+
content <<
|
112
|
+
if value.is_a?(Dictionary)
|
113
|
+
value.to_s(eol: eol, indent: (indent == 0) ? 0 : indent + 1)
|
114
|
+
else
|
115
|
+
value.to_s(eol: eol)
|
116
|
+
end
|
121
117
|
|
122
|
-
|
123
|
-
|
118
|
+
content << nl
|
119
|
+
end
|
124
120
|
|
125
|
-
|
126
|
-
|
121
|
+
content << tab * (indent - 1) if indent > 0
|
122
|
+
content << TOKENS.last
|
127
123
|
|
128
|
-
|
129
|
-
|
130
|
-
#
|
131
|
-
def transform_values(&b)
|
132
|
-
self.class.new self.map { |k, v|
|
133
|
-
[ k.to_sym, b.call(v) ]
|
134
|
-
}.to_h
|
135
|
-
end
|
124
|
+
super(content, eol: eol)
|
125
|
+
end
|
136
126
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
127
|
+
#
|
128
|
+
# Returns a new Dictionary object with values modified by given block.
|
129
|
+
#
|
130
|
+
def transform_values(&b)
|
131
|
+
self.class.new map { |k, v|
|
132
|
+
[k.to_sym, b.call(v)]
|
133
|
+
}.to_h
|
134
|
+
end
|
145
135
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
136
|
+
#
|
137
|
+
# Modifies the values of the Dictionary, leaving keys unchanged.
|
138
|
+
#
|
139
|
+
def transform_values!(&b)
|
140
|
+
each_pair do |k, v|
|
141
|
+
self[k] = b.call(unlink_object(v))
|
142
|
+
end
|
143
|
+
end
|
152
144
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
145
|
+
#
|
146
|
+
# Merges the content of the Dictionary with another Dictionary.
|
147
|
+
#
|
148
|
+
def merge(dict)
|
149
|
+
self.class.new(super)
|
150
|
+
end
|
157
151
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
152
|
+
def []=(key, val)
|
153
|
+
unless key.is_a?(Symbol) || key.is_a?(Name)
|
154
|
+
raise TypeError, "Expecting a Name for a Dictionary entry, found #{key.class} instead."
|
155
|
+
end
|
162
156
|
|
163
|
-
|
164
|
-
|
157
|
+
if val.nil?
|
158
|
+
delete(key)
|
159
|
+
return
|
160
|
+
end
|
165
161
|
|
166
|
-
|
167
|
-
|
168
|
-
end
|
162
|
+
super(link_object(key), link_object(val))
|
163
|
+
end
|
169
164
|
|
170
|
-
|
171
|
-
|
165
|
+
def [](key)
|
166
|
+
super(key.to_o)
|
167
|
+
end
|
172
168
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
169
|
+
alias_method :key?, :include?
|
170
|
+
alias_method :has_key?, :key?
|
171
|
+
|
172
|
+
def to_h
|
173
|
+
to_a.map! { |k, v| [k.value, v.value] }.to_h
|
174
|
+
end
|
175
|
+
alias_method :value, :to_h
|
177
176
|
|
178
|
-
|
177
|
+
# :nodoc:
|
178
|
+
def self.hint_type(_name)
|
179
|
+
nil
|
180
|
+
end
|
179
181
|
|
180
|
-
|
182
|
+
private
|
181
183
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
184
|
+
def guess_value_type(key, value)
|
185
|
+
hint_type = self.class.hint_type(key.value)
|
186
|
+
if hint_type.is_a?(::Array) && !value.is_a?(Reference) # Choose best match
|
187
|
+
hint_type = hint_type.find { |type| type < value.class }
|
188
|
+
end
|
187
189
|
|
188
|
-
|
189
|
-
end
|
190
|
+
hint_type
|
190
191
|
end
|
191
|
-
|
192
|
+
end
|
192
193
|
end
|