diff --git a/README.rst b/README.rst index 6c671b2..7fa5418 100644 --- a/README.rst +++ b/README.rst @@ -83,9 +83,17 @@ Examples: # reverse some of the pages in a.pdf by specifying a negative range stapler sel a.pdf 1-3 9-6 10 output.pdf +The ``sele`` command is an extension of ``sel``. The usage is the same as that +of ``sel``, but ``sele`` inserts an empty page after each input file if that +input file has an odd number of pages so that each input file starts with an +even page number in the generated output. The empty page shall have the same +size as the page previous to it. You may find this mode useful if you read in +double-page layout or if you want to print the concatenated output. + The delete command works almost exactly the same as select, but inverse. It uses the pages and ranges which you *didn't* specify. + split/burst: ~~~~~~~~~~~~ diff --git a/staplelib/commands.py b/staplelib/commands.py index 66f6aba..9506613 100644 --- a/staplelib/commands.py +++ b/staplelib/commands.py @@ -11,13 +11,14 @@ from . import CommandError, iohelper import staplelib - -def select(args, inverse=False): +def select(args, inverse=False, even_page=False): """ Concatenate files / select pages from files. inverse=True excludes rather than includes the selected pages from the file. + even_page=True inserts an empty page at the end of each input + file if it ends with an odd page number. """ filesandranges = iohelper.parse_ranges(args[:-1]) @@ -28,6 +29,7 @@ def select(args, inverse=False): raise CommandError("Both input and output filenames are required.") output = PdfFileWriter() + pagecnt = 0 try: for input in filesandranges: pdf = input['pdf'] @@ -51,12 +53,18 @@ def select(args, inverse=False): print "Using page: {} (rotation: {} deg.)".format( pageno, rotate) - output.addPage(pdf.getPage(pageno-1) - .rotateClockwise(rotate)) + page = pdf.getPage(pageno-1) + output.addPage(page.rotateClockwise(rotate)) + pagecnt += 1 else: raise CommandError("Page {} not found in {}.".format( pageno, input['name'])) + if even_page: + if pagecnt % 2 == 1: + output.addPage(iohelper.create_empty_page(page)) + pagecnt += 1 + except Exception, e: raise CommandError(e) @@ -66,6 +74,16 @@ def select(args, inverse=False): iohelper.write_pdf(output, staplelib.OPTIONS.destdir + os.sep + outputfilename) +def select_even(args, inverse=False): + """ + Concatenate files / select pages from files. + + Inserts an empty page at the end of each input file if it ends with + an odd page number. + """ + + select(args, inverse, True) + def delete(args): """Concatenate files and remove pages from files.""" diff --git a/staplelib/iohelper.py b/staplelib/iohelper.py index 600a4ff..97b8f9c 100644 --- a/staplelib/iohelper.py +++ b/staplelib/iohelper.py @@ -10,6 +10,9 @@ except ImportError: from pyPdf import PdfFileWriter, PdfFileReader +from reportlab.lib import pagesizes +from reportlab.pdfgen import canvas +from StringIO import StringIO from . import CommandError import staplelib @@ -124,3 +127,25 @@ def parse_ranges(files_and_ranges): current['pages'].append((p, rotate)) return operations + + +def create_empty_page(refpage=None): + """Create an empty page with the same size as refpage.""" + + if refpage is not None: + pagesize = refpage.mediaBox[-2:] + else: + pagesize = pagesizes.letter + + c = canvas.Canvas(None) + c.setPageSize(pagesize) + c.showPage() + + buf = StringIO() + buf.write(c.getpdfdata()) + buf.seek(0) + + reader = PdfFileReader(buf) + return reader.getPage(0) + + diff --git a/staplelib/stapler.py b/staplelib/stapler.py index 43c10c2..67ae3b5 100644 --- a/staplelib/stapler.py +++ b/staplelib/stapler.py @@ -14,7 +14,7 @@ usage: %prog [options] mode input.pdf ... [output.pdf] Modes: -cat/sel: [[]] ... (output needed) +cat/sel/sele: [[]] ... (output needed) Select the given pages/ranges from input files. No range means all pages. del: [[]] ... (output needed) @@ -68,6 +68,7 @@ def main(): modes = { "cat": commands.select, "sel": commands.select, + "sele": commands.select_even, "split": commands.split, "burst": commands.split, "del": commands.delete,