Class: HexaPDF::CLI::Merge
- Defined in:
- lib/hexapdf/cli/merge.rb
Overview
Merges pages from multiple PDF files.
Defined Under Namespace
Classes: InputSpec
Instance Method Summary collapse
-
#execute ⇒ Object
:nodoc:.
-
#initialize ⇒ Merge
constructor
:nodoc:.
-
#usage ⇒ Object
:nodoc:.
Methods included from Command::Extensions
Constructor Details
#initialize ⇒ Merge
:nodoc:
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/hexapdf/cli/merge.rb', line 47 def initialize #:nodoc: super('merge', takes_commands: false) short_desc("Merge multiple PDF files") long_desc(<<~EOF) This command merges pages from multiple PDFs into one output file which can optionally be encrypted/decrypted and optimized in various ways. The first input file is the primary input 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 --empty. The order of the files is important as they are used in that order. Also note that the --password and --pages options apply to the last preceeding input file. EOF .on(/.*/, "Input file, can be specified multiple times") do |file| @files << InputSpec.new(file, '1-e') throw :prune end .on("-p", "--password PASSWORD", String, "The password for decrypting the last " \ "specified input file (use - for reading from standard input)") do |pwd| raise OptionParser::InvalidArgument, "(No prior input file specified)" if @files.empty? pwd = (pwd == '-' ? read_password("#{@files.last.file} password") : pwd) @files.last.password = pwd end .on("-i", "--pages PAGES", "The pages of the last specified input file that " \ "should be used (default: 1-e)") do |pages| raise OptionParser::InvalidArgument, "(No prior input file specified)" if @files.empty? @files.last.pages = pages end .on("-e", "--empty", "Use an empty file as the first input file") do @initial_empty = true end .on("--[no-]interleave", "Interleave the pages from the input files (default: " \ "false)") do |c| @interleave = c end .separator("") .separator("Output related options") @files = [] @initial_empty = false @interleave = false end |
Instance Method Details
#execute ⇒ Object
:nodoc:
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/hexapdf/cli/merge.rb', line 94 def execute #:nodoc: if !@initial_empty && @files.empty? error = OptionParser::ParseError.new("At least one FILE or --empty is needed") error.reason = "Missing argument" raise error elsif (@initial_empty && @files.empty?) || (!@initial_empty && @files.length < 2) error = OptionParser::ParseError.new("Output file is needed") error.reason = "Missing argument" raise error end output_file = @files.pop.file maybe_raise_on_existing_file(output_file) # Create PDF documents for each input file cache = {} @files.each do |spec| cache[spec.file] ||= begin io = if spec.file == output_file StringIO.new(File.binread(spec.file)) else File.open(spec.file) end HexaPDF::Document.new(io: io, **(spec.password)) end spec.file = cache[spec.file] end # Assemble pages target = (@initial_empty ? HexaPDF::Document.new : @files.first.file) page_tree = target.add({Type: :Pages}) import_pages(page_tree) target.catalog[:Pages] = page_tree remove_unused_pages(target) target.pages.add unless target.pages.count > 0 (target) (target) write_document(target, output_file) end |
#usage ⇒ Object
:nodoc:
137 138 139 140 |
# File 'lib/hexapdf/cli/merge.rb', line 137 def usage #:nodoc: "Usage: #{command_parser..program_name} merge [options] {FILE | --empty} " \ "[FILE]... OUT_FILE" end |