#!/usr/bin/env python3 import os import argparse from PyPDF2 import PageObject, PdfReader, PdfWriter, PaperSize, Transformation def main(): PROGRAM_NAME="bookletify" DESCRIPTION = """Rearranges the pages of a pdf in order to print it as is, so that you can take it, cut it in half and close it like you would with a book. The result will be the original pdf in the correct order, with the size of half a page. Especially useful to print pdfs to A5 size on A4 paper""" parser = argparse.ArgumentParser( prog=PROGRAM_NAME, description=DESCRIPTION ) parser.add_argument('filename') parser.add_argument('-q', '--quiet', action='store_true', help='suppress stdout') parser.add_argument('-s', '--size', action='store', choices=['A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'C4'], default='A4', metavar='SIZE', help="""set final paper size. Possible values: 'A0', ..., 'A8' or 'C4'. Default value is 'A4'""") parser.add_argument('-b', '--binding-margin', default=10, type=float, metavar='MARGIN', help="""internal margin for the binding, expressed in millimeters. Default value is 10""") args = parser.parse_args() info = lambda text='', end='\n': print(text, end=end) if args.quiet: info = lambda text='', end='\n': None prog = lambda curr, max: info(f"\r{curr} / {max}", '\n' if curr == max else '') input_name = args.filename if not os.path.isfile(input_name): print(f'file {input_name} does not exist') exit(1) output_name = f'{input_name}-rearranged' if (input_name.endswith('.pdf')): output_name = f'{input_name[0:-4]}-rearranged.pdf' fullwidth = getattr(PaperSize, args.size).width fullheight = getattr(PaperSize, args.size).height smallwidth = fullheight / 2 smallheight = fullwidth # Convert mm to pixels at 72 dpi bindingwidth = args.binding_margin * 72 / float(25.4) smallblank = PageObject.create_blank_page(width=smallwidth - bindingwidth, height=smallheight) # Read the input reader = PdfReader(input_name) n = len(reader.pages) pages = [] info("Reading...") for i in range(n): prog(i, n) pages.append(reader.pages[i]) prog(n,n) while(len(pages) % 4 != 0): pages.append(smallblank) output = PdfWriter() info("\nRearranging...") def merge_srt_page(base, over, angle, tx, ty): sx = float(smallwidth - bindingwidth) / float(over.mediabox.width) sy = float(smallheight) / float(over.mediabox.height) t = Transformation().scale(sx, sy).rotate(angle). translate(tx, ty) over.add_transformation(t) base.merge_page(over) m = len(pages) for i in range(int(m / 2)): prog(i, int(m / 2)) new_page = PageObject.create_blank_page(width=fullwidth, height=fullheight) if i % 2 == 0: merge_srt_page(new_page, pages[m - 1 - i], -90, 0, fullheight) merge_srt_page(new_page, pages[i], - 90, 0, smallwidth - bindingwidth) pass else: merge_srt_page(new_page, pages[m - 1 - i], 90, smallheight, smallwidth + bindingwidth) merge_srt_page(new_page, pages[i], 90, smallheight, 0) output.add_page(new_page) prog(int(m/2), int(m/2)) info("\nSaving...") output.write(output_name) info("\nDone!") if __name__ == "__main__": main()