pdfmult 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ pdfmult
2
+ =======
3
+
4
+ `pdfmult` is a command line tool (written in [Ruby][Ruby]) that
5
+ rearranges multiple copies of a PDF page (shrunken) on one page.
6
+
7
+ The paper size of the produced PDF file is A4,
8
+ the input file is also assumed to be in A4 format.
9
+ The input PDF file may consist of several pages.
10
+ If `pdfmult` succeeds in obtaining the page count it will rearrange all pages,
11
+ if not, only the first page is processed
12
+ (unless the page count was specified via command line option).
13
+
14
+ Examples
15
+ --------
16
+
17
+ Use the program as shown in the examples below.
18
+
19
+ * `pdfmult sample.pdf`
20
+
21
+ writes 2 copies of `sample.pdf` to `sample_2.pdf`
22
+
23
+ <img src="/stomar/pdfmult/raw/master/example1.png" alt="" width="152" height="59">
24
+
25
+ * `pdfmult -n 4 sample.pdf`
26
+
27
+ writes 4 copies of `sample.pdf` to `sample_4.pdf`
28
+
29
+ <img src="/stomar/pdfmult/raw/master/example2.png" alt="" width="234" height="59">
30
+
31
+ * `pdfmult sample.pdf -o outfile.pdf`
32
+
33
+ writes 2 copies of `sample.pdf` to `outfile.pdf`
34
+
35
+ * `pdfmult sample.pdf -p 3`
36
+
37
+ processes the first 3 pages of `sample.pdf`
38
+
39
+ Installation
40
+ ------------
41
+
42
+ Use `gem install pdfmult`.
43
+
44
+ Or opy `lib/pdfmult.rb` under the name `pdfmult` into your search path.
45
+
46
+ On a Linux system you can use `[sudo] rake install`
47
+ to install `pdfmult` and its man page to `/usr/local`.
48
+
49
+ Requirements
50
+ ------------
51
+
52
+ As of now, `pdfmult` has only been tested on a Linux system.
53
+
54
+ - `pdfmult` is written in [Ruby][Ruby], so Ruby must be installed on your system.
55
+ - `pdfmult` uses `pdflatex` with the `pdfpages` package, so both have to be installed on the system.
56
+ - `pdfmult` tries to obtain the page count of PDF files with `pdfinfo`.
57
+ If it fails, by default only the first page of a PDF file will be processed.
58
+
59
+ Documentation
60
+ -------------
61
+
62
+ `pdfmult --help` prints a brief help message.
63
+
64
+ If you installed `pdfmult` using `rake install` you can read
65
+ its man page with `man pdfmult`.
66
+
67
+ Reporting bugs
68
+ --------------
69
+
70
+ Report bugs on the `pdfmult` home page: <https://github.com/stomar/pdfmult/>
71
+
72
+ License
73
+ -------
74
+
75
+ Copyright &copy; 2011-2012, Marcus Stollsteimer
76
+
77
+ `pdfmult` is free software: you can redistribute it and/or modify
78
+ it under the terms of the GNU General Public License version 3 or later (GPLv3+),
79
+ see [www.gnu.org/licenses/gpl.html](http://www.gnu.org/licenses/gpl.html).
80
+ There is NO WARRANTY, to the extent permitted by law.
81
+
82
+
83
+ [Ruby]: http://www.ruby-lang.org/
data/Rakefile ADDED
@@ -0,0 +1,64 @@
1
+ # rakefile for the pdfmult script.
2
+ #
3
+ # Copyright (C) 2012 Marcus Stollsteimer
4
+
5
+ require 'rake/testtask'
6
+
7
+ BINDIR = '/usr/local/bin'
8
+ MANDIR = '/usr/local/man/man1'
9
+
10
+ HELP2MAN = 'help2man'
11
+ SED = 'sed'
12
+
13
+ BINARY = 'lib/pdfmult.rb'
14
+ BINARYNAME = 'pdfmult' # install using this name
15
+ MANPAGE = 'man/pdfmult.1'
16
+ H2MFILE = 'pdfmult.h2m'
17
+
18
+
19
+ def gemspec_file
20
+ 'pdfmult.gemspec'
21
+ end
22
+
23
+
24
+ task :default => [:test]
25
+
26
+ Rake::TestTask.new do |t|
27
+ t.pattern = 'test/**/test_*.rb'
28
+ t.ruby_opts << '-rubygems'
29
+ t.verbose = true
30
+ t.warning = true
31
+ end
32
+
33
+
34
+ desc 'Install binary and man page'
35
+ task :install => [BINARY, MANPAGE] do
36
+ mkdir_p BINDIR
37
+ install(BINARY, BINDIR + '/' + BINARYNAME)
38
+ mkdir_p MANDIR
39
+ install(MANPAGE, MANDIR, :mode => 0644)
40
+ end
41
+
42
+
43
+ desc 'Uninstall binary and man page'
44
+ task :uninstall do
45
+ rm "#{BINDIR}/#{BINARYNAME}"
46
+ manfile = File.basename(MANPAGE)
47
+ rm "#{MANDIR}/#{manfile}"
48
+ end
49
+
50
+
51
+ desc 'Create man page'
52
+ task :man => [MANPAGE]
53
+
54
+ file MANPAGE => [BINARY, H2MFILE] do
55
+ sh "#{HELP2MAN} --no-info --include=#{H2MFILE} -o #{MANPAGE} ./#{BINARY}"
56
+ sh "#{SED} -i '/\.PP/{N;s/\.PP\\nOptions/.SH OPTIONS/}' #{MANPAGE}"
57
+ sh "#{SED} -i 's/^License GPL/.br\\nLicense GPL/;s/There is NO WARRANTY/.br\\nThere is NO WARRANTY/' #{MANPAGE}"
58
+ end
59
+
60
+
61
+ desc 'Build gem'
62
+ task :build do
63
+ sh "gem build #{gemspec_file}"
64
+ end
data/bin/pdfmult ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ require 'pdfmult'
4
+
5
+ Pdfmult::Application.run!
data/example1.fig ADDED
@@ -0,0 +1,21 @@
1
+ #FIG 3.2 Produced by xfig version 3.2.5b
2
+ Landscape
3
+ Center
4
+ Metric
5
+ A4
6
+ 100.00
7
+ Single
8
+ -2
9
+ 1200 2
10
+ 2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
11
+ 1 1 2.00 120.00 180.00
12
+ 1395 450 1845 450
13
+ 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
14
+ 540 0 1215 0 1215 900 540 900 540 0
15
+ 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
16
+ 2025 90 2925 90 2925 765 2025 765 2025 90
17
+ 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
18
+ 2475 90 2475 765
19
+ 4 1 0 50 -1 16 32 0.0000 4 405 375 855 630 A\001
20
+ 4 1 0 50 -1 16 24 0.0000 4 315 270 2700 585 A\001
21
+ 4 1 0 50 -1 16 24 0.0000 4 315 270 2250 585 A\001
data/example1.png ADDED
Binary file
data/example2.fig ADDED
@@ -0,0 +1,46 @@
1
+ #FIG 3.2 Produced by xfig version 3.2.5b
2
+ Landscape
3
+ Center
4
+ Metric
5
+ A4
6
+ 100.00
7
+ Single
8
+ -2
9
+ 1200 2
10
+ 6 450 0 1125 900
11
+ 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
12
+ 450 0 1125 0 1125 900 450 900 450 0
13
+ 4 1 0 50 -1 16 32 0.0000 4 390 285 765 630 2\001
14
+ -6
15
+ 6 1935 0 2610 900
16
+ 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
17
+ 1935 0 2610 0 2610 900 1935 900 1935 0
18
+ 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
19
+ 1935 450 2610 450
20
+ 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
21
+ 2272 0 2272 900
22
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 2430 315 1\001
23
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 2115 765 1\001
24
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 2430 765 1\001
25
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 2115 315 1\001
26
+ -6
27
+ 6 -315 0 360 900
28
+ 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
29
+ -315 0 360 0 360 900 -315 900 -315 0
30
+ 4 1 0 50 -1 16 32 0.0000 4 390 285 0 630 1\001
31
+ -6
32
+ 6 2700 0 3375 900
33
+ 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
34
+ 2700 0 3375 0 3375 900 2700 900 2700 0
35
+ 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
36
+ 2700 450 3375 450
37
+ 2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
38
+ 3037 0 3037 900
39
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 3195 315 2\001
40
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 2880 765 2\001
41
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 3195 765 2\001
42
+ 4 1 0 50 -1 16 16 0.0000 4 195 150 2880 315 2\001
43
+ -6
44
+ 2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
45
+ 1 1 2.00 120.00 180.00
46
+ 1305 450 1755 450
data/example2.png ADDED
Binary file
data/lib/pdfmult.rb ADDED
@@ -0,0 +1,335 @@
1
+ #!/usr/bin/ruby -w
2
+ # == Name
3
+ #
4
+ # pdfmult - put multiple copies of a PDF page on one page
5
+ #
6
+ # == Synopsis
7
+ #
8
+ # pdfmult [options] file
9
+ #
10
+ # == Description
11
+ #
12
+ # +pdfmult+ rearranges multiple copies of a PDF page (shrunken) on one page.
13
+ #
14
+ # The paper size of the produced PDF file is A4,
15
+ # the input file is also assumed to be in A4 format.
16
+ # The input PDF file may consist of several pages.
17
+ # If +pdfmult+ succeeds in obtaining the page count it will rearrange all pages,
18
+ # if not, only the first page is processed
19
+ # (unless the page count was specified via command line option).
20
+ #
21
+ # +pdfmult+ uses +pdflatex+ with the +pdfpages+ package,
22
+ # so both have to be installed on the system.
23
+ #
24
+ # == Options
25
+ #
26
+ # -n, --number:: Number of copies to put on one page: 2 (default), 4, 8, 9, 16.
27
+ #
28
+ # -o, --output:: Output file (default: infile_NUMBER.pdf).
29
+ #
30
+ # -p, --pages:: Number of pages to convert.
31
+ # If given, +pdfmult+ does not try to obtain the page count from the source PDF.
32
+ #
33
+ # -h, --help:: Prints a brief help message and exits.
34
+ #
35
+ # -v, --version:: Prints a brief version information and exits.
36
+ #
37
+ # == Examples
38
+ #
39
+ # pdfmult sample.pdf # => sample_2.pdf (2 copies)
40
+ # pdfmult -n 4 sample.pdf # => sample_4.pdf (4 copies)
41
+ # pdfmult sample.pdf -o outfile.pdf # => outfile.pdf (2 copies)
42
+ # pdfmult sample.pdf -p 3 # => processes 3 pages
43
+ #
44
+ # == Author
45
+ #
46
+ # Copyright (C) 2011-2012 Marcus Stollsteimer
47
+ #
48
+ # License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
49
+ #
50
+
51
+
52
+ require 'optparse'
53
+ require 'tempfile'
54
+ require 'fileutils'
55
+
56
+ # This module contains the classes for the +pdfmult+ tool
57
+ module Pdfmult
58
+
59
+ PROGNAME = 'pdfmult'
60
+ VERSION = '1.0.0'
61
+ DATE = '2012-03-15'
62
+ COPYRIGHT = "Copyright (C) 2011-2012 Marcus Stollsteimer.\n" +
63
+ "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n" +
64
+ "This is free software: you are free to change and redistribute it.\n" +
65
+ "There is NO WARRANTY, to the extent permitted by law."
66
+
67
+ PDFLATEX = '/usr/bin/pdflatex'
68
+ KPSEWHICH = '/usr/bin/kpsewhich'
69
+
70
+ # Parser for the command line options.
71
+ # The class method parse! does the job.
72
+ class Optionparser
73
+
74
+ # Parses the command line options from +argv+.
75
+ # (+argv+ is cleared).
76
+ # Might print out help or version information.
77
+ #
78
+ # +argv+ - array with the command line options
79
+ #
80
+ # Returns a hash containing the option parameters.
81
+ def self.parse!(argv)
82
+
83
+ options = {
84
+ :number => 2,
85
+ :infile => nil,
86
+ :outfile => nil,
87
+ :pages => nil
88
+ }
89
+
90
+ opt_parser = OptionParser.new do |opt|
91
+ opt.banner = "Usage: #{PROGNAME} [options] file"
92
+ opt.separator ''
93
+ opt.separator 'pdfmult is a command line tool that'
94
+ opt.separator 'rearranges multiple copies of a PDF page (shrunken) on one page.'
95
+ opt.separator ''
96
+ opt.separator 'The paper size of the produced PDF file is A4,'
97
+ opt.separator 'the input file is also assumed to be in A4 format.'
98
+ opt.separator 'The input PDF file may consist of several pages.'
99
+ opt.separator 'If pdfmult succeeds in obtaining the page count it will rearrange all pages,'
100
+ opt.separator 'if not, only the first page is processed'
101
+ opt.separator '(unless the page count was specified via command line option).'
102
+ opt.separator ''
103
+ opt.separator 'Options'
104
+ opt.separator ''
105
+
106
+ # process --version and --help first,
107
+ # exit successfully (GNU Coding Standards)
108
+ opt.on_tail('-h', '--help', 'Prints a brief help message and exits.') do
109
+ puts opt_parser
110
+ puts "\nReport bugs on the pdfmult home page: <https://github.com/stomar/pdfmult/>"
111
+ exit
112
+ end
113
+
114
+ opt.on_tail('-v', '--version',
115
+ 'Prints a brief version information and exits.') do
116
+ puts "#{PROGNAME} #{VERSION}"
117
+ puts COPYRIGHT
118
+ exit
119
+ end
120
+
121
+ opt.on('-n', '--number NUMBER', ['2', '4', '8', '9', '16'], Integer,
122
+ 'Number of copies to put on one page: 2 (default), 4, 8, 9, 16.') do |n|
123
+ options[:number] = n
124
+ end
125
+
126
+ opt.on('-o', '--output FILE', String,
127
+ 'Output file (default: file_2.pdf).') do |f|
128
+ options[:outfile] = f
129
+ end
130
+
131
+ opt.on('-p', '--pages NUMBER', Integer,
132
+ 'Number of pages to convert.',
133
+ "If given, #{PROGNAME} does not try to obtain the page count from the source PDF.") do |p|
134
+ raise(OptionParser::InvalidArgument, p) unless p > 0
135
+ options[:pages] = p
136
+ end
137
+
138
+ opt.separator ''
139
+ end
140
+ opt_parser.parse!(argv)
141
+
142
+ # only input file should be left in argv
143
+ raise(ArgumentError, 'wrong number of arguments') if (argv.size != 1 || argv[0] == '')
144
+
145
+ options[:infile] = argv.pop
146
+
147
+ # set output file unless set by option
148
+ options[:outfile] ||= options[:infile].gsub(/(.pdf)$/, '') + "_#{options[:number].to_s}.pdf"
149
+
150
+ options
151
+ end
152
+ end
153
+
154
+ # Class for the LaTeX document.
155
+ #
156
+ # Create an instance with LaTeXDocument.new, specifying
157
+ # the input file, the number of pages to put on one page,
158
+ # and the page count of the input file.
159
+ #
160
+ # The method +to_s+ returns the document as multiline string.
161
+ class LaTeXDocument
162
+
163
+ attr_accessor :infile, :number, :page_count
164
+
165
+ HEADER =
166
+ "\\documentclass[CLASSOPTIONS]{article}\n" +
167
+ "\\usepackage{pdfpages}\n" +
168
+ "\\pagestyle{empty}\n" +
169
+ "\\setlength{\\parindent}{0pt}\n" +
170
+ "\\begin{document}%\n"
171
+
172
+ CONTENT =
173
+ "\\includepdf[pages={PAGES},nup=GEOMETRY]{FILENAME}%\n"
174
+
175
+ FOOTER =
176
+ '\end{document}'
177
+
178
+ # Initializes a LaTeXDocument instance.
179
+ #
180
+ # +infile+ - input file name
181
+ # +number+ - number of pages to put on one page
182
+ # +page_count+ - page count of the input file
183
+ def initialize(infile, number, page_count)
184
+ @infile = infile
185
+ @number = number
186
+ @page_count = page_count
187
+ end
188
+
189
+ def to_s
190
+ class_options = 'a4paper'
191
+ page_string = 'PAGE,' * (@number - 1) + 'PAGE' # 4 copies: e.g. 1,1,1,1
192
+
193
+ case @number
194
+ when 2
195
+ class_options += ',landscape'
196
+ geometry = '2x1'
197
+ when 4
198
+ geometry = '2x2'
199
+ when 8
200
+ class_options += ',landscape'
201
+ geometry = '4x2'
202
+ when 9
203
+ geometry = '3x3'
204
+ when 16
205
+ geometry = '4x4'
206
+ end
207
+
208
+ content_template = CONTENT.gsub(/PAGES/, page_string).gsub(/GEOMETRY/, geometry).gsub(/FILENAME/, @infile)
209
+
210
+ content = HEADER.gsub(/CLASSOPTIONS/, class_options)
211
+ @page_count.times do |i|
212
+ content << content_template.gsub(/PAGE/,"#{i+1}")
213
+ end
214
+
215
+ content << FOOTER
216
+ end
217
+ end
218
+
219
+ # A class for PDF meta data (up to now only used for the page count).
220
+ #
221
+ # Create an instance with PDFInfo.new, specifying the file name.
222
+ # +PDFInfo+ tries to use the +pdfinfo+ system tool to obtain meta data.
223
+ # If successful, the attribute +page_count+ contains the page count,
224
+ # else the attribute is set to +nil+.
225
+ class PDFInfo
226
+
227
+ PDFINFOCMD = '/usr/bin/pdfinfo'
228
+
229
+ # Contains the page count of the input file, or nil.
230
+ attr_reader :page_count
231
+
232
+ # This is the initialization method for the class.
233
+ #
234
+ # +file+ - file name of the PDF file
235
+ def initialize(file, options={})
236
+ @page_count = nil
237
+ infos = Hash.new
238
+
239
+ binary = options[:pdfinfocmd] || PDFINFOCMD # only for unit tests
240
+ command = "#{binary} #{file}"
241
+ if Application.command_available?(command)
242
+ infostring = `#{command}`
243
+ infostring.each_line do |line|
244
+ key, val = line.chomp.split(/\s*:\s*/, 2)
245
+ infos[key] = val
246
+ end
247
+ value = infos['Pages']
248
+ @page_count = value.to_i unless value.nil?
249
+ end
250
+ end
251
+
252
+ # Returns true if default +pdfinfo+ system tool is available (for unit tests).
253
+ def self.infocmd_available? # :nodoc:
254
+ Application.command_available?(PDFINFOCMD + ' -v')
255
+ end
256
+ end
257
+
258
+ # The main program. It's run! method is called
259
+ # if the script is run from the command line.
260
+ # It parses the command line arguments and does the job.
261
+ class Application
262
+
263
+ ERRORCODE = {:general => 1, :usage => 2}
264
+
265
+ # The main program.
266
+ def self.run!
267
+
268
+ # parse options
269
+ begin
270
+ options = Optionparser.parse!(ARGV)
271
+ rescue => e
272
+ usage_fail(e.message)
273
+ end
274
+
275
+ # tests
276
+ general_fail("`#{PDFLATEX}' seems not to be installed") unless command_available?("#{PDFLATEX} --version")
277
+ general_fail("`pdfpages.sty' seems not to be installed") unless command_available?("#{KPSEWHICH} pdfpages.sty")
278
+
279
+ # main body #
280
+
281
+ infile = options[:infile]
282
+ outfile = options[:outfile]
283
+
284
+ # test input file
285
+ usage_fail("no such file: `#{infile}'") unless File.exist?(infile)
286
+ usage_fail("specified input not of the type `file'") unless File.ftype(infile) == 'file'
287
+
288
+ # set page number (get PDF info if necessary)
289
+ pages = options[:pages]
290
+ pages ||= PDFInfo.new(infile).page_count
291
+ pages ||= 1
292
+
293
+ # create LaTeX document
294
+ document = LaTeXDocument.new(infile, options[:number], pages)
295
+
296
+ Dir.mktmpdir('pdfmult') do |dir|
297
+ open("#{dir}/pdfmult.tex", 'w') do |f|
298
+ pdfpath = "#{dir}/pdfmult.pdf"
299
+ f.write(document.to_s)
300
+ f.flush
301
+ system("/usr/bin/pdflatex -output-directory #{dir} pdfmult.tex")
302
+ puts "Writing on #{outfile}."
303
+ FileUtils::mv(pdfpath, outfile)
304
+ end
305
+ end
306
+ end
307
+
308
+ # Prints an error message and exits.
309
+ def self.general_fail(message) # :nodoc:
310
+ warn "#{PROGNAME}: #{message}"
311
+ exit ERRORCODE[:general]
312
+ end
313
+
314
+ # Prints an error message and a short help information, then exits.
315
+ def self.usage_fail(message) # :nodoc:
316
+ warn "#{PROGNAME}: #{message}"
317
+ warn "Use `#{PROGNAME} --help' for valid options."
318
+ exit ERRORCODE[:usage]
319
+ end
320
+
321
+ # Tests silently whether the given system command is available.
322
+ #
323
+ # +command+ - command to test
324
+ def self.command_available?(command) # :nodoc:
325
+ !!system(command + ' >/dev/null 2>&1')
326
+ end
327
+ end
328
+
329
+ ### call main method only if called on command line
330
+
331
+ if __FILE__ == $0
332
+ Application.run!
333
+ end
334
+
335
+ end # module
data/man/pdfmult.1 ADDED
@@ -0,0 +1,49 @@
1
+ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4.
2
+ .TH PDFMULT "1" "March 2012" "pdfmult 1.0.0" "User Commands"
3
+ .SH NAME
4
+ pdfmult \- puts multiple copies of a PDF page on one page
5
+ .SH SYNOPSIS
6
+ .B pdfmult
7
+ [\fIoptions\fR] \fIfile\fR
8
+ .SH DESCRIPTION
9
+ pdfmult is a command line tool that
10
+ rearranges multiple copies of a PDF page (shrunken) on one page.
11
+ .PP
12
+ The paper size of the produced PDF file is A4,
13
+ the input file is also assumed to be in A4 format.
14
+ The input PDF file may consist of several pages.
15
+ If pdfmult succeeds in obtaining the page count it will rearrange all pages,
16
+ if not, only the first page is processed
17
+ (unless the page count was specified via command line option).
18
+ .SH OPTIONS
19
+ .TP
20
+ \fB\-n\fR, \fB\-\-number\fR NUMBER
21
+ Number of copies to put on one page: 2 (default), 4, 8, 9, 16.
22
+ .TP
23
+ \fB\-o\fR, \fB\-\-output\fR FILE
24
+ Output file (default: file_2.pdf).
25
+ .TP
26
+ \fB\-p\fR, \fB\-\-pages\fR NUMBER
27
+ Number of pages to convert.
28
+ If given, pdfmult does not try to obtain the page count from the source PDF.
29
+ .TP
30
+ \fB\-h\fR, \fB\-\-help\fR
31
+ Prints a brief help message and exits.
32
+ .TP
33
+ \fB\-v\fR, \fB\-\-version\fR
34
+ Prints a brief version information and exits.
35
+ .SH EXAMPLES
36
+ pdfmult sample.pdf # => sample_2.pdf (2 copies)
37
+ pdfmult -n 4 sample.pdf # => sample_4.pdf (4 copies)
38
+ pdfmult sample.pdf -o outfile.pdf # => outfile.pdf (2 copies)
39
+ pdfmult sample.pdf -p 3 # => processes 3 pages
40
+ .SH "REPORTING BUGS"
41
+ Report bugs on the pdfmult home page: <https://github.com/stomar/pdfmult/>
42
+ .SH COPYRIGHT
43
+ Copyright \(co 2011\-2012 Marcus Stollsteimer.
44
+ .br
45
+ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
46
+ .br
47
+ This is free software: you are free to change and redistribute it.
48
+ .br
49
+ There is NO WARRANTY, to the extent permitted by law.
data/pdfmult.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ require 'lib/pdfmult'
2
+
3
+ version = Pdfmult::VERSION
4
+ date = Pdfmult::DATE
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'pdfmult'
8
+ s.version = version
9
+ s.date = date
10
+ s.rubyforge_project = 'pdfmult'
11
+
12
+ s.description = 'pdfmult is a command line tool that rearranges ' +
13
+ 'multiple copies of a PDF page (shrunken) on one page.'
14
+ s.summary = 'pdfmult - puts multiple copies of a PDF page on one page'
15
+
16
+ s.authors = ['Marcus Stollsteimer']
17
+ s.email = 'sto.mar@web.de'
18
+ s.homepage = 'https://github.com/stomar/pdfmult/'
19
+
20
+ s.license = 'GPL-3'
21
+
22
+ s.requirements << 'pdflatex and the pdfpages package'
23
+
24
+ s.executables = ['pdfmult']
25
+ s.bindir = 'bin'
26
+ s.require_path = 'lib'
27
+ s.test_files = Dir.glob('test/**/test_*.rb')
28
+
29
+ s.rdoc_options = ['--charset=UTF-8']
30
+
31
+ s.files = %w[
32
+ README.md
33
+ Rakefile
34
+ pdfmult.gemspec
35
+ pdfmult.h2m
36
+ ] +
37
+ Dir.glob('example*.*') +
38
+ Dir.glob('{bin,lib,man,test}/**/*')
39
+
40
+ s.add_development_dependency('rake')
41
+ s.add_development_dependency('minitest')
42
+ end
data/pdfmult.h2m ADDED
@@ -0,0 +1,8 @@
1
+ [Name]
2
+ pdfmult \- puts multiple copies of a PDF page on one page
3
+
4
+ [Examples]
5
+ pdfmult sample.pdf # => sample_2.pdf (2 copies)
6
+ pdfmult -n 4 sample.pdf # => sample_4.pdf (4 copies)
7
+ pdfmult sample.pdf -o outfile.pdf # => outfile.pdf (2 copies)
8
+ pdfmult sample.pdf -p 3 # => processes 3 pages
data/test/sample.pdf ADDED
Binary file
data/test/sample.tex ADDED
@@ -0,0 +1,37 @@
1
+ \documentclass[paper=A4,fontsize=120pt,parskip=half,pagesize]{scrartcl}
2
+
3
+ \usepackage[utf8]{inputenc}
4
+ \usepackage[T1]{fontenc}
5
+
6
+ % Palatino / Helvetica
7
+ \usepackage{mathpazo}
8
+ \usepackage[scaled=.95]{helvet}
9
+
10
+ \usepackage[margin=2cm]{geometry}
11
+
12
+ % PDF-Metainformationen
13
+ \usepackage[pdftitle={Sample PDF Document},
14
+ pdfauthor={Marcus Stollsteimer},
15
+ pdfkeywords={},
16
+ pdfpagemode=UseNone,
17
+ pdfstartview=FitH,% Fit Width
18
+ bookmarks=false%
19
+ ]{hyperref}
20
+
21
+ \pagestyle{empty}
22
+
23
+ \begin{document}
24
+
25
+ \centering
26
+
27
+ Page\\ One
28
+
29
+ \newpage
30
+
31
+ Page\\ Two
32
+
33
+ \newpage
34
+
35
+ Page\\ Three
36
+
37
+ \end{document}
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/ruby -w
2
+ # test_pdfmult: Unit tests for the pdfmult script.
3
+ #
4
+ # Copyright (C) 2011-2012 Marcus Stollsteimer
5
+
6
+ require 'minitest/spec'
7
+ require 'minitest/autorun'
8
+ require 'pdfmult'
9
+
10
+ PROGNAME = 'test_pdfmult.rb'
11
+ PROGVERSION = '0.0.1'
12
+
13
+ SRCPATH = File.dirname(__FILE__)
14
+
15
+
16
+ describe Pdfmult::Optionparser do
17
+
18
+ it 'should return the correct default values' do
19
+ options = Pdfmult::Optionparser.parse!(['sample.pdf'])
20
+ expected = {
21
+ :infile => 'sample.pdf',
22
+ :outfile => 'sample_2.pdf',
23
+ :number => 2,
24
+ :pages => nil
25
+ }
26
+ options.must_equal expected
27
+ end
28
+
29
+ it 'should recognize the -n option and set the corresponding output filename' do
30
+ options = Pdfmult::Optionparser.parse!(['sample.pdf', '-n', '4'])
31
+ options[:outfile].must_equal 'sample_4.pdf'
32
+ options[:number].must_equal 4
33
+ end
34
+
35
+ it 'should not accept invalid -n option values' do
36
+ lambda { Pdfmult::Optionparser.parse!(['sample.pdf', '-n', '3']) }.must_raise OptionParser::InvalidArgument
37
+ end
38
+
39
+ it 'should recognize the -o option' do
40
+ options = Pdfmult::Optionparser.parse!(['sample.pdf', '-o', 'outfile.pdf'])
41
+ options[:outfile].must_equal 'outfile.pdf'
42
+ end
43
+
44
+ it 'should recognize the -p option' do
45
+ options = Pdfmult::Optionparser.parse!(['sample.pdf', '-p', '4'])
46
+ options[:pages].must_equal 4
47
+ end
48
+
49
+ it 'should only accept positive -p option values' do
50
+ lambda { Pdfmult::Optionparser.parse!(['sample.pdf', '-p', '0.5']) }.must_raise OptionParser::InvalidArgument
51
+ lambda { Pdfmult::Optionparser.parse!(['sample.pdf', '-p', '0']) }.must_raise OptionParser::InvalidArgument
52
+ lambda { Pdfmult::Optionparser.parse!(['sample.pdf', '-p', '-1']) }.must_raise OptionParser::InvalidArgument
53
+ end
54
+
55
+ it 'should not accept wrong number of arguments' do
56
+ lambda { Pdfmult::Optionparser.parse!(['sample.pdf', 'sample2.pdf']) }.must_raise ArgumentError
57
+ lambda { Pdfmult::Optionparser.parse!(['']) }.must_raise ArgumentError
58
+ lambda { Pdfmult::Optionparser.parse!([]) }.must_raise ArgumentError
59
+ end
60
+
61
+ it 'should not accept invalid options' do
62
+ lambda { Pdfmult::Optionparser.parse!(['-x']) }.must_raise OptionParser::InvalidOption
63
+ end
64
+ end
65
+
66
+
67
+ describe Pdfmult::LaTeXDocument do
68
+
69
+ it 'should return the expected LaTeX code' do
70
+ document = Pdfmult::LaTeXDocument.new('sample.pdf', 8, 3)
71
+ document.to_s.split(/\n/)[0].must_equal "\\documentclass[a4paper,landscape]{article}"
72
+ document.to_s.split(/\n/)[-2].must_equal "\\includepdf[pages={3,3,3,3,3,3,3,3},nup=4x2]{sample.pdf}%"
73
+ end
74
+ end
75
+
76
+
77
+ describe Pdfmult::PDFInfo do
78
+
79
+ before do
80
+ @sample_pdf = File.expand_path("#{SRCPATH}/sample.pdf")
81
+ end
82
+
83
+ describe 'when asked about the page count' do
84
+ it 'should return the page count for existing file and system tool' do
85
+ infocmd = Pdfmult::PDFInfo::PDFINFOCMD
86
+ skip("Skipped: `#{infocmd}' not available on the system") unless Pdfmult::PDFInfo.infocmd_available?
87
+ Pdfmult::PDFInfo.new(@sample_pdf).page_count.must_equal 3
88
+ Pdfmult::PDFInfo.new(@sample_pdf, :pdfinfocmd => infocmd).page_count.must_equal 3
89
+ end
90
+
91
+ it 'should return nil for non-existent files' do
92
+ Pdfmult::PDFInfo.new('not_a_file.pdf').page_count.must_be_nil
93
+ end
94
+
95
+ it "should return nil for non-existent `pdfinfo' system tool" do
96
+ Pdfmult::PDFInfo.new(@sample_pdf, :pdfinfocmd => 'not_a_command').page_count.must_be_nil
97
+ end
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdfmult
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Marcus Stollsteimer
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-15 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rake
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: minitest
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ description: pdfmult is a command line tool that rearranges multiple copies of a PDF page (shrunken) on one page.
49
+ email: sto.mar@web.de
50
+ executables:
51
+ - pdfmult
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - README.md
58
+ - Rakefile
59
+ - pdfmult.gemspec
60
+ - pdfmult.h2m
61
+ - example1.fig
62
+ - example1.png
63
+ - example2.fig
64
+ - example2.png
65
+ - bin/pdfmult
66
+ - lib/pdfmult.rb
67
+ - man/pdfmult.1
68
+ - test/sample.tex
69
+ - test/test_pdfmult.rb
70
+ - test/sample.pdf
71
+ homepage: https://github.com/stomar/pdfmult/
72
+ licenses:
73
+ - GPL-3
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --charset=UTF-8
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ requirements:
98
+ - pdflatex and the pdfpages package
99
+ rubyforge_project: pdfmult
100
+ rubygems_version: 1.7.2
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: pdfmult - puts multiple copies of a PDF page on one page
104
+ test_files:
105
+ - test/test_pdfmult.rb