hexapdf 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +56 -0
- data/CONTRIBUTERS +1 -1
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/examples/arc.rb +1 -1
- data/examples/graphics.rb +1 -1
- data/examples/hello_world.rb +1 -1
- data/examples/merging.rb +1 -1
- data/examples/show_char_bboxes.rb +1 -1
- data/examples/standard_pdf_fonts.rb +1 -1
- data/examples/truetype.rb +1 -1
- data/lib/hexapdf/cli.rb +14 -7
- data/lib/hexapdf/cli/extract.rb +1 -1
- data/lib/hexapdf/cli/info.rb +2 -2
- data/lib/hexapdf/cli/inspect.rb +4 -4
- data/lib/hexapdf/cli/modify.rb +151 -51
- data/lib/hexapdf/configuration.rb +1 -1
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/dictionary.rb +6 -19
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document.rb +23 -16
- data/lib/hexapdf/document/files.rb +130 -0
- data/lib/hexapdf/{font_utils.rb → document/fonts.rb} +40 -38
- data/lib/hexapdf/document/images.rb +117 -0
- data/lib/hexapdf/document/pages.rb +125 -0
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +10 -10
- data/lib/hexapdf/encryption/standard_security_handler.rb +11 -8
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -6
- data/lib/hexapdf/font/cmap/writer.rb +5 -7
- data/lib/hexapdf/font/true_type.rb +4 -1
- data/lib/hexapdf/font/true_type/font.rb +8 -16
- data/lib/hexapdf/font/true_type/table.rb +5 -16
- data/lib/hexapdf/font/true_type/table/cmap.rb +2 -7
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +2 -6
- data/lib/hexapdf/font/true_type/table/directory.rb +0 -5
- data/lib/hexapdf/font/true_type/table/glyf.rb +3 -11
- data/lib/hexapdf/font/true_type/table/head.rb +0 -12
- data/lib/hexapdf/font/true_type/table/hhea.rb +0 -7
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -5
- data/lib/hexapdf/font/true_type/table/loca.rb +0 -4
- data/lib/hexapdf/font/true_type/table/maxp.rb +0 -8
- data/lib/hexapdf/font/true_type/table/name.rb +3 -17
- data/lib/hexapdf/font/true_type/table/os2.rb +0 -14
- data/lib/hexapdf/font/true_type/table/post.rb +0 -8
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1.rb +2 -2
- data/lib/hexapdf/font/type1/font.rb +2 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +10 -1
- data/lib/hexapdf/font/type1_wrapper.rb +2 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/object.rb +18 -5
- data/lib/hexapdf/rectangle.rb +8 -1
- data/lib/hexapdf/revisions.rb +4 -2
- data/lib/hexapdf/serializer.rb +3 -3
- data/lib/hexapdf/stream.rb +3 -2
- data/lib/hexapdf/task/dereference.rb +4 -5
- data/lib/hexapdf/task/optimize.rb +6 -3
- data/lib/hexapdf/tokenizer.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/form.rb +19 -0
- data/lib/hexapdf/type/page.rb +21 -6
- data/lib/hexapdf/type/page_tree_node.rb +27 -34
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/man/man1/hexapdf.1 +259 -187
- data/test/hexapdf/content/graphic_object/test_arc.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_solid_arc.rb +1 -1
- data/test/hexapdf/content/test_canvas.rb +1 -1
- data/test/hexapdf/document/test_files.rb +71 -0
- data/test/hexapdf/{test_font_utils.rb → document/test_fonts.rb} +1 -2
- data/test/hexapdf/document/test_images.rb +78 -0
- data/test/hexapdf/document/test_pages.rb +114 -0
- data/test/hexapdf/encryption/test_standard_security_handler.rb +26 -5
- data/test/hexapdf/font/test_true_type_wrapper.rb +1 -1
- data/test/hexapdf/font/true_type/common.rb +0 -4
- data/test/hexapdf/font/true_type/table/test_cmap.rb +0 -6
- data/test/hexapdf/font/true_type/table/test_directory.rb +0 -5
- data/test/hexapdf/font/true_type/table/test_glyf.rb +5 -8
- data/test/hexapdf/font/true_type/table/test_head.rb +0 -20
- data/test/hexapdf/font/true_type/table/test_hhea.rb +0 -7
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +2 -7
- data/test/hexapdf/font/true_type/table/test_loca.rb +4 -8
- data/test/hexapdf/font/true_type/table/test_maxp.rb +0 -7
- data/test/hexapdf/font/true_type/table/test_name.rb +0 -19
- data/test/hexapdf/font/true_type/table/test_os2.rb +0 -8
- data/test/hexapdf/font/true_type/table/test_post.rb +0 -13
- data/test/hexapdf/font/true_type/test_font.rb +14 -38
- data/test/hexapdf/font/true_type/test_table.rb +0 -9
- data/test/hexapdf/font/type1/test_font_metrics.rb +22 -0
- data/test/hexapdf/task/test_dereference.rb +5 -1
- data/test/hexapdf/task/test_optimize.rb +1 -1
- data/test/hexapdf/test_dictionary.rb +4 -0
- data/test/hexapdf/test_document.rb +0 -7
- data/test/hexapdf/test_importer.rb +4 -4
- data/test/hexapdf/test_object.rb +31 -9
- data/test/hexapdf/test_rectangle.rb +18 -0
- data/test/hexapdf/test_revisions.rb +7 -0
- data/test/hexapdf/test_serializer.rb +6 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/test_form.rb +12 -0
- data/test/hexapdf/type/test_page.rb +39 -20
- data/test/hexapdf/type/test_page_tree_node.rb +28 -21
- metadata +21 -9
- data/lib/hexapdf/document_utils.rb +0 -209
- data/test/hexapdf/test_document_utils.rb +0 -144
data/lib/hexapdf/rectangle.rb
CHANGED
@@ -87,13 +87,20 @@ module HexaPDF
|
|
87
87
|
# upper-right corner.
|
88
88
|
def after_data_change
|
89
89
|
super
|
90
|
-
unless value.kind_of?(Array) && value.size == 4
|
90
|
+
unless value.kind_of?(Array) && value.size == 4 && value.all? {|i| i.kind_of?(Numeric)}
|
91
91
|
raise ArgumentError, "A PDF rectangle structure must contain an array of four numbers"
|
92
92
|
end
|
93
93
|
value[0], value[2] = value[2], value[0] if value[0] > value[2]
|
94
94
|
value[1], value[3] = value[3], value[1] if value[1] > value[3]
|
95
95
|
end
|
96
96
|
|
97
|
+
def perform_validation #:nodoc:
|
98
|
+
super
|
99
|
+
unless value.kind_of?(Array) && value.size == 4 && value.all? {|i| i.kind_of?(Numeric)}
|
100
|
+
yield("A PDF rectangle structure must contain an array of four numbers", false)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
97
104
|
end
|
98
105
|
|
99
106
|
end
|
data/lib/hexapdf/revisions.rb
CHANGED
@@ -169,8 +169,10 @@ module HexaPDF
|
|
169
169
|
@revisions[range].reverse.each_cons(2) do |rev, prev_rev|
|
170
170
|
prev_rev.trailer.value.replace(rev.trailer.value)
|
171
171
|
rev.each do |obj|
|
172
|
-
prev_rev.
|
173
|
-
|
172
|
+
if obj.data != prev_rev.object(obj)&.data
|
173
|
+
prev_rev.delete(obj.oid, mark_as_free: false)
|
174
|
+
prev_rev.add(obj)
|
175
|
+
end
|
174
176
|
end
|
175
177
|
end
|
176
178
|
_first, *other = *@revisions[range]
|
data/lib/hexapdf/serializer.rb
CHANGED
@@ -88,7 +88,7 @@ module HexaPDF
|
|
88
88
|
@dispatcher = Hash.new do |h, klass|
|
89
89
|
method = nil
|
90
90
|
klass.ancestors.each do |ancestor_klass|
|
91
|
-
method = "serialize_#{ancestor_klass.name.downcase.gsub(/::/, '_')}"
|
91
|
+
method = "serialize_#{ancestor_klass.name.to_s.downcase.gsub(/::/, '_')}"
|
92
92
|
(h[klass] = method; break) if respond_to?(method, true)
|
93
93
|
end
|
94
94
|
method
|
@@ -188,7 +188,7 @@ module HexaPDF
|
|
188
188
|
end
|
189
189
|
|
190
190
|
BYTE_IS_DELIMITER = {40 => true, 47 => true, 60 => true, 91 => true, # :nodoc:
|
191
|
-
41 => true, 62 => true, 93 => true}
|
191
|
+
41 => true, 62 => true, 93 => true}.freeze
|
192
192
|
|
193
193
|
# Serializes an Array object.
|
194
194
|
#
|
@@ -222,7 +222,7 @@ module HexaPDF
|
|
222
222
|
str << ">>".freeze
|
223
223
|
end
|
224
224
|
|
225
|
-
STRING_ESCAPE_MAP = {"(" => "\\(", ")" => "\\)", "\\" => "\\\\", "\r" => "\\r"} # :nodoc:
|
225
|
+
STRING_ESCAPE_MAP = {"(" => "\\(", ")" => "\\)", "\\" => "\\\\", "\r" => "\\r"}.freeze # :nodoc:
|
226
226
|
|
227
227
|
# Serializes a String object.
|
228
228
|
#
|
data/lib/hexapdf/stream.rb
CHANGED
@@ -71,7 +71,7 @@ module HexaPDF
|
|
71
71
|
#
|
72
72
|
# * A Proc object (that is converted to a Fiber when needed) in which case the +offset+ and
|
73
73
|
# value is ignored. The Proc object can also be passed by using a block.
|
74
|
-
def initialize(source =
|
74
|
+
def initialize(source = nil, offset: nil, length: nil, filter: nil, decode_parms: nil, &block)
|
75
75
|
if source.nil? && !block_given?
|
76
76
|
raise ArgumentError, "Either a source object or a block must be given"
|
77
77
|
end
|
@@ -257,7 +257,8 @@ module HexaPDF
|
|
257
257
|
# :nodoc:
|
258
258
|
# A mapping from short name to long name for filters.
|
259
259
|
FILTER_MAP = {AHx: :ASCIIHexDecode, A85: :ASCII85Decode, LZW: :LZWDecode,
|
260
|
-
Fl: :FlateDecode, RL: :RunLengthDecode, CCF: :CCITTFaxDecode,
|
260
|
+
Fl: :FlateDecode, RL: :RunLengthDecode, CCF: :CCITTFaxDecode,
|
261
|
+
DCT: :DCTDecode}.freeze
|
261
262
|
|
262
263
|
# Validates the /Filter entry so that it contains only long-name filter names.
|
263
264
|
def perform_validation
|
@@ -70,7 +70,7 @@ module HexaPDF
|
|
70
70
|
dereference(@doc.trailer)
|
71
71
|
@result = []
|
72
72
|
@doc.each(current: false) do |obj|
|
73
|
-
if !@seen.key?(obj) && obj.type != :ObjStm && obj.type != :XRef
|
73
|
+
if !@seen.key?(obj.data) && obj.type != :ObjStm && obj.type != :XRef
|
74
74
|
@result << obj
|
75
75
|
elsif obj.kind_of?(HexaPDF::Stream) && (val = obj.value[:Length]) &&
|
76
76
|
val.kind_of?(HexaPDF::Object) && val.indirect?
|
@@ -81,8 +81,8 @@ module HexaPDF
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def dereference(object) #:nodoc:
|
84
|
-
return object if @seen.key?(object)
|
85
|
-
@seen[object] = true
|
84
|
+
return object if @seen.key?(object.data)
|
85
|
+
@seen[object.data] = true
|
86
86
|
recurse(object.value)
|
87
87
|
object
|
88
88
|
end
|
@@ -96,8 +96,7 @@ module HexaPDF
|
|
96
96
|
when HexaPDF::Reference
|
97
97
|
dereference(@doc.object(val))
|
98
98
|
when HexaPDF::Object
|
99
|
-
|
100
|
-
val
|
99
|
+
dereference(val)
|
101
100
|
else
|
102
101
|
val
|
103
102
|
end
|
@@ -95,8 +95,11 @@ module HexaPDF
|
|
95
95
|
|
96
96
|
oid = 1
|
97
97
|
doc.revisions[0].each do |obj|
|
98
|
-
|
99
|
-
|
98
|
+
if obj.null? || unused.include?(obj) || (obj.type == :ObjStm) ||
|
99
|
+
(obj.type == :XRef && xref_streams != :preserve)
|
100
|
+
obj.data.value = nil
|
101
|
+
next
|
102
|
+
end
|
100
103
|
|
101
104
|
delete_fields_with_defaults(obj)
|
102
105
|
obj.oid = oid
|
@@ -200,7 +203,7 @@ module HexaPDF
|
|
200
203
|
# Compresses the contents of all pages by parsing and then serializing again. The HexaPDF
|
201
204
|
# serializer is already optimized for small output size so nothing else needs to be done.
|
202
205
|
def self.compress_pages(doc)
|
203
|
-
doc.pages.
|
206
|
+
doc.pages.each do |page|
|
204
207
|
processor = SerializationProcessor.new
|
205
208
|
HexaPDF::Content::Parser.parse(page.contents, processor)
|
206
209
|
page.contents = processor.result
|
data/lib/hexapdf/tokenizer.rb
CHANGED
@@ -56,12 +56,12 @@ module HexaPDF
|
|
56
56
|
# Characters defined as whitespace.
|
57
57
|
#
|
58
58
|
# See: PDF1.7 s7.2.2
|
59
|
-
WHITESPACE = "\0\t\n\f\r "
|
59
|
+
WHITESPACE = "\0\t\n\f\r ".freeze
|
60
60
|
|
61
61
|
# Characters defined as delimiters.
|
62
62
|
#
|
63
63
|
# See: PDF1.7 s7.2.2
|
64
|
-
DELIMITER = "()<>{}/[]%"
|
64
|
+
DELIMITER = "()<>{}/[]%".freeze
|
65
65
|
|
66
66
|
WHITESPACE_MULTI_RE = /[#{WHITESPACE}]+/ # :nodoc:
|
67
67
|
|
@@ -267,7 +267,7 @@ module HexaPDF
|
|
267
267
|
'(' => "(",
|
268
268
|
')' => ")",
|
269
269
|
'\\' => "\\",
|
270
|
-
}
|
270
|
+
}.freeze
|
271
271
|
|
272
272
|
# Parses the literal string at the current position.
|
273
273
|
#
|
@@ -107,8 +107,8 @@ module HexaPDF
|
|
107
107
|
# /Unix, /Mac and /DOS).
|
108
108
|
def path
|
109
109
|
tmp = (self[:UF] || self[:F] || self[:Unix] || self[:Mac] || self[:DOS] || '').dup
|
110
|
-
tmp.gsub!(/\\\//, "/")
|
111
|
-
tmp.
|
110
|
+
tmp.gsub!(/\\\//, "/") # PDF1.7 s7.11.2.1 but / in filename is interpreted as separator!
|
111
|
+
tmp.tr!("\\", "/") # always use slashes instead of back-slashes!
|
112
112
|
tmp
|
113
113
|
end
|
114
114
|
|
data/lib/hexapdf/type/form.rb
CHANGED
@@ -32,6 +32,7 @@
|
|
32
32
|
#++
|
33
33
|
|
34
34
|
require 'hexapdf/stream'
|
35
|
+
require 'hexapdf/content'
|
35
36
|
|
36
37
|
module HexaPDF
|
37
38
|
module Type
|
@@ -97,6 +98,24 @@ module HexaPDF
|
|
97
98
|
Content::Parser.parse(contents, processor)
|
98
99
|
end
|
99
100
|
|
101
|
+
# Returns the canvas for the form XObject.
|
102
|
+
#
|
103
|
+
# The canvas object is cached once it is created so that its graphics state is correctly
|
104
|
+
# retained without the need for parsing its contents.
|
105
|
+
#
|
106
|
+
# *Note* that a canvas can only be retrieved for initially empty form XObjects!
|
107
|
+
def canvas
|
108
|
+
unless defined?(@canvas)
|
109
|
+
unless stream.empty?
|
110
|
+
raise HexaPDF::Error, "Cannot create a canvas for a form XObjects with contents"
|
111
|
+
end
|
112
|
+
@canvas = Content::Canvas.new(self)
|
113
|
+
self.stream = @canvas.stream_data
|
114
|
+
set_filter(:FlateDecode)
|
115
|
+
end
|
116
|
+
@canvas
|
117
|
+
end
|
118
|
+
|
100
119
|
end
|
101
120
|
|
102
121
|
end
|
data/lib/hexapdf/type/page.rb
CHANGED
@@ -97,13 +97,13 @@ module HexaPDF
|
|
97
97
|
Ledger: [0, 0, 792, 1224].freeze,
|
98
98
|
Tabloid: [0, 0, 1224, 792].freeze,
|
99
99
|
Executive: [0, 0, 522, 756].freeze,
|
100
|
-
}
|
100
|
+
}.freeze
|
101
101
|
|
102
102
|
# The inheritable fields.
|
103
|
-
INHERITABLE_FIELDS = [:Resources, :MediaBox, :CropBox, :Rotate]
|
103
|
+
INHERITABLE_FIELDS = [:Resources, :MediaBox, :CropBox, :Rotate].freeze
|
104
104
|
|
105
105
|
# The required inheritable fields.
|
106
|
-
REQUIRED_INHERITABLE_FIELDS = [:Resources, :MediaBox]
|
106
|
+
REQUIRED_INHERITABLE_FIELDS = [:Resources, :MediaBox].freeze
|
107
107
|
|
108
108
|
|
109
109
|
define_field :Type, type: Symbol, required: true, default: :Page
|
@@ -150,9 +150,9 @@ module HexaPDF
|
|
150
150
|
# See: Dictionary#[]
|
151
151
|
def [](name)
|
152
152
|
if value[name].nil? && INHERITABLE_FIELDS.include?(name)
|
153
|
-
node = self
|
154
|
-
node = node[:Parent] while node.value[name].nil? && node
|
155
|
-
node[name]
|
153
|
+
node = self
|
154
|
+
node = node[:Parent] while node.value[name].nil? && node[:Parent]
|
155
|
+
node == self || node.value[name].nil? ? super : node[name]
|
156
156
|
else
|
157
157
|
super
|
158
158
|
end
|
@@ -248,6 +248,21 @@ module HexaPDF
|
|
248
248
|
Content::Parser.parse(contents, processor)
|
249
249
|
end
|
250
250
|
|
251
|
+
# Returns the index of the page in the page tree.
|
252
|
+
def index
|
253
|
+
idx = 0
|
254
|
+
node = self
|
255
|
+
while (parent_node = node[:Parent])
|
256
|
+
parent_node[:Kids].each do |kid|
|
257
|
+
kid = document.deref(kid)
|
258
|
+
break if kid.data == node.data
|
259
|
+
idx += (kid.type == :Page ? 1 : kid[:Count])
|
260
|
+
end
|
261
|
+
node = parent_node
|
262
|
+
end
|
263
|
+
idx
|
264
|
+
end
|
265
|
+
|
251
266
|
# Returns the requested type of canvas for the page.
|
252
267
|
#
|
253
268
|
# The canvas object is cached once it is created so that its graphics state is correctly
|
@@ -151,44 +151,37 @@ module HexaPDF
|
|
151
151
|
insert_page(-1, page)
|
152
152
|
end
|
153
153
|
|
154
|
-
#
|
155
|
-
#
|
154
|
+
# :call-seq:
|
155
|
+
# pages.delete_page(page) -> page or nil
|
156
|
+
# pages.delete_page(index) -> page or nil
|
156
157
|
#
|
157
|
-
#
|
158
|
+
# Deletes the given page or the page at the position specified by the zero-based index from
|
159
|
+
# the page tree and returns the deleted page object. If the page was not deleted, +nil+ is
|
160
|
+
# returned.
|
158
161
|
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
|
162
|
-
|
163
|
-
|
162
|
+
# Note that the page is *not* deleted from the document itself, only from the page tree! This
|
163
|
+
# also means that the /Parent entry of the page is set to +nil+ if deleted.
|
164
|
+
#
|
165
|
+
# Negative indices count backwards from the end, i.e. -1 is the last page.
|
166
|
+
def delete_page(page)
|
167
|
+
page = self.page(page) if page.kind_of?(Integer)
|
168
|
+
return nil unless page && page[:Parent]
|
164
169
|
|
165
|
-
|
166
|
-
|
167
|
-
self[:Kids].each_with_index do |kid, kid_index|
|
168
|
-
kid = document.deref(kid)
|
169
|
-
if kid.type == :Page && index == 0
|
170
|
-
page = self[:Kids].delete_at(kid_index)
|
171
|
-
document.delete(page)
|
172
|
-
break
|
173
|
-
elsif kid.type == :Page
|
174
|
-
index -= 1
|
175
|
-
elsif index < kid[:Count]
|
176
|
-
page = kid.delete_page(index)
|
177
|
-
if kid[:Count] == 0
|
178
|
-
self[:Kids].delete_at(kid_index)
|
179
|
-
document.delete(kid)
|
180
|
-
elsif kid[:Count] == 1
|
181
|
-
self[:Kids][kid_index] = kid[:Kids][0]
|
182
|
-
kid[:Kids][0][:Parent] = self
|
183
|
-
document.delete(kid)
|
184
|
-
end
|
185
|
-
break
|
186
|
-
else
|
187
|
-
index -= kid[:Count]
|
188
|
-
end
|
189
|
-
end
|
170
|
+
parent = page[:Parent]
|
171
|
+
index = parent[:Kids].index {|kid| document.deref(kid).data == page.data}
|
190
172
|
|
191
|
-
|
173
|
+
if index
|
174
|
+
ancestors = [parent]
|
175
|
+
ancestors << parent while (parent = parent[:Parent])
|
176
|
+
return nil unless ancestors.include?(self)
|
177
|
+
|
178
|
+
page[:Parent][:Kids].delete_at(index)
|
179
|
+
page.delete(:Parent)
|
180
|
+
ancestors.each {|node| node[:Count] -= 1 }
|
181
|
+
page
|
182
|
+
else
|
183
|
+
nil
|
184
|
+
end
|
192
185
|
end
|
193
186
|
|
194
187
|
# :call-seq:
|
@@ -84,7 +84,7 @@ module HexaPDF
|
|
84
84
|
|
85
85
|
private
|
86
86
|
|
87
|
-
LENGTH_TO_TYPE = {4 => 'N', 2 => 'n', 1 => 'C'} # :nodoc:
|
87
|
+
LENGTH_TO_TYPE = {4 => 'N', 2 => 'n', 1 => 'C'}.freeze # :nodoc:
|
88
88
|
FOUR_TO_INFINITY = 4..Float::INFINITY # :nodoc:
|
89
89
|
|
90
90
|
# Fills the bit cache so that at least 16bit are available (if possible).
|
@@ -81,7 +81,7 @@ module HexaPDF
|
|
81
81
|
\u00e0 \u00e1 \u00e2 \u00e3 \u00e4 \u00e5 \u00e6 \u00e7
|
82
82
|
\u00e8 \u00e9 \u00ea \u00eb \u00ec \u00ed \u00ee \u00ef
|
83
83
|
\u00f0 \u00f1 \u00f2 \u00f3 \u00f4 \u00f5 \u00f6 \u00f7
|
84
|
-
\u00f8 \u00f9 \u00fa \u00fb \u00fc \u00fd \u00fe \u00ff]
|
84
|
+
\u00f8 \u00f9 \u00fa \u00fb \u00fc \u00fd \u00fe \u00ff].freeze
|
85
85
|
|
86
86
|
# Converts the given string to UTF-8, assuming it contains bytes in PDFDocEncoding.
|
87
87
|
def self.convert_to_utf8(str)
|
data/lib/hexapdf/version.rb
CHANGED
data/man/man1/hexapdf.1
CHANGED
@@ -1,249 +1,321 @@
|
|
1
|
-
.\" generated
|
2
|
-
|
3
|
-
.
|
4
|
-
.TH "HEXAPDF" "1" "October 2016" "" ""
|
5
|
-
.
|
6
|
-
.SH "NAME"
|
1
|
+
.\" generated by kramdown
|
2
|
+
.TH "HEXAPDF" "1" "November 2016"
|
3
|
+
.SH NAME
|
7
4
|
hexapdf \- A Versatile PDF Manipulation Application
|
8
|
-
.
|
9
5
|
.SH "SYNOPSIS"
|
10
|
-
\fBhexapdf\
|
11
|
-
.
|
6
|
+
\fBhexapdf\fP [\fBOPTIONS\fP] \fBcommand\fP [\fBCOMMAND OPTIONS\fP]\.\.\.
|
12
7
|
.SH "DESCRIPTION"
|
13
|
-
hexapdf is an application for PDF manipulation\. It is part of the
|
14
|
-
.
|
8
|
+
hexapdf is an application for PDF manipulation\. It is part of the
|
9
|
+
.UR http://hexapdf\.gettalong\.org
|
10
|
+
hexapdf
|
11
|
+
.UE
|
12
|
+
library which also allows PDF creation, among other things\.
|
15
13
|
.P
|
16
14
|
Using the hexapdf application the following tasks can be performed with PDF files:
|
17
|
-
.
|
18
|
-
.
|
19
|
-
|
20
|
-
|
21
|
-
.IP
|
22
|
-
Showing general information of a PDF file (see the \fBinfo\
|
23
|
-
.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
.
|
28
|
-
|
29
|
-
|
30
|
-
.IP "" 0
|
31
|
-
.
|
32
|
-
.P
|
33
|
-
The application contains a built\-in \fBhelp\fR command that can be used to provide a quick reminder of a command\'s purpose and its options\.
|
34
|
-
.
|
15
|
+
.sp
|
16
|
+
.PD 0
|
17
|
+
.IP \(bu 4
|
18
|
+
Extracting embedded files (see the \fBextract\fP command)
|
19
|
+
.IP \(bu 4
|
20
|
+
Showing general information of a PDF file (see the \fBinfo\fP command)
|
21
|
+
.IP \(bu 4
|
22
|
+
Inspecting the internal structure of a PDF file (see the \fBinspect\fP command)
|
23
|
+
.IP \(bu 4
|
24
|
+
Modifying an existing PDF file (see the \fBmodify\fP command)
|
25
|
+
.PD
|
26
|
+
.P
|
27
|
+
The application contains a built\-in \fBhelp\fP command that can be used to provide a quick reminder of a command\[u2019]s purpose and its options\.
|
35
28
|
.SH "OPTIONS"
|
36
29
|
The following options can only be used when no command is specified:
|
37
|
-
.
|
38
30
|
.TP
|
39
|
-
\fB\-v\
|
31
|
+
\fB\-v\fP, \fB\-\-version\fP
|
40
32
|
Show the version of the hexapdf application and exit\.
|
41
|
-
.
|
42
33
|
.P
|
43
34
|
These options are available on every command (except if they are overridden):
|
44
|
-
.
|
45
35
|
.TP
|
46
|
-
\fB\-h\
|
36
|
+
\fB\-h\fP, \fB\-\-help\fP
|
47
37
|
Show the help for the application if no command was specified, or the command help otherwise\.
|
48
|
-
.
|
49
38
|
.SH "COMMANDS"
|
50
|
-
hexapdf uses a command\-style interface\. This means that it provides different functionalities depending on the used command and each command can have its own options\.
|
51
|
-
.
|
39
|
+
hexapdf uses a command\-style interface\. This means that it provides different functionalities depending on the used command, and each command can have its own options\.
|
52
40
|
.P
|
53
|
-
There is no need to write the full command name for hexapdf to understand it, the only requirement is that is must be unambiguous\. So using \fBe\
|
54
|
-
.
|
41
|
+
There is no need to write the full command name for hexapdf to understand it, the only requirement is that is must be unambiguous\. So using \fBe\fP for the \fBextract\fP command is sufficient\.
|
55
42
|
.SS "extract"
|
56
|
-
Synopsis: \fBextract\
|
57
|
-
.
|
43
|
+
Synopsis: \fBextract\fP [\fBOPTIONS\fP] \fIFILE\fP
|
58
44
|
.P
|
59
|
-
This command extracts embedded files from the PDF \fIFILE\
|
60
|
-
.
|
45
|
+
This command extracts embedded files from the PDF \fIFILE\fP\&\. If the \fB\-\-indices\fP option is not specified, the names and indices of the embedded files are just listed\.
|
61
46
|
.TP
|
62
|
-
\fB\-i\
|
63
|
-
The indices of the embedded files that should be extract\. The value \fI0\
|
64
|
-
.
|
47
|
+
\fB\-i\fP \fIA,B,C,\.\.\.\fP, \fB\-\-indices\fP \fIA,B,C,\.\.\.\fP
|
48
|
+
The indices of the embedded files that should be extract\. The value \fI0\fP can be used to extract all embedded files\.
|
65
49
|
.TP
|
66
|
-
\fB\-s\
|
67
|
-
Search the whole PDF file instead of the standard locations,
|
68
|
-
.
|
50
|
+
\fB\-s\fP, \fB\-\-[no\-]search\fP
|
51
|
+
Search the whole PDF file instead of the standard locations, that is files attached to the document as a whole or to an individual page\. Defaults to \fIfalse\fP\&\.
|
69
52
|
.TP
|
70
|
-
\fB\-p\
|
71
|
-
The password to decrypt the PDF \fIFILE\
|
72
|
-
.
|
53
|
+
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
54
|
+
The password to decrypt the PDF \fIFILE\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
73
55
|
.SS "help"
|
74
|
-
Synopsis: \fBhelp\
|
75
|
-
.
|
56
|
+
Synopsis: \fBhelp\fP [\fICOMMAND\fP\.\.\.]
|
76
57
|
.P
|
77
58
|
This command prints the application help if no arguments are given\. If one or more command names are given as arguments, these arguments are interpreted as a list of commands with sub\-commands and the help for the innermost command is shown\.
|
78
|
-
.
|
79
59
|
.SS "info"
|
80
|
-
Synopsis: \fBinfo\
|
81
|
-
.
|
60
|
+
Synopsis: \fBinfo\fP [\fBOPTIONS\fP] \fIFILE\fP
|
82
61
|
.P
|
83
|
-
This command reads the \fIFILE\
|
84
|
-
.
|
62
|
+
This command reads the \fIFILE\fP and shows general information about it, like author information, PDF version used, encryption information and so on\.
|
85
63
|
.TP
|
86
|
-
\fB\-p\
|
87
|
-
The password to decrypt the PDF \fIFILE\
|
88
|
-
.
|
64
|
+
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
65
|
+
The password to decrypt the PDF \fIFILE\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
89
66
|
.SS "inspect"
|
90
|
-
Synopsis: \fBinspect\
|
91
|
-
.
|
67
|
+
Synopsis: \fBinspect\fP [\fBOPTIONS\fP] \fIFILE\fP
|
92
68
|
.P
|
93
69
|
This command is useful when one needs to inspect the internal object structure or a stream of a PDF file\.
|
94
|
-
.
|
95
70
|
.P
|
96
|
-
If no option is given, the main PDF object, the catalog, is shown\. Otherwise the various, mutually exclusive display options define what is shown\. If multiple such options are specified only the last one is respected\. Note that PDF objects are always shown in the PDF syntax\.
|
97
|
-
.
|
71
|
+
If no option is given, the main PDF object, the catalog, is shown\. Otherwise the various, mutually exclusive display options define what is shown\. If multiple such options are specified only the last one is respected\. Note that PDF objects are always shown in the native PDF syntax\.
|
98
72
|
.TP
|
99
|
-
\fB\-t\
|
73
|
+
\fB\-t\fP, \fB\-\-trailer\fP
|
100
74
|
Show the trailer dictionary\.
|
101
|
-
.
|
102
75
|
.TP
|
103
|
-
\fB\-c\
|
76
|
+
\fB\-c\fP, \fB\-\-page\-count\fP
|
104
77
|
Print the number of pages\.
|
105
|
-
.
|
106
78
|
.TP
|
107
|
-
\fB\-\-pages\
|
108
|
-
Show the pages with their object and generation numbers and their associated content streams\. If a range is specified, only those pages are listed\. See the \fBPAGES SPECIFICATION\
|
109
|
-
.
|
79
|
+
\fB\-\-pages\fP [\fIPAGES\fP]
|
80
|
+
Show the pages with their object and generation numbers and their associated content streams\. If a range is specified, only those pages are listed\. See the \fBPAGES SPECIFICATION\fP below for details on the allowed format of \fIPAGES\fP\&\.
|
110
81
|
.TP
|
111
|
-
\fB\-o\
|
82
|
+
\fB\-o\fP \fIOID\fP[,\fIGEN\fP], \fB\-\-object\fP \fIOID\fP[,\fIGEN\fP]
|
112
83
|
Show the object with the given object and generation numbers\. The generation number defaults to 0 if not given\.
|
113
|
-
.
|
114
84
|
.TP
|
115
|
-
\fB\-s\
|
116
|
-
Show the filtered stream data (add \fB\-\-raw\
|
117
|
-
.
|
85
|
+
\fB\-s\fP \fIOID\fP[,\fIGEN\fP], \fB\-\-stream\fP \fIOID\fP[,\fIGEN\fP]
|
86
|
+
Show the filtered stream data (add \fB\-\-raw\fP to get the raw stream data) of the object with the given object and generation numbers\. The generation number defaults to 0 if not given\.
|
118
87
|
.TP
|
119
|
-
\fB\-\-raw\
|
120
|
-
Modifies \fB\-\-stream\
|
121
|
-
.
|
88
|
+
\fB\-\-raw\fP
|
89
|
+
Modifies \fB\-\-stream\fP to show the raw stream data instead of the filtered one\.
|
122
90
|
.TP
|
123
|
-
\fB\-p\
|
124
|
-
The password to decrypt the PDF \fIFILE\
|
125
|
-
.
|
91
|
+
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
92
|
+
The password to decrypt the PDF \fIFILE\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
126
93
|
.SS "modify"
|
127
|
-
Synopsis: \fBmodify\
|
128
|
-
.
|
94
|
+
Synopsis: \fBmodify\fP [\fBOPTIONS\fP] { \fB\-\-f\fP \fIINPUT\fP | \fB\-\-empty\fP } \fIOUTPUT\fP
|
95
|
+
.P
|
96
|
+
This command modifies a PDF file\. It can be used to select pages that should appear in the output file and to add pages from other PDF files (i\.e\. merging PDF files)\. The output file can be encrypted/decrypted and optimized in various ways\.
|
97
|
+
.P
|
98
|
+
The first input file is the primary file which gets modified, so meta data like file information, outlines, etc\. are taken from it\. Alternatively, it is possible to start with an empty PDF file by using \fB\-\-empty\fP\&\. The order of the options specifying the input files is important as the pages are added in that order\. Note that the \fB\-\-password\fP and \fB\-\-pages\fP options always apply to the last preceeding input file\.
|
99
|
+
.P
|
100
|
+
An input file can be specified multiple times, using a different \fB\-\-pages\fP option each time\. The \fB\-\-password\fP option, if needed, only needs to be used the first time\.
|
129
101
|
.P
|
130
|
-
|
131
|
-
.
|
102
|
+
Input file related options:
|
132
103
|
.TP
|
133
|
-
\fB\-
|
134
|
-
|
135
|
-
.
|
104
|
+
\fB\-f\fP \fIFILE\fP, \fB\-\-file\fP \fIFILE\fP
|
105
|
+
An input file\. At least one input file or \fB\-\-empty\fP needs be used\.
|
136
106
|
.TP
|
137
|
-
\fB\-\-
|
138
|
-
The
|
139
|
-
.
|
107
|
+
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
108
|
+
The password to decrypt the last input file specified with \fB\-\-file\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
109
|
+
.TP
|
110
|
+
\fB\-i\fP \fIPAGES\fP, \fB\-\-pages\fP \fIPAGES\fP
|
111
|
+
The pages (optionally rotated) from the last input file specified with the \fB\-\-file\fP option that should be included in the \fIOUTPUT\fP\&\. See the \fBPAGES SPECIFICATION\fP below for details on the allowed format of \fIPAGES\fP\&\. Default: \fI1\-e\fP (i\.e\. all pages with no additional rotation applied)\.
|
112
|
+
.TP
|
113
|
+
\fB\-e\fP, \fB\-\-empty\fP
|
114
|
+
Use an empty file as primary file\. This will lead to an output file that just contains the included pages of the input file and no other data from the input files\.
|
115
|
+
.TP
|
116
|
+
\fB\-\-interleave\fP
|
117
|
+
Interleave the pages from the input files: Takes the first specified page from the first input file, then the first specified page from the second input file, and so on\. After that the same with the second, third, \.\.\. specified pages\. If fewer pages were specified for an input file, the input file is just skipped for the rest of the rounds\.
|
118
|
+
.P
|
119
|
+
Output file related options:
|
140
120
|
.TP
|
141
|
-
\fB\-\-embed\
|
142
|
-
Embed the given file into the \
|
143
|
-
.
|
121
|
+
\fB\-\-embed\fP \fIFILE\fP
|
122
|
+
Embed the given file into the \fIOUTPUT\fP using built\-in features of PDF\. This option can be used multiple times to embed more than one file\.
|
144
123
|
.TP
|
145
|
-
\fB\-\-[no\-]compact\
|
146
|
-
Delete unnecessary PDF objects\. This includes merging the base revision and all incremental updates into a single revision\. Default: \fIyes\
|
147
|
-
.
|
124
|
+
\fB\-\-[no\-]compact\fP
|
125
|
+
Delete unnecessary PDF objects\. This includes merging the base revision and all incremental updates into a single revision\. Default: \fIyes\fP\&\.
|
148
126
|
.TP
|
149
|
-
\fB\-\-object\-streams
|
150
|
-
Defines how object streams should be treated: \fIgenerate\
|
151
|
-
.
|
127
|
+
\fB\-\-object\-streams\fP \fIMODE\fP
|
128
|
+
Defines how object streams should be treated: \fIgenerate\fP will remove all exisiting object streams and generate new ones, \fIdelete\fP will only remove existing object streams and \fIpreserve\fP will do nothing\. Default: \fIpreserve\fP\&\.
|
152
129
|
.TP
|
153
|
-
\fB\-\-xref\-streams
|
154
|
-
Defines how cross\-reference streams should be treated: \fIgenerate\
|
155
|
-
.
|
130
|
+
\fB\-\-xref\-streams\fP \fIMODE\fP
|
131
|
+
Defines how cross\-reference streams should be treated: \fIgenerate\fP will add them, \fIdelete\fP will remove them and \fIpreserve\fP will do nothing\. Default: \fIpreserve\fP\&\.
|
156
132
|
.TP
|
157
|
-
\fB\-\-streams
|
158
|
-
Defines how streams should be treated: \fIcompress\
|
159
|
-
.
|
133
|
+
\fB\-\-streams\fP \fIMODE\fP
|
134
|
+
Defines how streams should be treated: \fIcompress\fP will compress them when possible, \fIuncompress\fP will uncompress them when possible and \fIpreserve\fP will do nothing to them\. Default: \fIpreserve\fP\&\.
|
135
|
+
.TP
|
136
|
+
\fB\-\-[no\-]compress\-pages\fP
|
137
|
+
Recompress page content streams\. This is a very expensive operation in terms of processing time and won\[u2019]t lead to great file size improvements in many cases\. Default: \fIno\fP\&\.
|
160
138
|
.P
|
161
|
-
|
162
|
-
.
|
139
|
+
Output file encryption related options (all options except \fB\-\-decrypt\fP automatically enable \fB\-\-encrypt\fP):
|
163
140
|
.TP
|
164
|
-
\fB\-\-decrypt\
|
141
|
+
\fB\-\-decrypt\fP
|
165
142
|
Remove any encryption\.
|
166
|
-
.
|
167
|
-
.
|
168
|
-
If neither \fB\-\-decrypt\
|
169
|
-
.
|
170
|
-
.TP
|
171
|
-
\fB\-\-encrypt\
|
172
|
-
Encrypt the \
|
173
|
-
.
|
174
|
-
.
|
175
|
-
If neither \fB\-\-decrypt\
|
176
|
-
.
|
177
|
-
.TP
|
178
|
-
\fB\-\-owner\-password\
|
179
|
-
The owner password to be set on the \
|
180
|
-
.
|
181
|
-
.
|
182
|
-
|
183
|
-
.
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
.
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
.
|
200
|
-
|
201
|
-
|
202
|
-
.
|
203
|
-
.TP
|
204
|
-
\fB\-\-
|
205
|
-
|
206
|
-
.
|
207
|
-
|
208
|
-
|
209
|
-
.
|
143
|
+
.RS
|
144
|
+
.P
|
145
|
+
If neither \fB\-\-decrypt\fP nor \fB\-\-encrypt\fP are specified, the existing encryption configuration is preserved\.
|
146
|
+
.RE
|
147
|
+
.TP
|
148
|
+
\fB\-\-encrypt\fP
|
149
|
+
Encrypt the \fIOUTPUT\fP\&\.
|
150
|
+
.RS
|
151
|
+
.P
|
152
|
+
If neither \fB\-\-decrypt\fP nor \fB\-\-encrypt\fP are specified, the existing encryption configuration is preserved\.
|
153
|
+
.RE
|
154
|
+
.TP
|
155
|
+
\fB\-\-owner\-password\fP \fIPASSWORD\fP
|
156
|
+
The owner password to be set on the \fIOUTPUT\fP\&\. This password is needed when operations not allowed by the permissions need to be done\. It can also be used when opening the PDF file\.
|
157
|
+
.RS
|
158
|
+
.P
|
159
|
+
If an owner password is set but no user password, the output file can be opened without a password but the operations are restricted as if a user password were set\.
|
160
|
+
.P
|
161
|
+
Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
162
|
+
.RE
|
163
|
+
.TP
|
164
|
+
\fB\-\-user\-password\fP \fIPASSWORD\fP
|
165
|
+
The user password to be set on the \fIOUTPUT\fP\&\. This password is needed when opening the PDF file\. The application should restrict the operations to those allowed by the permissions\.
|
166
|
+
.RS
|
167
|
+
.P
|
168
|
+
Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
169
|
+
.RE
|
170
|
+
.TP
|
171
|
+
\fB\-\-algorithm\fP \fIALGORITHM\fP
|
172
|
+
The encryption algorithm to use on the \fIOUTPUT\fP\&\. Allowed algorithms are \fIaes\fP and \fIarc4\fP but \fIarc4\fP should only be used if it is absolutely necessary for compatibility reasons\. Default: \fIaes\fP\&\.
|
173
|
+
.TP
|
174
|
+
\fB\-\-key\-length\fP \fIBITS\fP
|
175
|
+
The length of the encryption key in bits\. The allowed values differ based on the chosen algorithm: A number divisible by eight between 40 to 128 for \fIarc4\fP and 128 or 256 for \fIaes\fP\&\. Default: \fB128\fP\&\.
|
176
|
+
.RS
|
177
|
+
.P
|
178
|
+
Note: Using 256bit AES encryption can lead to problems viewing the PDF in many applications on various platforms!
|
179
|
+
.RE
|
180
|
+
.TP
|
181
|
+
\fB\-\-force\-V4\fP
|
182
|
+
Force the use of PDF encryption version 4 if key length is \fI128\fP and algorithm is \fIarc4\fP\&\. This option is probably only useful for testing the implementation of PDF libraries\[u2019] encryption handling\.
|
183
|
+
.TP
|
184
|
+
\fB\-\-permissions\fP \fIPERMS\fP
|
185
|
+
A comma separated list of permissions to be set on the \fIOUTPUT\fP:
|
186
|
+
.RS
|
187
|
+
.TP
|
188
|
+
\fIprint\fP
|
189
|
+
allow printing
|
190
|
+
.TP
|
191
|
+
\fImodify_content\fP
|
192
|
+
allow modification of the content of pages
|
193
|
+
.TP
|
194
|
+
\fIcopy_content\fP
|
195
|
+
allow text extraction and similar operations
|
196
|
+
.TP
|
197
|
+
\fImodify_annotation\fP
|
198
|
+
allow creation and modification of annotations and filling in of forms
|
199
|
+
.TP
|
200
|
+
\fIfill_in_forms\fP
|
201
|
+
allow filling in of forms even if \fImodify_annotation\fP is not set
|
202
|
+
.TP
|
203
|
+
\fIextract_content\fP
|
204
|
+
allow text and graphics extraction in accessibility cases
|
205
|
+
.TP
|
206
|
+
\fIassemble_document\fP
|
207
|
+
allow page modifications and bookmark creation
|
208
|
+
.TP
|
209
|
+
\fIhigh_quality_print\fP
|
210
|
+
allow high quality printing
|
211
|
+
.RE
|
210
212
|
.SS "version"
|
211
|
-
This command shows the version of the hexapdf application\. It is an alternative to using the global \fB\-\-version\
|
212
|
-
.
|
213
|
+
This command shows the version of the hexapdf application\. It is an alternative to using the global \fB\-\-version\fP option\.
|
213
214
|
.SH "PAGES SPECIFICATION"
|
214
|
-
Some commands allow the specification of pages using a \fIPAGES\
|
215
|
-
.
|
215
|
+
Some commands allow the specification of pages using a \fIPAGES\fP argument\. This argument is expected to be a comma separated list of single page numbers or page ranges of the form \fISTART\fP\-\fIEND\fP\&\. The character \[u2018]\fBe\fP\[u2019] represents the last page and can be used instead of a single number or in a range\. The pages are used in the order in which the are specified\.
|
216
|
+
.P
|
217
|
+
If the start number of a page range is higher than the end number, the pages are used in the reverse order\.
|
218
|
+
.P
|
219
|
+
Step values can be used with page ranges\. If a range is followed by \fI/STEP\fP, \fISTEP\fP \- 1 pages are skipped after each used page\.
|
220
|
+
.P
|
221
|
+
Additionally, the page numbers and ranges can be suffixed with a rotation modifier:
|
222
|
+
.sp
|
223
|
+
.PD 0
|
224
|
+
.TP
|
225
|
+
\fBl\fP
|
226
|
+
Rotate the page left, that is 90 degrees counterclockwise
|
227
|
+
.TP
|
228
|
+
\fBr\fP
|
229
|
+
Rotate the page right, that is 90 degrees clockwise
|
230
|
+
.TP
|
231
|
+
\fBd\fP
|
232
|
+
Rotate the page 180 degrees
|
233
|
+
.TP
|
234
|
+
\fBn\fP
|
235
|
+
Remove any set page rotation
|
236
|
+
.PD
|
216
237
|
.P
|
217
|
-
|
218
|
-
.
|
238
|
+
Note that this additional functionality may not be used by all commands (it is used, for example, by the \fBmodify\fP command)\.
|
219
239
|
.P
|
220
240
|
Examples:
|
221
|
-
.
|
222
|
-
|
223
|
-
\
|
224
|
-
|
225
|
-
.IP
|
226
|
-
\
|
227
|
-
.
|
228
|
-
|
229
|
-
\
|
230
|
-
|
231
|
-
.IP
|
232
|
-
\
|
233
|
-
.
|
234
|
-
|
235
|
-
|
236
|
-
.
|
237
|
-
|
238
|
-
.
|
241
|
+
.IP \(bu 4
|
242
|
+
\fB1,2,3\fP: The pages 1, 2 and 3\.
|
243
|
+
.IP \(bu 4
|
244
|
+
\fB11,4\-9,1,e\fP: The pages 11, 4 to 9, 1 and the last page, in exactly this order\.
|
245
|
+
.IP \(bu 4
|
246
|
+
\fB1\-e\fP: All pages of the document\.
|
247
|
+
.IP \(bu 4
|
248
|
+
\fBe\-1\fP: All pages of the document in reverse order\.
|
249
|
+
.IP \(bu 4
|
250
|
+
\fB1\-5/2\fP: The pages 1, 3 and 5\.
|
251
|
+
.IP \(bu 4
|
252
|
+
\fB10\-1/3\fP: The pages 10, 7, 4 and 1\.
|
253
|
+
.IP \(bu 4
|
254
|
+
\fB1l,2r,3\-5d,6n\fP: The pages 1 (rotated left), 2 (rotated right), 3 to 5 (all rotated 180 degrees) and 6 (any possibly set rotation removed)\.
|
255
|
+
.SH "Examples"
|
256
|
+
.SS "modify"
|
257
|
+
\fBhexapdf modify \-\-file input\.pdf \-\-object\-stream generate output\.pdf\fP
|
258
|
+
.br
|
259
|
+
\fBhexapdf m \-f input\.pdf \-\-obj g output\.pdf\fP
|
260
|
+
.P
|
261
|
+
Compressing: Both commands do exactly the same, compressing the \fBinput\.pdf\fP to get a smaller file size\. Howver, the second command uses the feature of abbreviating commands and options to their shortest unambiguous name so that less key presses are required\.
|
262
|
+
.P
|
263
|
+
\fBhexapdf modify \-f input1\.pdf \-f input2\.pdf \-f input3\.pdf output\.pdf\fP
|
264
|
+
.br
|
265
|
+
\fBhexapdf modify \-e \-f input1\.pdf \-f input2\.pdf \-f input3\.pdf output\.pdf\fP
|
266
|
+
.P
|
267
|
+
Merging: In the first case use \fBinput1\.pdf\fP as primary input file and merge the pages from \fBinput2\.pdf\fP and \fBinput3\.pdf\fP into it\. In the second case an empty PDF file is used for merging the pages from the three given input files into it; the resulting output file will not have an meta data or other additional data from the first input file\.
|
268
|
+
.P
|
269
|
+
\fBhexapdf modify \-f odd\.pdf \-f even\.pdf \-\-interleave combined\.pdf\fP
|
270
|
+
.P
|
271
|
+
Page interleaving: Takes alternatly a page from \fBodd\.pdf\fP and \fBeven\.pdf\fP to create the output file\. This is very useful if you only have a simplex scanner: First you scan the front sides, creating \fBodd\.pdf\fP, and then you scan the back sides, creating \fBeven\.pdf\fP\&\. With the command the pages can be ordered in the correct way\.
|
272
|
+
.P
|
273
|
+
\fBhexapdf modify \-f input\.pdf \-i 1\-5,7\-10,12\-e output\.pdf\fP
|
274
|
+
.P
|
275
|
+
Page removal: Remove the pages 6 and 12 from the \fBinput\.pdf\fP\&\.
|
276
|
+
.P
|
277
|
+
\fBhexapdf modify \-f input\.pdf \-i 1r,2\-ed output\.pdf\fP
|
278
|
+
.P
|
279
|
+
Page rotation: Rotate the first page to the right, that is 90 degrees clockwise, and all other pages 180 degrees\.
|
280
|
+
.P
|
281
|
+
\fBhexapdf modify \-f input\.pdf \-\-user\-password my_pwd \-\-permissions print output\.pdf\fP
|
282
|
+
.P
|
283
|
+
Encryption: Encrypt the \fBoutput\.pdf\fP so that a password is needed to open it, and only allow printing\.
|
284
|
+
.P
|
285
|
+
\fBhexapdf modify \-f input\.pdf \-p input_password \-\-decrypt output\.pdf\fP
|
286
|
+
.P
|
287
|
+
Encryption removal: Create the \fBoutput\.pdf\fP as copy of \fBinput\.pdf\fP but with the encryption removed\. If the \fB\-\-decrypt\fP was not used, the output file would retain the encryption specification of the primary input file\.
|
288
|
+
.SS "extract"
|
289
|
+
\fBhexapdf extract input\.pdf\fP
|
290
|
+
.br
|
291
|
+
\fBhexapdf extract input\.pdf \-i 1\fP
|
292
|
+
.P
|
293
|
+
Embedded files: The first command lists the embedded files in the \fBinput\.pdf\fP, the second one then extracts the embedded file with the index 1\.
|
294
|
+
.SS "info"
|
295
|
+
\fBhexapdf info input\.pdf\fP
|
296
|
+
.P
|
297
|
+
File information: Show general information about the PDF file, like PDF version, number of pages, creator, creation date and encryption related information\.
|
298
|
+
.SS "inspect"
|
299
|
+
\fBhexapdf inspect input\.pdf\fP
|
300
|
+
.br
|
301
|
+
\fBhexapdf inspect input\.pdf \-o 3\fP
|
302
|
+
.P
|
303
|
+
Inspect a PDF: These commands can be used to inspect the internal object structure of a PDF file\. The first command shows the PDF catalog object, the main object of a PDF file\. The second one shows the object with the object number 3\.
|
239
304
|
.SH "EXIT STATUS"
|
240
305
|
The exit status is 0 if no error happened\. Otherwise it is 1\.
|
241
|
-
.
|
242
306
|
.SH "SEE ALSO"
|
243
|
-
The
|
244
|
-
.
|
307
|
+
The
|
308
|
+
.UR http://hexapdf\.gettalong\.org
|
309
|
+
hexapdf website
|
310
|
+
.UE
|
311
|
+
for more information\.
|
245
312
|
.SH "AUTHOR"
|
246
|
-
hexapdf was written by Thomas Leitner
|
247
|
-
.
|
313
|
+
hexapdf was written by Thomas Leitner
|
314
|
+
.MT t_leitner@gmx\.at
|
315
|
+
.UE
|
316
|
+
\&\.
|
248
317
|
.P
|
249
|
-
This manual page was written by Thomas Leitner
|
318
|
+
This manual page was written by Thomas Leitner
|
319
|
+
.MT t_leitner@gmx\.at
|
320
|
+
.UE
|
321
|
+
\&\.
|