Commits

Luke Plant  committed 9f4628e

Initial import

  • Participants

Comments (0)

Files changed (1)

File booklet_maker.py

+#!/usr/bin/env python
+import math
+import os
+import sys
+
+from PyPDF2 import PdfFileWriter, PdfFileReader
+
+
+class Sheet(object):
+    def __init__(self):
+        self.front = PrintPage()
+        self.back = PrintPage()
+
+
+class PrintPage(object):
+    def __init__(self):
+        self.left = PageContainer()
+        self.right = PageContainer()
+
+
+class PageContainer(object):
+    def __init__(self):
+        self.page = None
+
+
+def build_booklet(pages):
+    # Double sized page, with double-sided printing, fits 4 of the original.
+    sheet_count = int(math.ceil(len(pages) / 4.0))
+
+    booklet = [Sheet() for i in range(0, sheet_count)]
+
+    # Assign input pages to sheets
+
+    def containers():
+        # Yields parts of the booklet in the order they should be used.
+        for sheet in booklet:
+            yield sheet.back.right
+            yield sheet.front.left
+
+        for sheet in reversed(booklet):
+            yield sheet.front.right
+            yield sheet.back.left
+
+    for c, p in zip(containers(), pages):
+        c.page = p
+
+    return booklet
+
+
+def add_double_page(writer, page_size, print_page):
+    width, height = page_size
+    p = writer.insertBlankPage(width=width, height=height, index=writer.getNumPages())
+
+    # Merge the left page
+    l_page = print_page.left.page
+    if l_page is not None:
+        p.mergePage(l_page)
+
+    # Merge the right page with translation
+    r_page = print_page.right.page
+    if r_page is not None:
+        p.mergeTranslatedPage(r_page, width / 2, 0)
+
+
+def make_booklet(input_name, output_name, blanks=0):
+    reader = PdfFileReader(open(input_name, "rb"))
+    pages = [reader.getPage(p) for p in range(0, reader.getNumPages())]
+    for i in range(0, blanks):
+        pages.insert(0, None)
+
+    sheets = build_booklet(pages)
+
+    writer = PdfFileWriter()
+    p0 = reader.getPage(0)
+    input_width = p0.mediaBox.getWidth()
+    output_width = input_width * 2
+    input_height = p0.mediaBox.getHeight()
+    output_height = input_height
+
+    page_size = (output_width, output_height)
+    # We want to group fronts and backs together.
+    for sheet in sheets:
+        add_double_page(writer, page_size, sheet.back)
+
+    for sheet in sheets:
+        add_double_page(writer, page_size, sheet.front)
+
+    writer.write(open(output_name, "wb"))
+
+
+USAGE = """
+Converts a PDF document into a booklet former, by re-ordering pages and
+combining into double sized pages suitable for double-sided printing.
+
+Usage:
+
+booklet_maker.py  input.pdf output.pdf [blank pages to insert at start]
+"""
+
+if __name__ == '__main__':
+    if len(sys.argv) < 3:
+        print USAGE
+        sys.exit(1)
+
+    if len(sys.argv) == 4:
+        blanks = int(sys.argv[3])
+    else:
+        blanks = 0
+    make_booklet(sys.argv[1], sys.argv[2], blanks)