You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dm-scripts/bookletify.py

113 lines
3.7 KiB
Python

#!/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()