hexapdf 0.11.1 → 0.11.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -0
- data/lib/hexapdf/cli/image2pdf.rb +3 -3
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document.rb +5 -0
- data/lib/hexapdf/document/pages.rb +4 -0
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +22 -5
- data/lib/hexapdf/font/true_type/table/hmtx.rb +15 -5
- data/lib/hexapdf/image_loader/png.rb +3 -3
- data/lib/hexapdf/layout/text_box.rb +8 -3
- data/lib/hexapdf/layout/text_layouter.rb +1 -0
- data/lib/hexapdf/rectangle.rb +2 -2
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +4 -4
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +5 -5
- data/test/hexapdf/layout/test_text_box.rb +20 -2
- data/test/hexapdf/layout/test_text_layouter.rb +30 -11
- data/test/hexapdf/test_dictionary_fields.rb +8 -0
- data/test/hexapdf/test_writer.rb +2 -2
- metadata +3 -7
- data/CONTRIBUTERS +0 -5
- data/VERSION +0 -1
- data/man/man1/hexapdf.1 +0 -596
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60a5bf5332e0ebf949653852c2f77a7a78861b120bf0c5eed30ee6591cd0736e
|
4
|
+
data.tar.gz: 79c8495ffcf48c4d81180ab9aa39e5ee12386f0a015ccef2460e453a879609d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded53b4977a8caafc8811b80f42fd0e137fed0af84072ee864a30f02ac729d5327f85840c2f7eb21426a5f3beee8caa6b2d40f91e0521180f161db8ccad86a48
|
7
|
+
data.tar.gz: c1f7c2fb6e6fd2eacef1d11421768844471d0b048bf0eb36558f6a0a6426eed3438db1309aa17e3cd4e7a1e973affab946b52073c10ad7a37e0d9c3ce46cf3b8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,51 @@
|
|
1
|
+
## 0.11.6 - 2020-05-27
|
2
|
+
|
3
|
+
### Fixed
|
4
|
+
|
5
|
+
* [HexaPDF::Layout::TextBox] to respect the set width and height when fitting
|
6
|
+
and splitting the box
|
7
|
+
|
8
|
+
|
9
|
+
## 0.11.5 - 2020-01-27
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
* [HexaPDF::Font::TrueType::Table::CmapSubtable] to lazily parse the subtable
|
14
|
+
* [HexaPDF::Font::TrueType::Table::Hmtx] to lazily parse the width data
|
15
|
+
* CLI command `hexapdf image2pdf` to use the last argument as output file
|
16
|
+
instead of the first (same order as `merge`)
|
17
|
+
* Automatically require the HexaPDF C extension if it is installed
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
* Wrong line length calculation for variable width layouting when a text box is
|
22
|
+
too wide and needs to be broken into parts
|
23
|
+
* CLI command `hexapdf image2pdf` so that treating a PDF as image works
|
24
|
+
|
25
|
+
|
26
|
+
## 0.11.4 - 2019-12-28
|
27
|
+
|
28
|
+
### Fixed
|
29
|
+
|
30
|
+
* Memory consumption problem of PNG image loader when using images with alpha
|
31
|
+
channel
|
32
|
+
|
33
|
+
|
34
|
+
## 0.11.3 - 2019-11-27
|
35
|
+
|
36
|
+
### Fixed
|
37
|
+
|
38
|
+
* Restore compatibility with Ruby 2.4
|
39
|
+
|
40
|
+
|
41
|
+
## 0.11.2 - 2019-11-22
|
42
|
+
|
43
|
+
### Fixed
|
44
|
+
|
45
|
+
* Conversion of [HexaPDF::Rectangle] type when the original is not a plain
|
46
|
+
Array but a [HexaPDF::PDFArray]
|
47
|
+
|
48
|
+
|
1
49
|
## 0.11.1 - 2019-11-19
|
2
50
|
|
3
51
|
### Fixed
|
@@ -99,15 +99,15 @@ module HexaPDF
|
|
99
99
|
@margins = [0, 0, 0, 0]
|
100
100
|
end
|
101
101
|
|
102
|
-
def execute(
|
102
|
+
def execute(*images, out_file) #:nodoc:
|
103
103
|
maybe_raise_on_existing_file(out_file)
|
104
104
|
|
105
105
|
out = HexaPDF::Document.new
|
106
106
|
|
107
107
|
images.each do |image_file|
|
108
108
|
image = out.images.add(image_file)
|
109
|
-
iw = image.
|
110
|
-
ih = image.
|
109
|
+
iw = image.width.to_f
|
110
|
+
ih = image.height.to_f
|
111
111
|
if @scale != :fit
|
112
112
|
iw *= 72 / @scale
|
113
113
|
ih *= 72 / @scale
|
@@ -351,7 +351,7 @@ module HexaPDF
|
|
351
351
|
|
352
352
|
# Wraps a given array in the Rectangle class. Otherwise returns +nil+.
|
353
353
|
def self.convert(data, _type, document)
|
354
|
-
return unless data.kind_of?(Array)
|
354
|
+
return unless data.kind_of?(Array) || data.kind_of?(HexaPDF::PDFArray)
|
355
355
|
document.wrap(data, type: Rectangle)
|
356
356
|
end
|
357
357
|
|
data/lib/hexapdf/document.rb
CHANGED
@@ -52,6 +52,11 @@ require 'hexapdf/image_loader'
|
|
52
52
|
require 'hexapdf/font_loader'
|
53
53
|
require 'hexapdf/layout'
|
54
54
|
|
55
|
+
begin
|
56
|
+
require 'hexapdf/cext'
|
57
|
+
rescue LoadError
|
58
|
+
end
|
59
|
+
|
55
60
|
# == HexaPDF API Documentation
|
56
61
|
#
|
57
62
|
# Here are some pointers to more in depth information:
|
@@ -107,6 +107,8 @@ module HexaPDF
|
|
107
107
|
# Deletes the given page object from the document's page tree (but *not* from the document).
|
108
108
|
#
|
109
109
|
# Returns the page object, or +nil+ if the page object was not in the page tree.
|
110
|
+
#
|
111
|
+
# Also see: HexaPDF::Type::PageTreeNode#delete_page
|
110
112
|
def delete(page)
|
111
113
|
@document.catalog.pages.delete_page(page)
|
112
114
|
end
|
@@ -118,6 +120,8 @@ module HexaPDF
|
|
118
120
|
# document).
|
119
121
|
#
|
120
122
|
# Returns the page object, or +nil+ if the index was invalid.
|
123
|
+
#
|
124
|
+
# Also see: HexaPDF::Type::PageTreeNode#delete_page
|
121
125
|
def delete_at(index)
|
122
126
|
@document.catalog.pages.delete_page(index)
|
123
127
|
end
|
@@ -73,9 +73,14 @@ module HexaPDF
|
|
73
73
|
attr_accessor :language
|
74
74
|
|
75
75
|
# The complete code map.
|
76
|
+
#
|
77
|
+
# Is only fully initialized for existing fonts when a mapping is first accessed via #[].
|
76
78
|
attr_accessor :code_map
|
77
79
|
|
78
80
|
# The complete gid map.
|
81
|
+
#
|
82
|
+
# Is only fully initialized for existing fonts when a mapping is first accessed via
|
83
|
+
# #gid_to_code.
|
79
84
|
attr_accessor :gid_map
|
80
85
|
|
81
86
|
# Creates a new subtable.
|
@@ -127,7 +132,22 @@ module HexaPDF
|
|
127
132
|
elsif [0, 2, 4, 6].include?(@format)
|
128
133
|
length, @language = io.read(4).unpack('n2')
|
129
134
|
end
|
130
|
-
|
135
|
+
|
136
|
+
return false unless [0, 2, 4, 6, 10, 12].include?(@format)
|
137
|
+
offset = io.pos
|
138
|
+
@code_map = lambda do |code|
|
139
|
+
parse_mapping(io, offset, length)
|
140
|
+
@code_map[code]
|
141
|
+
end
|
142
|
+
@gid_map = lambda do |gid|
|
143
|
+
parse_mapping(io, offset, length)
|
144
|
+
@gid_map[gid]
|
145
|
+
end
|
146
|
+
true
|
147
|
+
end
|
148
|
+
|
149
|
+
def parse_mapping(io, offset, length)
|
150
|
+
io.pos = offset
|
131
151
|
@code_map, @gid_map = case @format
|
132
152
|
when 0 then Format0.parse(io, length)
|
133
153
|
when 2 then Format2.parse(io, length)
|
@@ -135,12 +155,9 @@ module HexaPDF
|
|
135
155
|
when 6 then Format6.parse(io, length)
|
136
156
|
when 10 then Format10.parse(io, length)
|
137
157
|
when 12 then Format12.parse(io, length)
|
138
|
-
else
|
139
|
-
supported = false
|
140
|
-
[{}, {}]
|
141
158
|
end
|
142
|
-
supported
|
143
159
|
end
|
160
|
+
private :parse_mapping
|
144
161
|
|
145
162
|
def inspect #:nodoc:
|
146
163
|
"#<#{self.class.name} (#{platform_id}, #{encoding_id}, #{language}, " \
|
@@ -51,7 +51,7 @@ module HexaPDF
|
|
51
51
|
# the :left_side_bearing.
|
52
52
|
Metric = Struct.new(:advance_width, :left_side_bearing)
|
53
53
|
|
54
|
-
#
|
54
|
+
# A hash of glyph ID to Metric objects mapping.
|
55
55
|
attr_accessor :horizontal_metrics
|
56
56
|
|
57
57
|
# Returns the Metric object for the give glyph ID.
|
@@ -63,10 +63,20 @@ module HexaPDF
|
|
63
63
|
|
64
64
|
def parse_table #:nodoc:
|
65
65
|
nr_entries = font[:hhea].num_of_long_hor_metrics
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
max_id = nr_entries + (directory_entry.length - 4 * nr_entries) / 2
|
67
|
+
@horizontal_metrics = Hash.new do |hash, glyph_id|
|
68
|
+
return nil if glyph_id >= max_id
|
69
|
+
if glyph_id >= nr_entries
|
70
|
+
with_io_pos(directory_entry.offset + 4 * nr_entries + (glyph_id - nr_entries) * 2) do
|
71
|
+
hash[glyph_id] = Metric.new(@horizontal_metrics[nr_entries - 1].advance_width,
|
72
|
+
*read_formatted(2, 's>'))
|
73
|
+
end
|
74
|
+
else
|
75
|
+
with_io_pos(directory_entry.offset + 4 * glyph_id) do
|
76
|
+
hash[glyph_id] = Metric.new(*read_formatted(4, 'ns>'))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
hash[glyph_id]
|
70
80
|
end
|
71
81
|
end
|
72
82
|
|
@@ -361,12 +361,12 @@ module HexaPDF
|
|
361
361
|
image_data << data.getbyte(0)
|
362
362
|
mask_data << data.getbyte(0)
|
363
363
|
while i < bytes_per_row
|
364
|
-
image_data << data.
|
364
|
+
bytes_per_colors.times {|j| image_data << data.getbyte(i + j) }
|
365
365
|
i += bytes_per_colors
|
366
|
-
mask_data << data.
|
366
|
+
bytes_per_alpha.times {|j| mask_data << data.getbyte(i + j) }
|
367
367
|
i += bytes_per_alpha
|
368
368
|
end
|
369
|
-
data[
|
369
|
+
data = data[bytes_per_row..-1]
|
370
370
|
end
|
371
371
|
end
|
372
372
|
|
@@ -64,6 +64,9 @@ module HexaPDF
|
|
64
64
|
#
|
65
65
|
# Also see TextLayouter#style for other style properties taken into account.
|
66
66
|
def fit(available_width, available_height, frame)
|
67
|
+
return false if (@initial_width > 0 && @initial_width > available_width) ||
|
68
|
+
(@initial_height > 0 && @initial_height > available_height)
|
69
|
+
|
67
70
|
@width = @height = 0
|
68
71
|
@result = if style.position == :flow
|
69
72
|
@tl.fit(@items, frame.width_specification, frame.contour_line.bbox.height)
|
@@ -74,8 +77,8 @@ module HexaPDF
|
|
74
77
|
height = (@initial_height > 0 ? @initial_height : available_height) - @height
|
75
78
|
@tl.fit(@items, width, height)
|
76
79
|
end
|
77
|
-
@width += @result.lines.max_by(&:width)&.width || 0
|
78
|
-
@height += @result.height
|
80
|
+
@width += (@initial_width > 0 ? width : @result.lines.max_by(&:width)&.width || 0)
|
81
|
+
@height += (@initial_height > 0 ? height : @result.height)
|
79
82
|
if style.last_line_gap && @result.lines.last
|
80
83
|
@height += style.line_spacing.gap(@result.lines.last, @result.lines.last)
|
81
84
|
end
|
@@ -86,7 +89,9 @@ module HexaPDF
|
|
86
89
|
# Splits the text box into two boxes if necessary and possible.
|
87
90
|
def split(available_width, available_height, frame)
|
88
91
|
fit(available_width, available_height, frame) unless @result
|
89
|
-
if @
|
92
|
+
if @width > available_width || @height > available_height
|
93
|
+
[nil, self]
|
94
|
+
elsif @result.remaining_items.empty?
|
90
95
|
[self]
|
91
96
|
elsif @result.lines.empty?
|
92
97
|
[nil, self]
|
data/lib/hexapdf/rectangle.rb
CHANGED
@@ -96,7 +96,7 @@ module HexaPDF
|
|
96
96
|
# top right corner.
|
97
97
|
def after_data_change
|
98
98
|
super
|
99
|
-
unless value.size == 4 && all?(Numeric)
|
99
|
+
unless value.size == 4 && all? {|v| v.kind_of?(Numeric) }
|
100
100
|
raise ArgumentError, "A PDF rectangle structure must contain an array of four numbers"
|
101
101
|
end
|
102
102
|
self[0], self[2] = self[2], self[0] if self[0] > self[2]
|
@@ -105,7 +105,7 @@ module HexaPDF
|
|
105
105
|
|
106
106
|
def perform_validation #:nodoc:
|
107
107
|
super
|
108
|
-
unless value.size == 4 && all?(Numeric)
|
108
|
+
unless value.size == 4 && all? {|v| v.kind_of?(Numeric) }
|
109
109
|
yield("A PDF rectangle structure must contain an array of four numbers", false)
|
110
110
|
end
|
111
111
|
end
|
data/lib/hexapdf/version.rb
CHANGED
@@ -43,14 +43,14 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
|
|
43
43
|
|
44
44
|
it "works for format 0" do
|
45
45
|
t = table([0, 262, 0].pack('n3') + [255].pack('C*') + (0..254).to_a.pack('C*'))
|
46
|
+
assert_equal(0, t.gid_to_code(255))
|
47
|
+
assert_equal(234, t.gid_to_code(233))
|
48
|
+
|
46
49
|
assert_equal(255, t[0])
|
47
50
|
assert_equal(233, t[234])
|
48
51
|
assert_nil(t[256])
|
49
52
|
|
50
|
-
|
51
|
-
assert_equal(234, t.gid_to_code(233))
|
52
|
-
|
53
|
-
assert_raises(HexaPDF::Error) { table([0, 20, 0].pack('n3') + "a" * 20) }
|
53
|
+
assert_raises(HexaPDF::Error) { table([0, 20, 0].pack('n3') + "a" * 20)[0] }
|
54
54
|
end
|
55
55
|
|
56
56
|
it "works for format 2" do
|
@@ -5,7 +5,7 @@ require_relative 'common'
|
|
5
5
|
require 'hexapdf/font/true_type/table/hhea'
|
6
6
|
require 'hexapdf/font/true_type/table/hmtx'
|
7
7
|
|
8
|
-
describe HexaPDF::Font::TrueType::Table::
|
8
|
+
describe HexaPDF::Font::TrueType::Table::Hmtx do
|
9
9
|
before do
|
10
10
|
data = [1, -2, 3, -4, 5, -6].pack('ns>ns>s>2')
|
11
11
|
set_up_stub_true_type_font(data)
|
@@ -17,14 +17,14 @@ describe HexaPDF::Font::TrueType::Table::Hhea do
|
|
17
17
|
describe "initialize" do
|
18
18
|
it "reads the data from the associated file" do
|
19
19
|
table = create_table(:Hmtx)
|
20
|
-
assert_equal(1, table[0].advance_width)
|
21
|
-
assert_equal(-2, table[0].left_side_bearing)
|
22
|
-
assert_equal(3, table[1].advance_width)
|
23
|
-
assert_equal(-4, table[1].left_side_bearing)
|
24
20
|
assert_equal(3, table[2].advance_width)
|
25
21
|
assert_equal(5, table[2].left_side_bearing)
|
26
22
|
assert_equal(3, table[3].advance_width)
|
27
23
|
assert_equal(-6, table[3].left_side_bearing)
|
24
|
+
assert_equal(1, table[0].advance_width)
|
25
|
+
assert_equal(-2, table[0].left_side_bearing)
|
26
|
+
assert_equal(3, table[1].advance_width)
|
27
|
+
assert_equal(-4, table[1].left_side_bearing)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -31,11 +31,11 @@ describe HexaPDF::Layout::TextBox do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "respects the set width and height" do
|
34
|
-
box = create_box([@inline_box]
|
34
|
+
box = create_box([@inline_box], width: 40, height: 50, style: {padding: 10})
|
35
35
|
assert(box.fit(100, 100, @frame))
|
36
36
|
assert_equal(40, box.width)
|
37
37
|
assert_equal(50, box.height)
|
38
|
-
assert_equal([
|
38
|
+
assert_equal([10], box.instance_variable_get(:@result).lines.map(&:width))
|
39
39
|
end
|
40
40
|
|
41
41
|
it "fits into the frame's outline" do
|
@@ -52,6 +52,16 @@ describe HexaPDF::Layout::TextBox do
|
|
52
52
|
assert_equal(50, box.width)
|
53
53
|
assert_equal(20, box.height)
|
54
54
|
end
|
55
|
+
|
56
|
+
it "can't fit the text box if the set width is bigger than the available width" do
|
57
|
+
box = create_box([@inline_box], width: 101)
|
58
|
+
refute(box.fit(100, 100, @frame))
|
59
|
+
end
|
60
|
+
|
61
|
+
it "can't fit the text box if the set height is bigger than the available height" do
|
62
|
+
box = create_box([@inline_box], height: 101)
|
63
|
+
refute(box.fit(100, 100, @frame))
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
57
67
|
describe "split" do
|
@@ -70,6 +80,14 @@ describe HexaPDF::Layout::TextBox do
|
|
70
80
|
assert_equal([nil, box], box.split(5, 20, @frame))
|
71
81
|
end
|
72
82
|
|
83
|
+
it "works if the whole text box doesn't fits" do
|
84
|
+
box = create_box([@inline_box], width: 102)
|
85
|
+
assert_equal([nil, box], box.split(100, 100, @frame))
|
86
|
+
|
87
|
+
box = create_box([@inline_box], height: 102)
|
88
|
+
assert_equal([nil, box], box.split(100, 100, @frame))
|
89
|
+
end
|
90
|
+
|
73
91
|
it "splits the box if necessary" do
|
74
92
|
box = create_box([@inline_box] * 10)
|
75
93
|
boxes = box.split(50, 10, @frame)
|
@@ -556,18 +556,37 @@ describe HexaPDF::Layout::TextLayouter do
|
|
556
556
|
end
|
557
557
|
end
|
558
558
|
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
assert_equal(:success, result.status)
|
565
|
-
assert_equal(str.strip.length, result.lines.sum {|l| l.items.sum {|i| i.items.count } })
|
566
|
-
assert_equal(45, result.height)
|
559
|
+
describe "breaks a text fragment into parts if it is wider than the available width" do
|
560
|
+
before do
|
561
|
+
@str = " This is averylongstring"
|
562
|
+
@frag = HexaPDF::Layout::TextFragment.create(@str, font: @font)
|
563
|
+
end
|
567
564
|
|
568
|
-
|
569
|
-
|
570
|
-
|
565
|
+
it "works with fixed width" do
|
566
|
+
result = @layouter.fit([@frag], 20, 100)
|
567
|
+
assert(result.remaining_items.empty?)
|
568
|
+
assert_equal(:success, result.status)
|
569
|
+
assert_equal(@str.delete(" ").length, result.lines.sum {|l| l.items.sum {|i| i.items.count } })
|
570
|
+
assert_equal(54, result.height)
|
571
|
+
|
572
|
+
result = @layouter.fit([@frag], 1, 100)
|
573
|
+
assert_equal(8, result.remaining_items.count)
|
574
|
+
assert_equal(:box_too_wide, result.status)
|
575
|
+
end
|
576
|
+
|
577
|
+
it "works with variable width" do
|
578
|
+
width_block = lambda do |height, line_height|
|
579
|
+
# 'averylongstring' would fit when only considering height but not height + line_height
|
580
|
+
if height + line_height < 15
|
581
|
+
63
|
582
|
+
else
|
583
|
+
10
|
584
|
+
end
|
585
|
+
end
|
586
|
+
result = @layouter.fit([@frag], width_block, 30)
|
587
|
+
assert_equal(:height, result.status)
|
588
|
+
assert_equal([26.95, 9.44, 7.77], result.lines.map {|l| l.width.round(3) })
|
589
|
+
end
|
571
590
|
end
|
572
591
|
|
573
592
|
describe "horizontal alignment" do
|
@@ -226,5 +226,13 @@ describe HexaPDF::DictionaryFields do
|
|
226
226
|
@field.convert([0, 1, 2, 3], doc)
|
227
227
|
doc.verify
|
228
228
|
end
|
229
|
+
|
230
|
+
it "allows conversion to a Rectangle from a HexaPDF::PDFArray" do
|
231
|
+
data = HexaPDF::PDFArray.new([0, 1, 2, 3])
|
232
|
+
doc = Minitest::Mock.new
|
233
|
+
doc.expect(:wrap, :data, [data, type: HexaPDF::Rectangle])
|
234
|
+
@field.convert(data, doc)
|
235
|
+
doc.verify
|
236
|
+
end
|
229
237
|
end
|
230
238
|
end
|
data/test/hexapdf/test_writer.rb
CHANGED
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
|
|
40
40
|
219
|
41
41
|
%%EOF
|
42
42
|
3 0 obj
|
43
|
-
<</Producer(HexaPDF version 0.11.
|
43
|
+
<</Producer(HexaPDF version 0.11.6)>>
|
44
44
|
endobj
|
45
45
|
xref
|
46
46
|
3 1
|
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
|
|
72
72
|
141
|
73
73
|
%%EOF
|
74
74
|
6 0 obj
|
75
|
-
<</Producer(HexaPDF version 0.11.
|
75
|
+
<</Producer(HexaPDF version 0.11.6)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hexapdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Leitner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdparse
|
@@ -102,11 +102,9 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- CHANGELOG.md
|
105
|
-
- CONTRIBUTERS
|
106
105
|
- LICENSE
|
107
106
|
- README.md
|
108
107
|
- Rakefile
|
109
|
-
- VERSION
|
110
108
|
- agpl-3.0.txt
|
111
109
|
- bin/hexapdf
|
112
110
|
- data/hexapdf/afm/Courier-Bold.afm
|
@@ -401,7 +399,6 @@ files:
|
|
401
399
|
- lib/hexapdf/version.rb
|
402
400
|
- lib/hexapdf/writer.rb
|
403
401
|
- lib/hexapdf/xref_section.rb
|
404
|
-
- man/man1/hexapdf.1
|
405
402
|
- test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz
|
406
403
|
- test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz
|
407
404
|
- test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz
|
@@ -637,8 +634,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
637
634
|
- !ruby/object:Gem::Version
|
638
635
|
version: '0'
|
639
636
|
requirements: []
|
640
|
-
|
641
|
-
rubygems_version: 2.7.3
|
637
|
+
rubygems_version: 3.0.3
|
642
638
|
signing_key:
|
643
639
|
specification_version: 4
|
644
640
|
summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
data/CONTRIBUTERS
DELETED
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.11.1
|
data/man/man1/hexapdf.1
DELETED
@@ -1,596 +0,0 @@
|
|
1
|
-
.\" generated by kramdown
|
2
|
-
.TH "HEXAPDF" "1" "November 2016"
|
3
|
-
.SH NAME
|
4
|
-
hexapdf \- A Versatile PDF Manipulation Application
|
5
|
-
.SH "SYNOPSIS"
|
6
|
-
\fBhexapdf\fP [\fBOPTIONS\fP] \fBcommand\fP [\fBCOMMAND OPTIONS\fP]\.\.\.
|
7
|
-
.SH "DESCRIPTION"
|
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\.
|
13
|
-
.P
|
14
|
-
Using the hexapdf application the following tasks can be performed with PDF files:
|
15
|
-
.sp
|
16
|
-
.PD 0
|
17
|
-
.IP \(bu 4
|
18
|
-
Modifying an existing PDF file (see the \fBmodify\fP command)
|
19
|
-
.IP \(bu 4
|
20
|
-
Merging multiple PDF files into one (see the \fBmerge\fP command)
|
21
|
-
.IP \(bu 4
|
22
|
-
Splitting a PDF file into individual pages (see the \fBsplit\fP command)
|
23
|
-
.IP \(bu 4
|
24
|
-
Optimizing the file size of a PDF file (see the \fBoptimize\fP command)
|
25
|
-
.IP \(bu 4
|
26
|
-
Watermarking/Stamping a PDF onto another one (see the \fBwatermark\fP command)
|
27
|
-
.IP \(bu 4
|
28
|
-
Extracting embedded files (see the \fBfiles\fP command)
|
29
|
-
.IP \(bu 4
|
30
|
-
Extracting images (see the \fBimages\fP command)
|
31
|
-
.IP \(bu 4
|
32
|
-
Converting images to PDF (see the \fBimage2pdf\fP command)
|
33
|
-
.IP \(bu 4
|
34
|
-
Showing general information of a PDF file (see the \fBinfo\fP command)
|
35
|
-
.IP \(bu 4
|
36
|
-
Batch execution of a command on multiple PDF files (see the \fBbatch\fP command)
|
37
|
-
.IP \(bu 4
|
38
|
-
Inspecting the internal structure of a PDF file (see the \fBinspect\fP command)
|
39
|
-
.PD
|
40
|
-
.P
|
41
|
-
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\.
|
42
|
-
.SH "OPTIONS"
|
43
|
-
The following options can only be used when no command is specified:
|
44
|
-
.TP
|
45
|
-
\fB\-v\fP, \fB\-\-version\fP
|
46
|
-
Show the version of the hexapdf application and exit\.
|
47
|
-
.P
|
48
|
-
These options are available on every command (except if they are overridden):
|
49
|
-
.TP
|
50
|
-
\fB\-\-[no\-]force\fP
|
51
|
-
Force overwriting existing files\. Default: \fIfalse\fP\&\.
|
52
|
-
.TP
|
53
|
-
\fB\-\-strict\fP
|
54
|
-
Enable strict parsing and validation\. By default, correctable parse error and validation problems are treated as warnings which allows processing most PDF files\. If this option is used, correctable parse errors and uncorrectable validation problems are treated as errors\.
|
55
|
-
.RS
|
56
|
-
.P
|
57
|
-
Note that a PDF file may have validation errors and still be usable since most viewing applications are very forgiving\.
|
58
|
-
.RE
|
59
|
-
.TP
|
60
|
-
\fB\-\-verbose\fP, \fB\-v\fP
|
61
|
-
Enable more verbose output\. There are three verbosity levels: 0 (no output), 1 (warning output) and 2 (warning and informational output)\. The default level is 1, specifying this option increases it to 2\.
|
62
|
-
.TP
|
63
|
-
\fB\-\-quiet\fP
|
64
|
-
Suppress any output by setting the verbosity level to 0\. Also see the description of \fB\-\-verbose\fP above\.
|
65
|
-
.TP
|
66
|
-
\fB\-h\fP, \fB\-\-help\fP
|
67
|
-
Show the help for the application if no command was specified, or the command help otherwise\.
|
68
|
-
.SS "Optimization Options"
|
69
|
-
Theses options can only be used with the \fBmerge\fP, \fBmodify\fP and \fBoptimize\fP commands and control optimization aspects when writing an output PDF file\. Note that the defaults maybe different depending on the command\.
|
70
|
-
.TP
|
71
|
-
\fB\-\-[no\-]compact\fP
|
72
|
-
Delete unnecessary PDF objects\. This includes merging the base revision and all incremental updates into a single revision\. Default: \fIyes\fP\&\.
|
73
|
-
.TP
|
74
|
-
\fB\-\-object\-streams\fP \fIMODE\fP
|
75
|
-
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\&\.
|
76
|
-
.TP
|
77
|
-
\fB\-\-xref\-streams\fP \fIMODE\fP
|
78
|
-
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\&\.
|
79
|
-
.TP
|
80
|
-
\fB\-\-streams\fP \fIMODE\fP
|
81
|
-
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\&\.
|
82
|
-
.TP
|
83
|
-
\fB\-\-[no\-]compress\-pages\fP
|
84
|
-
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\&\.
|
85
|
-
.TP
|
86
|
-
\fB\-\-[no\-]optimize\-fonts\fP
|
87
|
-
Optimize embedded font files by removing normally unneeded font data\. Note that this may have a negative effect on PDFs with forms since form entry usually requires fully embedded font files\. Default: \fIno\fP\&\.
|
88
|
-
.SS "Encryption Options"
|
89
|
-
These options can only be used with the \fBmerge\fP and \fBmodify\fP commands and control if and how an output PDF file should be encrypted\. All options except \fB\-\-decrypt\fP automatically enable \fB\-\-encrypt\fP\&\.
|
90
|
-
.P
|
91
|
-
Note that if a password is needed to open the input file and if encryption parameters are changed, the provided password is not automatically used for the output file!
|
92
|
-
.TP
|
93
|
-
\fB\-\-decrypt\fP
|
94
|
-
Remove any encryption\.
|
95
|
-
.RS
|
96
|
-
.P
|
97
|
-
If neither \fB\-\-decrypt\fP nor \fB\-\-encrypt\fP are specified, the existing encryption configuration is preserved\.
|
98
|
-
.RE
|
99
|
-
.TP
|
100
|
-
\fB\-\-encrypt\fP
|
101
|
-
Encrypt the \fIOUTPUT\fP\&\.
|
102
|
-
.RS
|
103
|
-
.P
|
104
|
-
If neither \fB\-\-decrypt\fP nor \fB\-\-encrypt\fP are specified, the existing encryption configuration is preserved\.
|
105
|
-
.RE
|
106
|
-
.TP
|
107
|
-
\fB\-\-owner\-password\fP \fIPASSWORD\fP
|
108
|
-
The owner password to be set on the output file\. 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\.
|
109
|
-
.RS
|
110
|
-
.P
|
111
|
-
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\.
|
112
|
-
.P
|
113
|
-
Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
114
|
-
.RE
|
115
|
-
.TP
|
116
|
-
\fB\-\-user\-password\fP \fIPASSWORD\fP
|
117
|
-
The user password to be set on the output file\. This password is needed when opening the PDF file\. The application should restrict the operations to those allowed by the permissions\.
|
118
|
-
.RS
|
119
|
-
.P
|
120
|
-
Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
121
|
-
.RE
|
122
|
-
.TP
|
123
|
-
\fB\-\-algorithm\fP \fIALGORITHM\fP
|
124
|
-
The encryption algorithm to use on the output file\. 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\&\.
|
125
|
-
.TP
|
126
|
-
\fB\-\-key\-length\fP \fIBITS\fP
|
127
|
-
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\&\.
|
128
|
-
.RS
|
129
|
-
.P
|
130
|
-
Note: Using 256bit AES encryption can lead to problems viewing the PDF in many applications on various platforms!
|
131
|
-
.RE
|
132
|
-
.TP
|
133
|
-
\fB\-\-force\-V4\fP
|
134
|
-
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\.
|
135
|
-
.TP
|
136
|
-
\fB\-\-permissions\fP \fIPERMS\fP
|
137
|
-
A comma separated list of permissions to be set on the output file:
|
138
|
-
.RS
|
139
|
-
.TP
|
140
|
-
\fIprint\fP
|
141
|
-
allow printing
|
142
|
-
.TP
|
143
|
-
\fImodify_content\fP
|
144
|
-
allow modification of the content of pages
|
145
|
-
.TP
|
146
|
-
\fIcopy_content\fP
|
147
|
-
allow text extraction and similar operations
|
148
|
-
.TP
|
149
|
-
\fImodify_annotation\fP
|
150
|
-
allow creation and modification of annotations and filling in of forms
|
151
|
-
.TP
|
152
|
-
\fIfill_in_forms\fP
|
153
|
-
allow filling in of forms even if \fImodify_annotation\fP is not set
|
154
|
-
.TP
|
155
|
-
\fIextract_content\fP
|
156
|
-
allow text and graphics extraction in accessibility cases
|
157
|
-
.TP
|
158
|
-
\fIassemble_document\fP
|
159
|
-
allow page modifications and bookmark creation
|
160
|
-
.TP
|
161
|
-
\fIhigh_quality_print\fP
|
162
|
-
allow high quality printing
|
163
|
-
.RE
|
164
|
-
.SH "COMMANDS"
|
165
|
-
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\.
|
166
|
-
.P
|
167
|
-
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 \fBf\fP for the \fBfiles\fP command is sufficient\. The same is true for long option names and option values\.
|
168
|
-
.P
|
169
|
-
Any command that reads and writes a PDF file may do in\-place processing of the file\. This is automatically done if an input file name is the same as the output file name\. Note that the option \fB\-\-force\fP has to be used in this case\.
|
170
|
-
.SS "batch"
|
171
|
-
Synopsis: \fBbatch\fP \fICOMMAND\fP \fIFILES\.\.\.\fP
|
172
|
-
.P
|
173
|
-
This command allows executing a single command for multiple input files, thereby reducing the overall execution time\.
|
174
|
-
.P
|
175
|
-
The first argument \fICOMMAND\fP is used as a hexapdf command line and must not contain the binary name, just everything else\. The rest of the arguments are the input files\. The specified command will be executed for each input file, with all occurences of {} being replaced by the file name\.
|
176
|
-
.SS "files"
|
177
|
-
Synopsis: \fBfiles\fP [\fBOPTIONS\fP] \fIPDF\fP
|
178
|
-
.P
|
179
|
-
This command extracts embedded files from the \fIPDF\fP\&\. If the \fB\-\-extract\fP option is not specified, the indices and names of the embedded files are just listed\.
|
180
|
-
.TP
|
181
|
-
\fB\-e\fP [\fIA,B,C,\.\.\.\fP], \fB\-\-extract\fP [\fIA,B,C,\.\.\.\fP]
|
182
|
-
The indices of the embedded files that should be extracted\. The value \fI0\fP can be used to extract all embedded files\.
|
183
|
-
.TP
|
184
|
-
\fB\-s\fP, \fB\-\-[no\-]search\fP
|
185
|
-
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\&\.
|
186
|
-
.TP
|
187
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
188
|
-
The password to decrypt the \fIPDF\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
189
|
-
.SS "help"
|
190
|
-
Synopsis: \fBhelp\fP [\fICOMMAND\fP\.\.\.]
|
191
|
-
.P
|
192
|
-
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\.
|
193
|
-
.SS "images"
|
194
|
-
Synopsis: \fBimages\fP [\fBOPTIONS\fP] \fIPDF\fP
|
195
|
-
.P
|
196
|
-
This command extracts images from the \fIPDF\fP\&\. If the \fB\-\-extract\fP option is not specified, the images are listed with their indices and additional information, sorted by page number\. Note that if an image is used multiple times on a page, only the first occurence of it will be included\.
|
197
|
-
.P
|
198
|
-
The \fB\-\-extract\fP option can then be used to extract one or more images, saving them to files called \fBPREFIX\-N\.EXT\fP where the prefix can be set via \fB\-\-prefix\fP, \fIN\fP is the image index and \fIEXT\fP is either png, jpg or jpx\.
|
199
|
-
.TP
|
200
|
-
\fB\-e\fP [\fIA,B,C,\.\.\.\fP], \fB\-\-extract\fP [\fIA,B,C,\.\.\.\fP]
|
201
|
-
The indices of the images that should be extracted\. Use \fI0\fP or no value to extract all images\.
|
202
|
-
.TP
|
203
|
-
\fB\-\-prefix\fP \fIPREFIX\fP
|
204
|
-
The prefix to use when saving images\. May include directories\. Defaults to \fIimage\fP\&\.
|
205
|
-
.TP
|
206
|
-
\fB\-s\fP, \fB\-\-[no\-]search\fP
|
207
|
-
Search the whole PDF file instead of the standard locations, that is, images referenced by pages\. Defaults to \fIfalse\fP\&\.
|
208
|
-
.TP
|
209
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
210
|
-
The password to decrypt the \fIPDF\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
211
|
-
.P
|
212
|
-
The following information is shown for each image when listing images:
|
213
|
-
.RS
|
214
|
-
.TP
|
215
|
-
\fBindex\fP
|
216
|
-
The image index needed when this image should be extracted\.
|
217
|
-
.TP
|
218
|
-
\fBpage\fP
|
219
|
-
The page number on which this image appears\.
|
220
|
-
.TP
|
221
|
-
\fBoid\fP
|
222
|
-
The PDF internal object identifier consisting of the object and generation numbers\.
|
223
|
-
.TP
|
224
|
-
\fBwidth\fP
|
225
|
-
The width of the image in pixels\.
|
226
|
-
.TP
|
227
|
-
\fBheight\fP
|
228
|
-
The height of the image in pixels\.
|
229
|
-
.TP
|
230
|
-
\fBcolor\fP
|
231
|
-
The color space used for the image\. Either gray, rgb, cmyk or other\.
|
232
|
-
.TP
|
233
|
-
\fBcomp\fP
|
234
|
-
The number of color components\.
|
235
|
-
.TP
|
236
|
-
\fBbpc\fP
|
237
|
-
The number of bits per color component\.
|
238
|
-
.TP
|
239
|
-
\fBx\-ppi\fP
|
240
|
-
The pixels per inch (PPI) of the x\-direction of the image, as found on the page\.
|
241
|
-
.TP
|
242
|
-
\fBy\-ppi\fP
|
243
|
-
The pixels per inch (PPI) of the y\-direction of the image, as found on the page\.
|
244
|
-
.TP
|
245
|
-
\fBsize\fP
|
246
|
-
The file size of the image as stored in the PDF\.
|
247
|
-
.TP
|
248
|
-
\fBtype\fP
|
249
|
-
The image type\. Either jpg (JPEG), jp2 (JPEG2000), ccitt (CCITT Group 3 or 4 Fax), jbig2 (JBIG2) or png (PNG)\.
|
250
|
-
.TP
|
251
|
-
\fBwritable\fP
|
252
|
-
Either true or false depending on whether hexapdf supports the image format\.
|
253
|
-
.RE
|
254
|
-
.SS "image2pdf"
|
255
|
-
Synopsis: \fBiamge2pdf\fP [\fBOPTIONS\fP] \fIOUTPUT\fP [\fIIMAGES\fP\.\.\.]
|
256
|
-
.P
|
257
|
-
This command converts one or more images into a single PDF file, one image per page\. The various options allow setting a page size, scaling the images and defining margins\. Images are always centered on the pages\.
|
258
|
-
.P
|
259
|
-
Supported image formats are JPEG, PNG and PDF\. Images in PNG format may take longer to process due to the way they are stored inside a PDF\.
|
260
|
-
.TP
|
261
|
-
\fB\-p\fP \fIPAGE_SIZE\fP, \fB\-\-page\-size\fP \fIPAGE_SIZE\fP
|
262
|
-
The PDF page size\. The default value of \fIauto\fP chooses the page size based on the image dimensions\. Either \fIauto\fP which chooses a size based on the image size or a valid page size like \fIA4\fP, \fIA4\-landscape\fP or \fI595x842\fP\&\. The \fI\-landscape\fP suffix can be added to any predefined page size\.
|
263
|
-
.RS
|
264
|
-
.P
|
265
|
-
Common page sizes are \fIA4\fP, \fIA5\fP, \fIA3\fP, \fILetter\fP and \fILegal\fP\&\.
|
266
|
-
.RE
|
267
|
-
.TP
|
268
|
-
\fB\-\-[no\-]auto\-rotate\fP
|
269
|
-
If enabled (the default) pages are automatically rotated so that the pages and images always have the same orientation\. I\.e\. landscape\-oriented images go on landscape page, portrait\-oriented images on portrait pages\.
|
270
|
-
.RS
|
271
|
-
.P
|
272
|
-
Note that pages won\[u2019]t be rotated if scaling is used and the image would fit into the requested page size\.
|
273
|
-
.RE
|
274
|
-
.TP
|
275
|
-
\fB\-s\fP \fISCALE\fP, \fB\-\-scale\fP \fISCALE\fP
|
276
|
-
Defines how the images should be scaled\. The default value of \fIfit\fP scales the images so that they optimally fit the pages\. Otherwise \fISCALE\fP is interpreted as the minimum number of pixels per inch (PPI) that the images should have\.
|
277
|
-
.TP
|
278
|
-
\fB\-m\fP \fIMARGINS\fP, \fB\-\-margins\fP \fIMARGINS\fP
|
279
|
-
Defines the margins around the images\. The argument \fIMARGINS\fP can either be a single number specifying the margin on all four sides, or four numbers separated by commas (like \fB10,20,30,40\fP) specifying the top, right, bottom and left margins\. Default: \fI0\fP\&\.
|
280
|
-
.P
|
281
|
-
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
282
|
-
.SS "info"
|
283
|
-
Synopsis: \fBinfo\fP [\fBOPTIONS\fP] \fIFILE\fP
|
284
|
-
.P
|
285
|
-
This command reads the \fIFILE\fP and shows general information about it, like author information, PDF version used, encryption information and so on\.
|
286
|
-
.TP
|
287
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
288
|
-
The password to decrypt the PDF \fIFILE\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
289
|
-
.SS "inspect"
|
290
|
-
Synopsis: \fBinspect\fP [\fBOPTIONS\fP] \fIFILE\fP \fI[[CMD [ARGS]]\.\.\.]\fP
|
291
|
-
.P
|
292
|
-
This command is useful when one needs to inspect the internal object structure or a stream of a PDF file\.
|
293
|
-
.P
|
294
|
-
If no arguments are given, the interactive mode is started\. This interactive mode allows you to execute inspection commands without re\-parsing the PDF file, leading to better performance for big PDF files\.
|
295
|
-
.P
|
296
|
-
Otherwise the arguments are interpreted as interactive mode commands and executed\. It is possible to specify more than one command in this way by separating them with semicolons, or whitespace in case the number of command arguments is fixed\.
|
297
|
-
.TP
|
298
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
299
|
-
The password to decrypt the PDF \fIFILE\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
300
|
-
.P
|
301
|
-
If an interactive mode command or argument is \fBOID[,GEN]\fP, object and generation numbers are expected\. The generation number defaults to 0 if not given\. PDF objects are always shown in the native PDF syntax\.
|
302
|
-
.P
|
303
|
-
The available commands are:
|
304
|
-
.TP
|
305
|
-
\fBOID[,GEN] | o[bject] OID[,GEN]\fP
|
306
|
-
Print the given indirect object\.
|
307
|
-
.TP
|
308
|
-
\fBr[ecursive] OID[,GEN]\fP
|
309
|
-
Print the given indirect object recursively\. This means that all references found in the object are resolved and the resulting objects themselves recursively printed\.
|
310
|
-
.RS
|
311
|
-
.P
|
312
|
-
To make it easier to compare such structures between PDF files, the entries of dictionaries are printed in sorted order and the original references are replaced by custom ones\. Once an indirect object is first encountered, it is preceeded by either \fB{obj INDEX}\fP or \fB{obj page PAGEINDEX}\fP where \fBINDEX\fP is an increasing number and \fBPAGEINDEX\fP is the index of the page\. Later references are replaced by \fB{ref INDEX}\fP and \fB{ref page PAGEINDEX}\fP respectively\.
|
313
|
-
.P
|
314
|
-
Here is a simplified example output:
|
315
|
-
.sp
|
316
|
-
.RS 4
|
317
|
-
.EX
|
318
|
-
<<
|
319
|
-
/Info {obj 1} <<
|
320
|
-
/Producer (HexaPDF version 0\.9\.3)
|
321
|
-
>>
|
322
|
-
/Root {obj 2} <<
|
323
|
-
/Pages {obj 3} <<
|
324
|
-
/Count 1
|
325
|
-
/Kids [{obj page 1} <<
|
326
|
-
/MediaBox [0 0 595 842 ]
|
327
|
-
/Parent {ref 3}
|
328
|
-
/Type /Page
|
329
|
-
>> ]
|
330
|
-
/Type /Pages
|
331
|
-
>>
|
332
|
-
/Type /Catalog
|
333
|
-
>>
|
334
|
-
/Size 4
|
335
|
-
>>
|
336
|
-
.EE
|
337
|
-
.RE
|
338
|
-
.P
|
339
|
-
On line 2 the indirect object for the key \fB/Info\fP is shown, preceeded by the custom reference\. On line 8 is an example for a page object with the special reference key\. And on line 10 there is a back reference to the object with index 3 which is started on line 6\.
|
340
|
-
.RE
|
341
|
-
.TP
|
342
|
-
\fBs[tream] OID[,GEN]\fP
|
343
|
-
Print the filtered stream, i\.e\. the stream with all filters applied\. This is useful, for example, to view the contents of content streams\.
|
344
|
-
.TP
|
345
|
-
\fBraw[\-stream] OID[,GEN]\fP
|
346
|
-
Print the raw stream, i\.e\. the stream as it appears in the file\. This is useful, for example, to extract streams into files\.
|
347
|
-
.TP
|
348
|
-
\fBx[ref] OID[,GEN]\fP
|
349
|
-
Print the cross\-reference entry for the given indirect object\.
|
350
|
-
.TP
|
351
|
-
\fBc[atalog]\fP
|
352
|
-
Print the catalog dictionary\.
|
353
|
-
.TP
|
354
|
-
\fBt[railer]\fP
|
355
|
-
Print the trailer dictionary\.
|
356
|
-
.TP
|
357
|
-
\fBp[ages] [RANGE]\fP
|
358
|
-
Print 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\&\.
|
359
|
-
.TP
|
360
|
-
\fBpc | page\-count\fP
|
361
|
-
Print the number of pages\.
|
362
|
-
.TP
|
363
|
-
\fBsearch REGEXP\fP
|
364
|
-
Print all objects matching the pattern\. Each object is preceeded by \fBobj OID GEN\fP and followed by \fBendobj\fP to make it easier to further explore the data\.
|
365
|
-
.TP
|
366
|
-
\fBh[elp]\fP
|
367
|
-
Print the available commands with a short description\.
|
368
|
-
.TP
|
369
|
-
\fBq[uit]Quit\fP
|
370
|
-
Quit the interactive mode\.
|
371
|
-
.SS "merge"
|
372
|
-
Synopsis: \fBmerge\fP [\fBOPTIONS\fP] { \fIINPUT\fP | \fB\-\-empty\fP } [\fIINPUT\fP]\.\.\. \fIOUTPUT\fP
|
373
|
-
.P
|
374
|
-
This command merges pages from multiple PDFs into one output file which can optionally be encrypted/decrypted and optimized in various ways\.
|
375
|
-
.P
|
376
|
-
The first input file is the primary file from which meta data like file information, outlines, etc\. are taken from\. Alternatively, it is possible to start with an empty PDF file by using \fB\-\-empty\fP\&\. The order of 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\.
|
377
|
-
.P
|
378
|
-
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\.
|
379
|
-
.TP
|
380
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
381
|
-
The password to decrypt the last input file\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
382
|
-
.TP
|
383
|
-
\fB\-i\fP \fIPAGES\fP, \fB\-\-pages\fP \fIPAGES\fP
|
384
|
-
The pages (optionally rotated) from the last input file 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)\.
|
385
|
-
.TP
|
386
|
-
\fB\-e\fP, \fB\-\-empty\fP
|
387
|
-
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\.
|
388
|
-
.TP
|
389
|
-
\fB\-\-interleave\fP
|
390
|
-
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\.
|
391
|
-
.P
|
392
|
-
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
393
|
-
.SS "modify"
|
394
|
-
Synopsis: \fBmodify\fP [\fBOPTIONS\fP] \fIINPUT\fP \fIOUTPUT\fP
|
395
|
-
.P
|
396
|
-
This command modifies a PDF file\. It can be used to select pages that should appear in the output file and/or rotate them\. The output file can also be encrypted/decrypted and optimized in various ways\.
|
397
|
-
.TP
|
398
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
399
|
-
The password to decrypt the \fIINPUT\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
400
|
-
.TP
|
401
|
-
\fB\-i\fP \fIPAGES\fP, \fB\-\-pages\fP \fIPAGES\fP
|
402
|
-
The pages (optionally rotated) from the \fIINPUT\fP 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)\.
|
403
|
-
.TP
|
404
|
-
\fB\-e\fP \fIFILE\fP, \fB\-\-embed\fP \fIFILE\fP
|
405
|
-
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\.
|
406
|
-
.P
|
407
|
-
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
408
|
-
.SS "optimize"
|
409
|
-
Synopsis: \fBoptimize\fP [\fBOPTIONS\fP] \fIINPUT\fP \fIOUTPUT\fP
|
410
|
-
.P
|
411
|
-
This command uses several optimization strategies to reduce the file size of the PDF file\.
|
412
|
-
.P
|
413
|
-
By default, all strategies except page compression are used since page compression may take a very long time without much benefit\.
|
414
|
-
.TP
|
415
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
416
|
-
The password to decrypt the \fIINPUT\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
417
|
-
.P
|
418
|
-
The \fBOptimization Options\fP can be used with this command\. Note that the defaults are changed to provide good compression out of the box\.
|
419
|
-
.SS "split"
|
420
|
-
Synopsis: \fBsplit\fP [\fBOPTIONS\fP] \fIINPUT\fP [\fIOUTPUT_SPEC\fP]
|
421
|
-
.P
|
422
|
-
This command splits the input file into multiple output files, each containing one page\.
|
423
|
-
.P
|
424
|
-
If no \fIOUTPUT_SPEC\fP is given, files of the form \fIINPUT_0001\.pdf\fP, \fIINPUT_0002\.pdf\fP, \.\.\. and so on are created (only the name \fIINPUT\fP without the file extension is used)\. Otherwise \fIOUTPUT_SPEC\fP determines the file names of the created files, with a printf\-style format string like \[u2018]%04d\[u2019] being replaced by the page number\. For example, if the files should be named \fIpage_01\.pdf\fP, \fIpage_02\.pdf\fP and so on, use \fIpage_%02d\.pdf\fP for the \fIOUTPUT_SPEC\fP\&\.
|
425
|
-
.TP
|
426
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
427
|
-
The password to decrypt the \fIINPUT\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
428
|
-
.P
|
429
|
-
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
430
|
-
.SS "watermark"
|
431
|
-
Synopsis: \fBwatermark\fP [\fBOPTIONS\fP] \fIINPUT\fP \fIOUTPUT\fP
|
432
|
-
.P
|
433
|
-
This command uses one ore more pages from a PDF file and applies them as background or stamp (depending on the \fB\-\-type\fP option) on another PDF file\. If multiple pages are selected from the watermark PDF, the \fB\-\-repeat\fP option can be used to specify how they should be applied\.
|
434
|
-
.TP
|
435
|
-
\fB\-w\fP \fIWATERMARK\fP, \fB\-\-watermark\-file\fP \fIWATERMARK\fP
|
436
|
-
The PDF file that should be used for watermarking\.
|
437
|
-
.TP
|
438
|
-
\fB\-i\fP \fIPAGES\fP, \fB\-\-pages\fP \fIPAGES\fP
|
439
|
-
The pages from the \fIWATERMARK\fP PDF that should be used\. The first \fIWATERMARK\fP page is applied to the first \fIINPUT\fP page, the second \fIWATERMARK\fP page to the second \fIINPUT\fP page and so on\. If there are fewer \fIWATERMARK\fP pages than \fIINPUT\fP pages, the \fB\-\-repeat\fP option comes into play\.
|
440
|
-
.RS
|
441
|
-
.P
|
442
|
-
See the \fBPAGES SPECIFICATION\fP below for details on the allowed format of \fIPAGES\fP\&\. Default: \fI1\fP\&\.
|
443
|
-
.RE
|
444
|
-
.TP
|
445
|
-
\fB\-r\fP \fIREPEAT_MODE\fP, \fB\-\-repeat\fP \fIREPEAT_MODE\fP
|
446
|
-
Specifies how the \fIWATERMARK\fP pages should be repeated: \fBlast\fP (the default) will only repeat the last \fIWATERMARK\fP page whereas \fBall\fP will cyclically repeat all \fIWATERMARK\fP pages\.
|
447
|
-
.TP
|
448
|
-
\fB\-t\fP \fIWATERMARK_TYPE\fP, \fB\-\-type\fP \fIWATERMARK_TYPE\fP
|
449
|
-
Specifies how the \fIWATERMARK\fP pages are applied to the \fIINPUT\fP pages: \fBbackground\fP (the default) applies them below the page contents and \fBstamp\fP applies them above the page contents\.
|
450
|
-
.TP
|
451
|
-
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
452
|
-
The password to decrypt the \fIINPUT\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
453
|
-
.P
|
454
|
-
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
455
|
-
.SS "version"
|
456
|
-
This command shows the version of the hexapdf application\. It is an alternative to using the global \fB\-\-version\fP option\.
|
457
|
-
.SH "PAGES SPECIFICATION"
|
458
|
-
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\.
|
459
|
-
.P
|
460
|
-
If the start number of a page range is higher than the end number, the pages are used in the reverse order\.
|
461
|
-
.P
|
462
|
-
Single page numbers that are not valid are ignored\. If a page number in a page range is higher than the page number of the last page, the page number of the last page is used instead\.
|
463
|
-
.P
|
464
|
-
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\.
|
465
|
-
.P
|
466
|
-
Additionally, the page numbers and ranges can be suffixed with a rotation modifier:
|
467
|
-
.sp
|
468
|
-
.PD 0
|
469
|
-
.TP
|
470
|
-
\fBl\fP
|
471
|
-
Rotate the page left, that is 90 degrees counterclockwise
|
472
|
-
.TP
|
473
|
-
\fBr\fP
|
474
|
-
Rotate the page right, that is 90 degrees clockwise
|
475
|
-
.TP
|
476
|
-
\fBd\fP
|
477
|
-
Rotate the page 180 degrees
|
478
|
-
.TP
|
479
|
-
\fBn\fP
|
480
|
-
Remove any set page rotation
|
481
|
-
.PD
|
482
|
-
.P
|
483
|
-
Note that this additional functionality may not be used by all commands (it is used, for example, by the \fBmodify\fP command)\.
|
484
|
-
.P
|
485
|
-
Examples:
|
486
|
-
.IP \(bu 4
|
487
|
-
\fB1,2,3\fP: The pages 1, 2 and 3\.
|
488
|
-
.IP \(bu 4
|
489
|
-
\fB11,4\-9,1,e\fP: The pages 11, 4 to 9, 1 and the last page, in exactly this order\.
|
490
|
-
.IP \(bu 4
|
491
|
-
\fB1\-e\fP: All pages of the document\.
|
492
|
-
.IP \(bu 4
|
493
|
-
\fBe\-1\fP: All pages of the document in reverse order\.
|
494
|
-
.IP \(bu 4
|
495
|
-
\fB1\-5/2\fP: The pages 1, 3 and 5\.
|
496
|
-
.IP \(bu 4
|
497
|
-
\fB10\-1/3\fP: The pages 10, 7, 4 and 1\.
|
498
|
-
.IP \(bu 4
|
499
|
-
\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)\.
|
500
|
-
.SH "EXAMPLES"
|
501
|
-
.SS "merge"
|
502
|
-
\fBhexapdf merge input1\.pdf input2\.pdf input3\.pdf output\.pdf\fP
|
503
|
-
.br
|
504
|
-
\fBhexapdf merge \-e input1\.pdf input2\.pdf input3\.pdf output\.pdf\fP
|
505
|
-
.P
|
506
|
-
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\.
|
507
|
-
.P
|
508
|
-
\fBhexapdf merge odd\.pdf even\.pdf \-\-interleave combined\.pdf\fP
|
509
|
-
.P
|
510
|
-
Page interleaving: Takes alternately 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\.
|
511
|
-
.SS "modify"
|
512
|
-
\fBhexapdf modify input\.pdf \-i 1\-5,7\-10,12\-e output\.pdf\fP
|
513
|
-
.P
|
514
|
-
Page removal: Remove the pages 6 and 11 from the \fBinput\.pdf\fP\&\.
|
515
|
-
.P
|
516
|
-
\fBhexapdf modify input\.pdf \-i 1r,2\-ed output\.pdf\fP
|
517
|
-
.P
|
518
|
-
Page rotation: Rotate the first page to the right, that is 90 degrees clockwise, and all other pages 180 degrees\.
|
519
|
-
.P
|
520
|
-
\fBhexapdf modify input\.pdf \-\-user\-password my_pwd \-\-permissions print output\.pdf\fP
|
521
|
-
.P
|
522
|
-
Encryption: Create the \fBoutput\.pdf\fP from the \fBinput\.pdf\fP so that a password is needed to open it, and only allow printing\.
|
523
|
-
.P
|
524
|
-
\fBhexapdf modify input\.pdf \-p input_password \-\-decrypt output\.pdf\fP
|
525
|
-
.P
|
526
|
-
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 input file\.
|
527
|
-
.SS "optimize"
|
528
|
-
\fBhexapdf optimize input\.pdf output\.pdf\fP
|
529
|
-
.P
|
530
|
-
Optimization: Compress the \fBinput\.pdf\fP to get a smaller file size\.
|
531
|
-
.SS "split"
|
532
|
-
\fBhexapdf split input\.pdf out_%02d\.pdf\fP
|
533
|
-
.P
|
534
|
-
Split the \fBinput\.pdf\fP into individual pages, naming the output files \fBout_01\.pdf\fP, \fBout_02\.pdf\fP, and so on\.
|
535
|
-
.SS "watermark"
|
536
|
-
\fBhexapdf watermark \-w watermark\.pdf \-t stamp input\.pdf output\.pdf\fP
|
537
|
-
.P
|
538
|
-
Applies the first page of the \fBwatermark\.pdf\fP as stamp on \fBinput\.pdf\fP\&\.
|
539
|
-
.P
|
540
|
-
\fBhexapdf watermark \-w watermark\.pdf \-i 2\-5 \-r all input\.pdf output\.pdf\fP
|
541
|
-
.P
|
542
|
-
Cyclically applies the pages 2 to 5 of the \fBwatermark\.pdf\fP as background on \fBinput\.pdf\fP\&\.
|
543
|
-
.SS "files"
|
544
|
-
\fBhexapdf files input\.pdf\fP
|
545
|
-
.br
|
546
|
-
\fBhexapdf files input\.pdf \-e 1\fP
|
547
|
-
.P
|
548
|
-
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\.
|
549
|
-
.SS "images"
|
550
|
-
\fBhexapdf images input\.pdf\fP
|
551
|
-
.br
|
552
|
-
\fBhexapdf images input\.pdf \-e \-\-prefix images/image\fP
|
553
|
-
.P
|
554
|
-
Image info and extraction: The first command lists the images of the \fBinput\.pdf\fP, the second one then extracts the images into the subdirectory \fBimages\fP with the prefix \fBimage\fP\&\.
|
555
|
-
.SS "image2pdf"
|
556
|
-
\fBhexapdf image2pdf output\.pdf image1\.jpg image2\.pdf image3\.png\fP
|
557
|
-
.P
|
558
|
-
Create a PDF file \fBoutput\.pdf\fP containing three pages with one image per page and the image fitted to the page\.
|
559
|
-
.SS "info"
|
560
|
-
\fBhexapdf info input\.pdf\fP
|
561
|
-
.P
|
562
|
-
File information: Show general information about the PDF file, like PDF version, number of pages, creator, creation date and encryption related information\.
|
563
|
-
.SS "inspect"
|
564
|
-
\fBhexapdf inspect input\.pdf \-o 3\fP
|
565
|
-
.P
|
566
|
-
Show the object with the object number 3 of the given PDF file\.
|
567
|
-
.P
|
568
|
-
\fBhexapdf inspect input\.pdf\fP
|
569
|
-
.P
|
570
|
-
Start the interactive inspection mode\.
|
571
|
-
.SS "batch"
|
572
|
-
\fBhexapdf batch \'info {}\' input1\.pdf input2\.pdf input3\.pdf\fP
|
573
|
-
.P
|
574
|
-
Execute the info command for all input files\.
|
575
|
-
.P
|
576
|
-
\fBhexapdf batch \'optimize \-\-object\-streams delete {} done\-{}\' input1\.pdf input2\.pdf input3\.pdf\fP
|
577
|
-
.P
|
578
|
-
Optimize the given input files, creating the three output files \fBdone\-input1\.pdf\fP, \fBdone\-input2\.pdf\fP and \fBdone\-input3\.pdf\fP\&\.
|
579
|
-
.SH "EXIT STATUS"
|
580
|
-
The exit status is 0 if no error happened\. Otherwise it is 1\.
|
581
|
-
.SH "SEE ALSO"
|
582
|
-
The
|
583
|
-
.UR http://hexapdf\.gettalong\.org
|
584
|
-
hexapdf website
|
585
|
-
.UE
|
586
|
-
for more information\.
|
587
|
-
.SH "AUTHOR"
|
588
|
-
hexapdf was written by Thomas Leitner
|
589
|
-
.MT t_leitner@gmx\.at
|
590
|
-
.UE
|
591
|
-
\&\.
|
592
|
-
.P
|
593
|
-
This manual page was written by Thomas Leitner
|
594
|
-
.MT t_leitner@gmx\.at
|
595
|
-
.UE
|
596
|
-
\&\.
|