summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-06-14 22:17:46 +0000
committerKarl Berry <karl@freefriends.org>2015-06-14 22:17:46 +0000
commit4cad9cf047cf4bb824a71c8af70edee1b20874f1 (patch)
tree9dca48848d460108937bd24f6d66179e16dfe1a2
parentbf587c17edfdc46c03e91570278a8faa0c4285a0 (diff)
pdfbook2 (4jun15)
git-svn-id: svn://tug.org/texlive/trunk@37537 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/texlive/linked_scripts/Makefile.am1
-rw-r--r--Build/source/texk/texlive/linked_scripts/Makefile.in1
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2237
l---------Master/bin/alpha-linux/pdfbook21
l---------Master/bin/amd64-freebsd/pdfbook21
l---------Master/bin/amd64-netbsd/pdfbook21
l---------Master/bin/armel-linux/pdfbook21
l---------Master/bin/armhf-linux/pdfbook21
l---------Master/bin/i386-cygwin/pdfbook21
l---------Master/bin/i386-freebsd/pdfbook21
l---------Master/bin/i386-linux/pdfbook21
l---------Master/bin/i386-netbsd/pdfbook21
l---------Master/bin/i386-solaris/pdfbook21
l---------Master/bin/mipsel-linux/pdfbook21
l---------Master/bin/powerpc-linux/pdfbook21
l---------Master/bin/sparc-solaris/pdfbook21
l---------Master/bin/universal-darwin/pdfbook21
-rwxr-xr-xMaster/bin/win32/pdfbook2.exebin0 -> 1536 bytes
l---------Master/bin/x86_64-cygwin/pdfbook21
l---------Master/bin/x86_64-darwin/pdfbook21
l---------Master/bin/x86_64-linux/pdfbook21
l---------Master/bin/x86_64-solaris/pdfbook21
-rw-r--r--Master/texmf-dist/doc/man/man1/pdfbook2.1121
-rw-r--r--Master/texmf-dist/doc/man/man1/pdfbook2.man1.pdfbin0 -> 7053 bytes
-rw-r--r--Master/texmf-dist/doc/support/pdfbook2/README133
-rwxr-xr-xMaster/texmf-dist/scripts/pdfbook2/pdfbook2237
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds2
-rw-r--r--Master/tlpkg/tlpsrc/collection-binextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/pdfbook2.tlpsrc2
30 files changed, 754 insertions, 1 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am
index 09e66a19753..3f84ef1b853 100644
--- a/Build/source/texk/texlive/linked_scripts/Makefile.am
+++ b/Build/source/texk/texlive/linked_scripts/Makefile.am
@@ -140,6 +140,7 @@ texmf_other_scripts = \
musixtex/musixtex.lua \
oberdiek/pdfatfi.pl \
pax/pdfannotextractor.pl \
+ pdfbook2/pdfbook2 \
pdfcrop/pdfcrop.pl \
pedigree-perl/pedigree.pl \
perltex/perltex.pl \
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in
index bfba303b51f..a5650b423ac 100644
--- a/Build/source/texk/texlive/linked_scripts/Makefile.in
+++ b/Build/source/texk/texlive/linked_scripts/Makefile.in
@@ -358,6 +358,7 @@ texmf_other_scripts = \
musixtex/musixtex.lua \
oberdiek/pdfatfi.pl \
pax/pdfannotextractor.pl \
+ pdfbook2/pdfbook2 \
pdfcrop/pdfcrop.pl \
pedigree-perl/pedigree.pl \
perltex/perltex.pl \
diff --git a/Build/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2 b/Build/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2
new file mode 100755
index 00000000000..a288df70fd5
--- /dev/null
+++ b/Build/source/texk/texlive/linked_scripts/pdfbook2/pdfbook2
@@ -0,0 +1,237 @@
+#!/usr/bin/env python
+""" pdfbook2 - transform pdf files to booklets
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ """
+
+
+import sys
+import subprocess
+import os
+from optparse import OptionParser, OptionGroup, HelpFormatter
+import shutil
+
+
+#===============================================================================
+# Create booklet for file $name
+#===============================================================================
+
+def booklify( name, opts ):
+ #------------------------------------------------------ Check if file exists
+ print "\nProcessing", name
+ if not os.path.isfile( name ):
+ print "SKIP: file not found."
+ return
+ print "Getting bounds...",
+ sys.stdout.flush()
+
+ #---------------------------------------------------------- useful constants
+ bboxName = "%%HiResBoundingBox:"
+ tmpFile = ".crop-tmp.pdf"
+
+ #------------------------------------------------- find min/max bounding box
+ if opts.crop:
+ p = subprocess.Popen( ["pdfcrop", "--verbose",
+ "--resolution", repr( opts.resolution ),
+ name, tmpFile],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+ out, err = p.communicate()
+ if len( err ) != 0:
+ print err
+ print "\n\nABORT: Problem getting bounds"
+ sys.exit( 1 )
+ lines = out.splitlines()
+ bboxes = [s[len( bboxName ) + 1:] for s in lines if s.startswith( bboxName )]
+ bounds = [[float( x ) for x in bbox.split()] for bbox in bboxes ]
+ minLOdd = min( [bound[0] for bound in bounds[::2] ] )
+ maxROdd = max( [bound[2] for bound in bounds[::2] ] )
+ minLEven = min( [bound[0] for bound in bounds[1::2] ] )
+ maxREven = max( [bound[2] for bound in bounds[1::2] ] )
+ minT = min( [bound[1] for bound in bounds ] )
+ maxB = max( [bound[3] for bound in bounds ] )
+
+ widthOdd = maxROdd - minLOdd
+ widthEven = maxREven - minLEven
+ maxWidth = max( widthOdd, widthEven )
+ minLOdd -= maxWidth - widthOdd
+ maxREven += maxWidth - widthEven
+
+ print "done"
+ sys.stdout.flush()
+
+ #--------------------------------------------- crop file to area of interest
+ print "cropping...",
+ sys.stdout.flush()
+ p = subprocess.Popen( ["pdfcrop",
+ "--bbox-odd", "{L} {T} {R} {B}".format( L = minLOdd - opts.innerMargin / 2,
+ T = minT - opts.topMargin,
+ R = maxROdd + opts.outerMargin,
+ B = maxB + opts.outerMargin ),
+ "--bbox-even", "{L} {T} {R} {B}".format( L = minLEven - opts.outerMargin,
+ T = minT - opts.topMargin,
+ R = maxREven + opts.innerMargin / 2,
+ B = maxB + opts.outerMargin ),
+ "--resolution", repr( opts.resolution ),
+ name,
+ tmpFile],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+ out, err = p.communicate()
+ if len( err ) != 0:
+ print err
+ print "\n\nABORT: Problem with cropping"
+ sys.exit( 1 )
+ print "done"
+ sys.stdout.flush()
+ else:
+ shutil.copy( name, tmpFile )
+
+ #-------------------------------------------------------- create the booklet
+ print "create booklet...",
+ sys.stdout.flush()
+ pdfJamCallList = [ "pdfjam",
+ "--booklet", "true",
+ "--landscape",
+ "--suffix", "book",
+ "--signature", repr( opts.signature ),
+ tmpFile ]
+
+ # add option --paper to call
+ if opts.paper is not None:
+ pdfJamCallList.append( "--paper" )
+ pdfJamCallList.append( opts.paper )
+
+ # add option --short-edge to call
+ if opts.shortedge:
+ # check if everyshi.sty exists as texlive recommends
+ p = subprocess.Popen( ["kpsewhich", "everyshi.sty"],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+ out, err = p.communicate()
+ if len( out ) == 0:
+ print "\n\nABORT: The everyshi.sty latex package is needed for short-edge."
+ sys.exit( 1 )
+ else:
+ pdfJamCallList.append( "--preamble" )
+ pdfJamCallList.append( r"\usepackage{everyshi}\makeatletter\EveryShipout{\ifodd\c@page\pdfpageattr{/Rotate 180}\fi}\makeatother" )
+
+ # run call to pdfJam to make booklet
+ p = subprocess.Popen( pdfJamCallList,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+
+ #-------------------------------------------- move file and remove temp file
+ os.rename( tmpFile[:-4] + "-book.pdf", name[:-4] + "-book.pdf" )
+ os.remove( tmpFile )
+ print "done"
+ sys.stdout.flush()
+
+
+#===============================================================================
+# Help formatter
+#===============================================================================
+
+class MyHelpFormatter ( HelpFormatter ):
+ """Format help with indented section bodies.
+ """
+
+ def __init__( self,
+ indent_increment = 4,
+ max_help_position = 16,
+ width = None,
+ short_first = 0 ):
+ HelpFormatter.__init__(
+ self, indent_increment, max_help_position, width, short_first )
+
+ def format_usage( self, usage ):
+ return ( "USAGE\n\n%*s%s\n" ) % ( self.indent_increment, "", usage )
+
+ def format_heading( self, heading ):
+ return "%*s%s\n\n" % ( self.current_indent, "", heading.upper() )
+
+
+#===============================================================================
+# main programm
+#===============================================================================
+
+if __name__ == "__main__":
+ #------------------------------------------------------------ useful strings
+ usageString = "Usage: %prog [options] file1 [file2 ...]"
+ versionString = """
+ %prog v1.2
+ (c) 2015 Johannes Neumann (http://www.neumannjo.de)
+ licensed under GPLv3 (http://www.gnu.org/licenses/gpl-3.0)
+ based on pdfbook by David Firth with help from Marco Pessotto\n"""
+ defaultString = " (default: %default)"
+
+ #------------------------------------------------- create commandline parser
+ parser = OptionParser( usage = usageString, version = versionString,
+ formatter = MyHelpFormatter( indent_increment = 4 ) )
+
+ generalGroup = OptionGroup( parser, "General" )
+ generalGroup.add_option( "-p", "--paper", dest = "paper", type = "str", action = "store",
+ metavar = "STR",
+ help = "Format of the output paper dimensions as latex keyword (e.g. a4paper, letterpaper, legalpaper, ...)" )
+ generalGroup.add_option( "-s", "--short-edge", dest = "shortedge", action = "store_true",
+ help = "Format the booklet for short-edge double-sided printing",
+ default = False )
+ generalGroup.add_option( "-n", "--no-crop", dest = "crop", action = "store_false",
+ help = "Prevent the cropping to the content area",
+ default = True )
+ parser.add_option_group( generalGroup )
+
+ marginGroup = OptionGroup( parser, "Margins" )
+ marginGroup.add_option( "-o", "--outer-margin", type = "int", default = 40,
+ dest = "outerMargin", action = "store", metavar = "INT",
+ help = "Defines the outer margin in the booklet" + defaultString )
+ marginGroup.add_option( "-i", "--inner-margin", type = "int", default = 150,
+ dest = "innerMargin", action = "store", metavar = "INT",
+ help = "Defines the inner margin between the pages in the booklet" + defaultString )
+ marginGroup.add_option( "-t", "--top-margin", type = "int", default = 30,
+ dest = "topMargin", action = "store", metavar = "INT",
+ help = "Defines the top margin in the booklet" + defaultString )
+ marginGroup.add_option( "-b", "--bottom-margin", type = "int", default = 30, metavar = "INT",
+ dest = "bottomMargin", action = "store",
+ help = "Defines the bottom margin in the booklet" + defaultString )
+ parser.add_option_group( marginGroup )
+
+ advancedGroup = OptionGroup( parser, "Advanced" )
+ advancedGroup.add_option( "--signature", dest = "signature", action = "store", type = "int",
+ help = "Define the signature for the booklet handed to pdfjam, needs to be multiple of 4" + defaultString,
+ default = 4, metavar = "INT" )
+ advancedGroup.add_option( "--signature*", dest = "signature", action = "store", type = "int",
+ help = "Same as --signature", metavar = "INT" )
+ advancedGroup.add_option( "--resolution", dest = "resolution", action = "store", type = "int",
+ help = "Resolution used by ghostscript in bp" + defaultString,
+ metavar = "INT", default = 72 )
+ parser.add_option_group( advancedGroup )
+
+ opts, args = parser.parse_args()
+
+ #------------------------------------ show help if started without arguments
+ if len( args ) == 0:
+ parser.print_version()
+ parser.print_help()
+ print ""
+ sys.exit( 2 )
+
+ #------------------------------------------- run for each provided file name
+ parser.print_version()
+ for arg in args:
+ booklify( arg, opts )
diff --git a/Master/bin/alpha-linux/pdfbook2 b/Master/bin/alpha-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/alpha-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/amd64-freebsd/pdfbook2 b/Master/bin/amd64-freebsd/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/amd64-freebsd/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/amd64-netbsd/pdfbook2 b/Master/bin/amd64-netbsd/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/amd64-netbsd/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/armel-linux/pdfbook2 b/Master/bin/armel-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/armel-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/armhf-linux/pdfbook2 b/Master/bin/armhf-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/armhf-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/i386-cygwin/pdfbook2 b/Master/bin/i386-cygwin/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/i386-cygwin/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/i386-freebsd/pdfbook2 b/Master/bin/i386-freebsd/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/i386-freebsd/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/i386-linux/pdfbook2 b/Master/bin/i386-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/i386-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/i386-netbsd/pdfbook2 b/Master/bin/i386-netbsd/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/i386-netbsd/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/i386-solaris/pdfbook2 b/Master/bin/i386-solaris/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/i386-solaris/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/mipsel-linux/pdfbook2 b/Master/bin/mipsel-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/mipsel-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/powerpc-linux/pdfbook2 b/Master/bin/powerpc-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/powerpc-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/sparc-solaris/pdfbook2 b/Master/bin/sparc-solaris/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/sparc-solaris/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/universal-darwin/pdfbook2 b/Master/bin/universal-darwin/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/universal-darwin/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/win32/pdfbook2.exe b/Master/bin/win32/pdfbook2.exe
new file mode 100755
index 00000000000..5777d90a17a
--- /dev/null
+++ b/Master/bin/win32/pdfbook2.exe
Binary files differ
diff --git a/Master/bin/x86_64-cygwin/pdfbook2 b/Master/bin/x86_64-cygwin/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/x86_64-cygwin/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/x86_64-darwin/pdfbook2 b/Master/bin/x86_64-darwin/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/x86_64-darwin/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/x86_64-linux/pdfbook2 b/Master/bin/x86_64-linux/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/x86_64-linux/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/bin/x86_64-solaris/pdfbook2 b/Master/bin/x86_64-solaris/pdfbook2
new file mode 120000
index 00000000000..bb39290d77a
--- /dev/null
+++ b/Master/bin/x86_64-solaris/pdfbook2
@@ -0,0 +1 @@
+../../texmf-dist/scripts/pdfbook2/pdfbook2 \ No newline at end of file
diff --git a/Master/texmf-dist/doc/man/man1/pdfbook2.1 b/Master/texmf-dist/doc/man/man1/pdfbook2.1
new file mode 100644
index 00000000000..713ad258d7a
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/pdfbook2.1
@@ -0,0 +1,121 @@
+.TH pdfbook2 1 "June 3, 2015" "" "pdfbook2 - transform pdf files to booklets"
+
+.SH NAME
+pdfbook2 \- transform pdf files into booklets for double-sided printing
+
+.SH SYNOPSIS
+\fBpdfbook2\fR [ \fIoptions\fR ] \fIINPUT\fR [ \fIINPUT\fR, ...]
+
+.SH DESCRIPTION
+Create print-ready PDF files from some \fIINPUT\fR PDF files for booklet printing. The resulting files need to be printed in landscape/long edge double sided printing. The default paper format depends on the locale and is choosen by pdfjam. It can be set with the --paper option.
+.PP
+Before the pdf is composed the \fIINPUT\fR file is cropped to the relevant area in order to discard unnecessary white spaces. In this process, all pages are cropped to the same dimensions. Extra margins can be defined at the edges of the booklet and in the middle where the binding occurs.
+.PP
+The \fIOUTPUT\fR is written to \fIINPUT\fR-book.pdf. Existing files will be overwritten. All input files are processed seperatly.
+
+.SH EXAMPLE
+To simply \fBcreate a booklet\fR from input.pdf you can use
+.PP
+.nf
+.RS
+pdfbook2 input.pdf
+.RE
+.fi
+.PP
+to create input-book.pdf. To select a special \fBtype of paper\fR you can do
+.PP
+.nf
+.RS
+pdfbook2 --paper=letter input.pdf
+.RE
+.fi
+.PP
+for letter or
+.PP
+.nf
+.RS
+pdfbook2 --paper=a4paper input.pdf
+.RE
+.fi
+.PP
+for standard A4. To increase the \fBinner margin for binding\fR use
+.PP
+.nf
+.RS
+pdfbook2 --inner-margin=200 input.pdf
+.RE
+.fi
+.PP
+to increase the default value of 150. You can submit \fBmultiple files\fR to the
+script for processing like
+.PP
+.nf
+.RS
+pdfbook2 input1.pdf input2.pdf
+.RE
+.fi
+.PP
+which will result in input1-book.pdf and input2-book.pdf.
+
+.SH OPTIONS
+.TP
+.BR \-\-version
+show program's version number and exit
+.TP
+.BR -h ", " --help
+show help message and exit
+
+.SS GENERAL
+.TP
+.BR -p ", " --paper = \fISTR\fR
+Format of the output paper dimensions as latex keyword (e.g. a4paper, letterpaper, legalpaper, ...)
+.TP
+.BR -s ", " --short-edge
+Format the booklet for short-edge double-sided printing
+.TP
+.BR -n ", " --no-crop
+Prevent the cropping to the content area
+
+.SS MARGINS
+.TP
+.BR -o ", " --outer-margin = \fIINT\fR
+Defines the outer margin in the booklet (default: 40)
+.TP
+.BR -i ", " --inner-margin = \fIINT\fR
+Defines the inner margin between the pages in the booklet (default: 150)
+.TP
+.BR -t ", " --top-margin = \fIINT\fR
+Defines the top margin in the booklet (default: 30)
+.TP
+.BR -b ", " --bottom-margin = \fIINT\fR
+Defines the bottom margin in the booklet (default: 30)
+
+.SS ADVANCED
+.TP
+.BR --signature = \fIINT\fR
+Define the signature for the booklet handed to pdfjam, needs to be multiple of 4 (default: 4)
+.TP
+.BR --signature* = \fIINT\fR
+Same as --signature
+.TP
+.BR --resolution = \fIINT\fR
+Resolution used by ghostscript in bp (default: 72)
+
+.SH "SEE ALSO"
+.BR pdfbook (1),
+.BR pdfjam (1),
+.BR pdfcrop (1)
+
+.SH ABOUT
+pdfbook2 v1.2
+.br
+(c) 2015 Johannes Neumann (http://www.neumannjo.de)
+.br
+licensed under GPLv3 (http://www.gnu.org/licenses/gpl-3.0)
+.br
+based on pdfbook by David Firth with help from Marco Pessotto
+
+.SH LICENSE
+This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
diff --git a/Master/texmf-dist/doc/man/man1/pdfbook2.man1.pdf b/Master/texmf-dist/doc/man/man1/pdfbook2.man1.pdf
new file mode 100644
index 00000000000..4e0a92cdad1
--- /dev/null
+++ b/Master/texmf-dist/doc/man/man1/pdfbook2.man1.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/support/pdfbook2/README b/Master/texmf-dist/doc/support/pdfbook2/README
new file mode 100644
index 00000000000..fd7dfa406f1
--- /dev/null
+++ b/Master/texmf-dist/doc/support/pdfbook2/README
@@ -0,0 +1,133 @@
+pdfbook2 - transform pdf files to booklets
+==========================================
+
+ pdfbook2 v1.2
+ (c) 2015 Johannes Neumann (http://www.neumannjo.de)
+ licensed under GPLv3 (http://www.gnu.org/licenses/gpl-3.0)
+ based on pdfbook by David Firth with help from Marco Pessotto
+
+DESCRIPTION
+
+ Create print-ready PDF files from some INPUT PDF files for booklet printing.
+ The resulting files need to be printed in landscape/long edge double sided
+ printing. The default paper format depends on the locale and is choosen by
+ pdfjam. It can be set with the --paper option.
+
+ Before the pdf is composed the INPUT file is cropped to the relevant area in
+ order to discard unnecessary white spaces. In this process, all pages are
+ cropped to the same dimensions. Extra margins can be defined at the edges of
+ the booklet and in the middle where the binding occurs.
+
+ The OUTPUT is written to INPUT-book.pdf. Existing files will be overwritten.
+ All input files are processed seperatly.
+
+LICENSE
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details. You should have received a copy of the GNU General Public
+ License along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+INSTALLATION
+
+ Simply copy the file to any convenient location preferably covered by the
+ PATH variable of your shell. Make sure it is set as executable like
+
+ chmod +x pdfbook2
+
+ for unix like systems.
+
+REQUIREMENTS
+
+ python 2.7, pdfjam, pdfcrop and their dependencies.
+
+EXAMPLES
+
+ To simply create a booklet from input.pdf you can use
+
+ pdfbook2 input.pdf
+
+ to create input-book.pdf. To select a special type of paper you can do
+
+ pdfbook2 --paper=letter input.pdf
+
+ for letter or
+
+ pdfbook2 --paper=a4paper input.pdf
+
+ for standard A4. To increase the inner margin for binding use
+
+ pdfbook2 --inner-margin=200 input.pdf
+
+ to increase the default value of 150. You can submit multiple files to the
+ script for processing like
+
+ pdfbook2 input1.pdf input2.pdf
+
+ which will result in input1-book.pdf and input2-book.pdf.
+
+USAGE
+
+ pdfbook2 [options] file1 [file2 ...]
+
+OPTIONS
+
+ --version show program's version number and exit
+ --help, -h show this help message and exit
+
+ GENERAL
+
+ --paper=STR, -p STR
+ Format of the output paper dimensions as latex keyword (e.g.
+ a4paper, letterpaper, legalpaper, ...)
+ --short-edge, -s
+ Format the booklet for short-edge double-sided printing
+ --no-crop, -n
+ Prevent the cropping to the content area
+
+ MARGINS
+
+ --outer-margin=INT, -o INT
+ Defines the outer margin in the booklet (default: 40)
+ --inner-margin=INT, -i INT
+ Defines the inner margin between the pages in the booklet
+ (default: 150)
+ --top-margin=INT, -t INT
+ Defines the top margin in the booklet (default: 30)
+ --bottom-margin=INT, -b INT
+ Defines the bottom margin in the booklet (default: 30)
+
+ ADVANCED
+
+ --signature=INT
+ Define the signature for the booklet handed to pdfjam, needs to
+ be multiple of 4 (default: 4)
+ --signature*=INT
+ Same as --signature
+ --resolution=INT
+ Resolution used by ghostscript in bp (default: 72)
+
+CHANGELOG
+
+ 1.2 2015/06/03
+
+ - added man page
+
+ 1.1 2015/06/01
+
+ - added resolution, signature, no-crop options
+ - better handling of input files with different margins on odd and
+ even pages
+ - added short options
+ - speedup for bound calculations and cropping by setting ghostscript
+ resolution to 72 (ref. --resolution option)
+
+ 1.0 2015/05/27
+
+ - initial version
diff --git a/Master/texmf-dist/scripts/pdfbook2/pdfbook2 b/Master/texmf-dist/scripts/pdfbook2/pdfbook2
new file mode 100755
index 00000000000..a288df70fd5
--- /dev/null
+++ b/Master/texmf-dist/scripts/pdfbook2/pdfbook2
@@ -0,0 +1,237 @@
+#!/usr/bin/env python
+""" pdfbook2 - transform pdf files to booklets
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ """
+
+
+import sys
+import subprocess
+import os
+from optparse import OptionParser, OptionGroup, HelpFormatter
+import shutil
+
+
+#===============================================================================
+# Create booklet for file $name
+#===============================================================================
+
+def booklify( name, opts ):
+ #------------------------------------------------------ Check if file exists
+ print "\nProcessing", name
+ if not os.path.isfile( name ):
+ print "SKIP: file not found."
+ return
+ print "Getting bounds...",
+ sys.stdout.flush()
+
+ #---------------------------------------------------------- useful constants
+ bboxName = "%%HiResBoundingBox:"
+ tmpFile = ".crop-tmp.pdf"
+
+ #------------------------------------------------- find min/max bounding box
+ if opts.crop:
+ p = subprocess.Popen( ["pdfcrop", "--verbose",
+ "--resolution", repr( opts.resolution ),
+ name, tmpFile],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+ out, err = p.communicate()
+ if len( err ) != 0:
+ print err
+ print "\n\nABORT: Problem getting bounds"
+ sys.exit( 1 )
+ lines = out.splitlines()
+ bboxes = [s[len( bboxName ) + 1:] for s in lines if s.startswith( bboxName )]
+ bounds = [[float( x ) for x in bbox.split()] for bbox in bboxes ]
+ minLOdd = min( [bound[0] for bound in bounds[::2] ] )
+ maxROdd = max( [bound[2] for bound in bounds[::2] ] )
+ minLEven = min( [bound[0] for bound in bounds[1::2] ] )
+ maxREven = max( [bound[2] for bound in bounds[1::2] ] )
+ minT = min( [bound[1] for bound in bounds ] )
+ maxB = max( [bound[3] for bound in bounds ] )
+
+ widthOdd = maxROdd - minLOdd
+ widthEven = maxREven - minLEven
+ maxWidth = max( widthOdd, widthEven )
+ minLOdd -= maxWidth - widthOdd
+ maxREven += maxWidth - widthEven
+
+ print "done"
+ sys.stdout.flush()
+
+ #--------------------------------------------- crop file to area of interest
+ print "cropping...",
+ sys.stdout.flush()
+ p = subprocess.Popen( ["pdfcrop",
+ "--bbox-odd", "{L} {T} {R} {B}".format( L = minLOdd - opts.innerMargin / 2,
+ T = minT - opts.topMargin,
+ R = maxROdd + opts.outerMargin,
+ B = maxB + opts.outerMargin ),
+ "--bbox-even", "{L} {T} {R} {B}".format( L = minLEven - opts.outerMargin,
+ T = minT - opts.topMargin,
+ R = maxREven + opts.innerMargin / 2,
+ B = maxB + opts.outerMargin ),
+ "--resolution", repr( opts.resolution ),
+ name,
+ tmpFile],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+ out, err = p.communicate()
+ if len( err ) != 0:
+ print err
+ print "\n\nABORT: Problem with cropping"
+ sys.exit( 1 )
+ print "done"
+ sys.stdout.flush()
+ else:
+ shutil.copy( name, tmpFile )
+
+ #-------------------------------------------------------- create the booklet
+ print "create booklet...",
+ sys.stdout.flush()
+ pdfJamCallList = [ "pdfjam",
+ "--booklet", "true",
+ "--landscape",
+ "--suffix", "book",
+ "--signature", repr( opts.signature ),
+ tmpFile ]
+
+ # add option --paper to call
+ if opts.paper is not None:
+ pdfJamCallList.append( "--paper" )
+ pdfJamCallList.append( opts.paper )
+
+ # add option --short-edge to call
+ if opts.shortedge:
+ # check if everyshi.sty exists as texlive recommends
+ p = subprocess.Popen( ["kpsewhich", "everyshi.sty"],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+ out, err = p.communicate()
+ if len( out ) == 0:
+ print "\n\nABORT: The everyshi.sty latex package is needed for short-edge."
+ sys.exit( 1 )
+ else:
+ pdfJamCallList.append( "--preamble" )
+ pdfJamCallList.append( r"\usepackage{everyshi}\makeatletter\EveryShipout{\ifodd\c@page\pdfpageattr{/Rotate 180}\fi}\makeatother" )
+
+ # run call to pdfJam to make booklet
+ p = subprocess.Popen( pdfJamCallList,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE )
+ p.wait()
+
+ #-------------------------------------------- move file and remove temp file
+ os.rename( tmpFile[:-4] + "-book.pdf", name[:-4] + "-book.pdf" )
+ os.remove( tmpFile )
+ print "done"
+ sys.stdout.flush()
+
+
+#===============================================================================
+# Help formatter
+#===============================================================================
+
+class MyHelpFormatter ( HelpFormatter ):
+ """Format help with indented section bodies.
+ """
+
+ def __init__( self,
+ indent_increment = 4,
+ max_help_position = 16,
+ width = None,
+ short_first = 0 ):
+ HelpFormatter.__init__(
+ self, indent_increment, max_help_position, width, short_first )
+
+ def format_usage( self, usage ):
+ return ( "USAGE\n\n%*s%s\n" ) % ( self.indent_increment, "", usage )
+
+ def format_heading( self, heading ):
+ return "%*s%s\n\n" % ( self.current_indent, "", heading.upper() )
+
+
+#===============================================================================
+# main programm
+#===============================================================================
+
+if __name__ == "__main__":
+ #------------------------------------------------------------ useful strings
+ usageString = "Usage: %prog [options] file1 [file2 ...]"
+ versionString = """
+ %prog v1.2
+ (c) 2015 Johannes Neumann (http://www.neumannjo.de)
+ licensed under GPLv3 (http://www.gnu.org/licenses/gpl-3.0)
+ based on pdfbook by David Firth with help from Marco Pessotto\n"""
+ defaultString = " (default: %default)"
+
+ #------------------------------------------------- create commandline parser
+ parser = OptionParser( usage = usageString, version = versionString,
+ formatter = MyHelpFormatter( indent_increment = 4 ) )
+
+ generalGroup = OptionGroup( parser, "General" )
+ generalGroup.add_option( "-p", "--paper", dest = "paper", type = "str", action = "store",
+ metavar = "STR",
+ help = "Format of the output paper dimensions as latex keyword (e.g. a4paper, letterpaper, legalpaper, ...)" )
+ generalGroup.add_option( "-s", "--short-edge", dest = "shortedge", action = "store_true",
+ help = "Format the booklet for short-edge double-sided printing",
+ default = False )
+ generalGroup.add_option( "-n", "--no-crop", dest = "crop", action = "store_false",
+ help = "Prevent the cropping to the content area",
+ default = True )
+ parser.add_option_group( generalGroup )
+
+ marginGroup = OptionGroup( parser, "Margins" )
+ marginGroup.add_option( "-o", "--outer-margin", type = "int", default = 40,
+ dest = "outerMargin", action = "store", metavar = "INT",
+ help = "Defines the outer margin in the booklet" + defaultString )
+ marginGroup.add_option( "-i", "--inner-margin", type = "int", default = 150,
+ dest = "innerMargin", action = "store", metavar = "INT",
+ help = "Defines the inner margin between the pages in the booklet" + defaultString )
+ marginGroup.add_option( "-t", "--top-margin", type = "int", default = 30,
+ dest = "topMargin", action = "store", metavar = "INT",
+ help = "Defines the top margin in the booklet" + defaultString )
+ marginGroup.add_option( "-b", "--bottom-margin", type = "int", default = 30, metavar = "INT",
+ dest = "bottomMargin", action = "store",
+ help = "Defines the bottom margin in the booklet" + defaultString )
+ parser.add_option_group( marginGroup )
+
+ advancedGroup = OptionGroup( parser, "Advanced" )
+ advancedGroup.add_option( "--signature", dest = "signature", action = "store", type = "int",
+ help = "Define the signature for the booklet handed to pdfjam, needs to be multiple of 4" + defaultString,
+ default = 4, metavar = "INT" )
+ advancedGroup.add_option( "--signature*", dest = "signature", action = "store", type = "int",
+ help = "Same as --signature", metavar = "INT" )
+ advancedGroup.add_option( "--resolution", dest = "resolution", action = "store", type = "int",
+ help = "Resolution used by ghostscript in bp" + defaultString,
+ metavar = "INT", default = 72 )
+ parser.add_option_group( advancedGroup )
+
+ opts, args = parser.parse_args()
+
+ #------------------------------------ show help if started without arguments
+ if len( args ) == 0:
+ parser.print_version()
+ parser.print_help()
+ print ""
+ sys.exit( 2 )
+
+ #------------------------------------------- run for each provided file name
+ parser.print_version()
+ for arg in args:
+ booklify( arg, opts )
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 5a1c291d7ed..ac342aca497 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -408,7 +408,7 @@ my @TLP_working = qw(
patch patchcmd patgen2-tutorial path pauldoc pawpict pax
pbox pb-diagram pbsheet
pdf14
- pdf-trans pdfcomment pdfcprot pdfcrop pdfjam pdfmarginpar
+ pdf-trans pdfbook2 pdfcomment pdfcprot pdfcrop pdfjam pdfmarginpar
pdfpages pdfscreen pdfslide pdfsync pdftex-def pdftricks pdftricks2 pdfx
pecha pedigree-perl perception perfectcut perltex
permute persian-bib
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index b987c3b8e67..052a4d18d40 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -2633,6 +2633,7 @@ $standardttf = '\.ttf';
'mkjobtexmf' => 'mkjobtexmf\.pl$',
'mkpic' => '^mkpic$',
'musixtex' => '\.lua$',
+ 'pdfbook2' => 'pdfbook2$',
'pdfcrop' => '\.pl$', # doscripts() does r*
'pdfjam' => 'pdf[^.]*$',
'pedigree-perl' => '\.pl$',
@@ -2699,6 +2700,7 @@ $standardttf = '\.ttf';
'musixtnt' => '\.1$',
'pedigree-perl' => '\.1$',
'perltex' => 'perltex.1',
+ 'pdfbook2' => '\.1$',
'pdfjam' => '\.1$',
'pkfix-helper' => 'pkfix-helper.1',
'pmx' => '\.1$',
diff --git a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
index 432a3af040c..f9cf3050f79 100644
--- a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc
@@ -50,6 +50,7 @@ depend listings-ext
depend match_parens
depend mkjobtexmf
depend patgen
+depend pdfbook2
depend pdfcrop
depend pdfjam
depend pdftools
diff --git a/Master/tlpkg/tlpsrc/pdfbook2.tlpsrc b/Master/tlpkg/tlpsrc/pdfbook2.tlpsrc
new file mode 100644
index 00000000000..aefd3a571c4
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/pdfbook2.tlpsrc
@@ -0,0 +1,2 @@
+binpattern f bin/${ARCH}/${PKGNAME}
+