origamindee 3.0.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.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +89 -0
  3. data/COPYING.LESSER +165 -0
  4. data/README.md +131 -0
  5. data/bin/config/pdfcop.conf.yml +236 -0
  6. data/bin/pdf2pdfa +87 -0
  7. data/bin/pdf2ruby +333 -0
  8. data/bin/pdfcop +476 -0
  9. data/bin/pdfdecompress +97 -0
  10. data/bin/pdfdecrypt +91 -0
  11. data/bin/pdfencrypt +113 -0
  12. data/bin/pdfexplode +223 -0
  13. data/bin/pdfextract +277 -0
  14. data/bin/pdfmetadata +143 -0
  15. data/bin/pdfsh +12 -0
  16. data/bin/shell/console.rb +128 -0
  17. data/bin/shell/hexdump.rb +59 -0
  18. data/bin/shell/irbrc +69 -0
  19. data/examples/README.md +34 -0
  20. data/examples/attachments/attachment.rb +38 -0
  21. data/examples/attachments/nested_document.rb +51 -0
  22. data/examples/encryption/encryption.rb +28 -0
  23. data/examples/events/events.rb +72 -0
  24. data/examples/flash/flash.rb +37 -0
  25. data/examples/flash/helloworld.swf +0 -0
  26. data/examples/forms/javascript.rb +54 -0
  27. data/examples/forms/xfa.rb +115 -0
  28. data/examples/javascript/hello_world.rb +22 -0
  29. data/examples/javascript/js_emulation.rb +54 -0
  30. data/examples/loop/goto.rb +32 -0
  31. data/examples/loop/named.rb +33 -0
  32. data/examples/signature/signature.rb +65 -0
  33. data/examples/uri/javascript.rb +56 -0
  34. data/examples/uri/open-uri.rb +21 -0
  35. data/examples/uri/submitform.rb +47 -0
  36. data/lib/origami/3d.rb +364 -0
  37. data/lib/origami/acroform.rb +321 -0
  38. data/lib/origami/actions.rb +318 -0
  39. data/lib/origami/annotations.rb +711 -0
  40. data/lib/origami/array.rb +242 -0
  41. data/lib/origami/boolean.rb +90 -0
  42. data/lib/origami/catalog.rb +418 -0
  43. data/lib/origami/collections.rb +144 -0
  44. data/lib/origami/compound.rb +161 -0
  45. data/lib/origami/destinations.rb +252 -0
  46. data/lib/origami/dictionary.rb +192 -0
  47. data/lib/origami/encryption.rb +1084 -0
  48. data/lib/origami/extensions/fdf.rb +347 -0
  49. data/lib/origami/extensions/ppklite.rb +422 -0
  50. data/lib/origami/filespec.rb +197 -0
  51. data/lib/origami/filters/ascii.rb +211 -0
  52. data/lib/origami/filters/ccitt/tables.rb +267 -0
  53. data/lib/origami/filters/ccitt.rb +357 -0
  54. data/lib/origami/filters/crypt.rb +38 -0
  55. data/lib/origami/filters/dct.rb +54 -0
  56. data/lib/origami/filters/flate.rb +69 -0
  57. data/lib/origami/filters/jbig2.rb +57 -0
  58. data/lib/origami/filters/jpx.rb +47 -0
  59. data/lib/origami/filters/lzw.rb +170 -0
  60. data/lib/origami/filters/predictors.rb +292 -0
  61. data/lib/origami/filters/runlength.rb +129 -0
  62. data/lib/origami/filters.rb +364 -0
  63. data/lib/origami/font.rb +196 -0
  64. data/lib/origami/functions.rb +79 -0
  65. data/lib/origami/graphics/colors.rb +230 -0
  66. data/lib/origami/graphics/instruction.rb +98 -0
  67. data/lib/origami/graphics/path.rb +182 -0
  68. data/lib/origami/graphics/patterns.rb +174 -0
  69. data/lib/origami/graphics/render.rb +62 -0
  70. data/lib/origami/graphics/state.rb +149 -0
  71. data/lib/origami/graphics/text.rb +225 -0
  72. data/lib/origami/graphics/xobject.rb +918 -0
  73. data/lib/origami/graphics.rb +38 -0
  74. data/lib/origami/header.rb +75 -0
  75. data/lib/origami/javascript.rb +713 -0
  76. data/lib/origami/linearization.rb +330 -0
  77. data/lib/origami/metadata.rb +172 -0
  78. data/lib/origami/name.rb +135 -0
  79. data/lib/origami/null.rb +65 -0
  80. data/lib/origami/numeric.rb +181 -0
  81. data/lib/origami/obfuscation.rb +245 -0
  82. data/lib/origami/object.rb +760 -0
  83. data/lib/origami/optionalcontent.rb +183 -0
  84. data/lib/origami/outline.rb +54 -0
  85. data/lib/origami/outputintents.rb +85 -0
  86. data/lib/origami/page.rb +722 -0
  87. data/lib/origami/parser.rb +269 -0
  88. data/lib/origami/parsers/fdf.rb +56 -0
  89. data/lib/origami/parsers/pdf/lazy.rb +176 -0
  90. data/lib/origami/parsers/pdf/linear.rb +122 -0
  91. data/lib/origami/parsers/pdf.rb +118 -0
  92. data/lib/origami/parsers/ppklite.rb +57 -0
  93. data/lib/origami/pdf.rb +1108 -0
  94. data/lib/origami/reference.rb +134 -0
  95. data/lib/origami/signature.rb +702 -0
  96. data/lib/origami/stream.rb +705 -0
  97. data/lib/origami/string.rb +444 -0
  98. data/lib/origami/template/patterns.rb +56 -0
  99. data/lib/origami/template/widgets.rb +151 -0
  100. data/lib/origami/trailer.rb +190 -0
  101. data/lib/origami/tree.rb +62 -0
  102. data/lib/origami/version.rb +23 -0
  103. data/lib/origami/webcapture.rb +100 -0
  104. data/lib/origami/xfa/config.rb +453 -0
  105. data/lib/origami/xfa/connectionset.rb +146 -0
  106. data/lib/origami/xfa/datasets.rb +49 -0
  107. data/lib/origami/xfa/localeset.rb +42 -0
  108. data/lib/origami/xfa/package.rb +59 -0
  109. data/lib/origami/xfa/pdf.rb +73 -0
  110. data/lib/origami/xfa/signature.rb +42 -0
  111. data/lib/origami/xfa/sourceset.rb +43 -0
  112. data/lib/origami/xfa/stylesheet.rb +44 -0
  113. data/lib/origami/xfa/template.rb +1691 -0
  114. data/lib/origami/xfa/xdc.rb +42 -0
  115. data/lib/origami/xfa/xfa.rb +146 -0
  116. data/lib/origami/xfa/xfdf.rb +43 -0
  117. data/lib/origami/xfa/xmpmeta.rb +43 -0
  118. data/lib/origami/xfa.rb +62 -0
  119. data/lib/origami/xreftable.rb +557 -0
  120. data/lib/origami.rb +47 -0
  121. data/test/dataset/calc.pdf +85 -0
  122. data/test/dataset/crypto.pdf +36 -0
  123. data/test/dataset/empty.pdf +49 -0
  124. data/test/test_actions.rb +27 -0
  125. data/test/test_annotations.rb +68 -0
  126. data/test/test_forms.rb +30 -0
  127. data/test/test_native_types.rb +83 -0
  128. data/test/test_object_tree.rb +33 -0
  129. data/test/test_pages.rb +60 -0
  130. data/test/test_pdf.rb +20 -0
  131. data/test/test_pdf_attachment.rb +34 -0
  132. data/test/test_pdf_create.rb +24 -0
  133. data/test/test_pdf_encrypt.rb +102 -0
  134. data/test/test_pdf_parse.rb +134 -0
  135. data/test/test_pdf_parse_lazy.rb +69 -0
  136. data/test/test_pdf_sign.rb +97 -0
  137. data/test/test_streams.rb +184 -0
  138. data/test/test_xrefs.rb +67 -0
  139. metadata +280 -0
@@ -0,0 +1,242 @@
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
+
22
+ module Origami
23
+
24
+ class InvalidArrayObjectError < InvalidObjectError #:nodoc:
25
+ end
26
+
27
+ #
28
+ # Class representing an Array Object.
29
+ # Arrays contain a set of Object.
30
+ #
31
+ class Array < ::Array
32
+ include CompoundObject
33
+ using TypeConversion
34
+
35
+ TOKENS = %w{ [ ] } #:nodoc:
36
+ @@regexp_open = Regexp.new(WHITESPACES + Regexp.escape(TOKENS.first) + WHITESPACES)
37
+ @@regexp_close = Regexp.new(WHITESPACES + Regexp.escape(TOKENS.last) + WHITESPACES)
38
+
39
+ #
40
+ # Creates a new PDF Array Object.
41
+ # _data_:: An array of objects.
42
+ #
43
+ def initialize(data = [], parser = nil, hint_type: nil)
44
+ raise TypeError, "Expected type Array, received #{data.class}." unless data.is_a?(::Array)
45
+ super()
46
+
47
+ data.each_with_index do |value, index|
48
+ value = value.to_o
49
+
50
+ if Origami::OPTIONS[:enable_type_guessing]
51
+ index_type = hint_type.is_a?(::Array) ? hint_type[index % hint_type.size] : hint_type
52
+ if index_type.is_a?(::Array) and not value.is_a?(Reference)
53
+ index_type = index_type.find {|type| type < value.class }
54
+ end
55
+
56
+ if index_type.is_a?(Class) and index_type < value.class
57
+ value = value.cast_to(index_type, parser)
58
+ end
59
+
60
+ if index_type and parser and Origami::OPTIONS[:enable_type_propagation]
61
+ if value.is_a?(Reference)
62
+ parser.defer_type_cast(value, index_type)
63
+ end
64
+ end
65
+ end
66
+
67
+ self.push(value)
68
+ end
69
+ end
70
+
71
+ def pre_build
72
+ self.map!(&:to_o)
73
+
74
+ super
75
+ end
76
+
77
+ def self.parse(stream, parser = nil, hint_type: nil) #:nodoc:
78
+ scanner = Parser.init_scanner(stream)
79
+ offset = scanner.pos
80
+ data = []
81
+
82
+ if not scanner.skip(@@regexp_open)
83
+ raise InvalidArrayObjectError, "No token '#{TOKENS.first}' found"
84
+ end
85
+
86
+ while scanner.skip(@@regexp_close).nil? do
87
+ type = Object.typeof(scanner)
88
+ raise InvalidArrayObjectError, "Bad embedded object format" if type.nil?
89
+
90
+ value = type.parse(scanner, parser)
91
+ data << value
92
+ end
93
+
94
+ array = Array.new(data, parser, hint_type: hint_type)
95
+ array.file_offset = offset
96
+
97
+ array
98
+ end
99
+
100
+ #
101
+ # Converts self into a Ruby array.
102
+ #
103
+ def to_a
104
+ super.map(&:value)
105
+ end
106
+ alias value to_a
107
+
108
+ alias each_value each
109
+
110
+ def to_s(eol: $/) #:nodoc:
111
+ content = TOKENS.first.dup
112
+ content << self.map {|entry|
113
+ entry = entry.to_o
114
+
115
+ case entry
116
+ when Dictionary # Do not indent dictionaries inside of arrays.
117
+ entry.to_s(indent: 0, eol: eol)
118
+ else
119
+ entry.to_s(eol: eol)
120
+ end
121
+ }.join(' ')
122
+ content << TOKENS.last
123
+
124
+ super(content, eol: eol)
125
+ end
126
+
127
+ def +(other)
128
+ a = Origami::Array.new(self.to_a + other.to_a)
129
+ a.no, a.generation = @no, @generation
130
+
131
+ a
132
+ end
133
+
134
+ def <<(item)
135
+ super link_object(item)
136
+ end
137
+
138
+ def push(*items)
139
+ items.each {|item| self << item }
140
+ end
141
+
142
+ def []=(index, item)
143
+ super(index, link_object(item))
144
+ end
145
+
146
+ def insert(index, *items)
147
+ items.reverse_each do |item|
148
+ super(index, link_object(item))
149
+ end
150
+
151
+ self
152
+ end
153
+
154
+ def concat(*arys)
155
+ self.push(*arys.flatten)
156
+ end
157
+
158
+ #
159
+ # Parameterized Array class with additional typing information.
160
+ # Example: Array.of(Integer)
161
+ #
162
+ def self.of(klass, *klasses, length: nil)
163
+ Class.new(self) do
164
+ const_set('ARRAY_TYPE', (klasses.empty? and not klass.is_a?(::Array)) ? klass : [ klass ].concat(klasses))
165
+ const_set('STATIC_LENGTH', length)
166
+
167
+ def initialize(data = [], parser = nil)
168
+ super(data, parser, hint_type: self.class.const_get('ARRAY_TYPE'))
169
+ end
170
+
171
+ def pre_build #:nodoc:
172
+ do_type_check if Origami::OPTIONS[:enable_type_checking]
173
+
174
+ super
175
+ end
176
+
177
+ def self.parse(stream, parser = nil)
178
+ super(stream, parser, hint_type: const_get('ARRAY_TYPE'))
179
+ end
180
+
181
+ def do_type_check #:nodoc:
182
+ static_length = self.class.const_get('STATIC_LENGTH')
183
+ array_type = self.class.const_get('ARRAY_TYPE')
184
+
185
+ if static_length and self.length != static_length
186
+ STDERR.puts "Warning: object #{self.class.name} has unexpected length #{self.length} (should be #{static_length})"
187
+ end
188
+
189
+ self.each_with_index do |object, index|
190
+ index_type = array_type.is_a?(::Array) ? array_type[index % array_type.size] : array_type
191
+
192
+ begin
193
+ object_value = object.solve
194
+ rescue InvalidReferenceError
195
+ STDERR.puts "Warning: in object #{self.class}, invalid reference at index #{index}"
196
+ next
197
+ end
198
+
199
+ unless object_value.is_a?(index_type)
200
+ STDERR.puts "Warning: object #{self.class.name || 'Array'} should be composed of #{index_type.name} at index #{index} (got #{object_value.type} instead)"
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+
208
+ #
209
+ # Class representing a location on a page or a bounding box.
210
+ #
211
+ class Rectangle < Array.of(Number, length: 4)
212
+
213
+ def self.[](coords)
214
+ corners =
215
+ if [ :llx, :lly, :urx, :ury ].all? {|p| coords.include?(p)}
216
+ coords.values_at(:llx, :lly, :urx, :ury)
217
+ elsif [ :width, :height ].all? {|p| coords.include?(p)}
218
+ width, height = coords.values_at(:width, :height)
219
+ x = coords.fetch(:x, 0)
220
+ y = coords.fetch(:y, 0)
221
+ [ x, y, x+width, y+height ]
222
+ else
223
+ raise ArgumentError, "Bad arguments for #{self.class}: #{coords.inspect}"
224
+ end
225
+
226
+ unless corners.all? { |corner| corner.is_a?(Numeric) }
227
+ raise TypeError, "All coords must be numbers"
228
+ end
229
+
230
+ Rectangle.new(corners)
231
+ end
232
+
233
+ def width
234
+ self[2] - self[0]
235
+ end
236
+
237
+ def height
238
+ self[3] - self[1]
239
+ end
240
+ end
241
+
242
+ end
@@ -0,0 +1,90 @@
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
+ module Origami
22
+
23
+ class InvalidBooleanObjectError < InvalidObjectError #:nodoc:
24
+ end
25
+
26
+ #
27
+ # Class representing a Boolean Object.
28
+ # A Boolean Object can be *true* or *false*.
29
+ #
30
+ class Boolean
31
+ include Origami::Object
32
+
33
+ TOKENS = %w{ true false } #:nodoc:
34
+ @@regexp = Regexp.new(WHITESPACES + "(?<value>#{Regexp.union(TOKENS)})")
35
+
36
+ #
37
+ # Creates a new Boolean value.
38
+ # _value_:: *true* or *false*.
39
+ #
40
+ def initialize(value)
41
+ unless value.is_a?(TrueClass) or value.is_a?(FalseClass)
42
+ raise TypeError, "Expected type TrueClass or FalseClass, received #{value.class}."
43
+ end
44
+
45
+ super()
46
+
47
+ @value = (value == true)
48
+ end
49
+
50
+ def to_s(eol: $/) #:nodoc:
51
+ super(@value.to_s, eol: eol)
52
+ end
53
+
54
+ def self.parse(stream, _parser = nil) #:nodoc:
55
+ scanner = Parser.init_scanner(stream)
56
+ offset = scanner.pos
57
+
58
+ if scanner.scan(@@regexp).nil?
59
+ raise InvalidBooleanObjectError
60
+ end
61
+
62
+ value = (scanner['value'] == "true")
63
+
64
+ bool = Boolean.new(value)
65
+ bool.file_offset = offset
66
+
67
+ bool
68
+ end
69
+
70
+ #
71
+ # Converts self into a Ruby boolean, that is TrueClass or FalseClass instance.
72
+ #
73
+ def value
74
+ @value
75
+ end
76
+
77
+ def false?
78
+ @value == false
79
+ end
80
+
81
+ def true?
82
+ @value == true
83
+ end
84
+
85
+ def ==(bool)
86
+ @value == bool
87
+ end
88
+ end
89
+
90
+ end