From 9f784976762a1a1d240ff67cd6426934ffd5d189 Mon Sep 17 00:00:00 2001 From: Francesco Baldino Date: Wed, 24 May 2023 11:31:56 +0200 Subject: [PATCH] bookletify now supports trimming borders --- bookletify.py | 78 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/bookletify.py b/bookletify.py index 9072585..6953485 100755 --- a/bookletify.py +++ b/bookletify.py @@ -12,11 +12,7 @@ def main(): 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 = argparse.ArgumentParser(prog=PROGRAM_NAME, description=DESCRIPTION) parser.add_argument('filename') parser.add_argument('-q', '--quiet', action='store_true', @@ -28,13 +24,33 @@ def main(): 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""") + millimeters relative to the final paper size (ie: + half of the height of the paper size specified by + --size). Set to 0 to disable. This setting is + independent to the trim setting, ie: increasing or + decreasing this margin does not trim any content on + the final pdf, the content gets scaled down (or up) + to fit to the final width minus the binding margin. + Default value is 10""") + parser.add_argument('-t', '--trim', + default=[0,0,0,0], + type=float, + nargs=4, + metavar='T', + help="""margins to trim, expressed in millimeters + relative to the original page size, as: top right + bottom left. This setting is independent to the + binding margin, ie: first the trim is applied, then + the trimmed content gets scaled up (or down) to the + full height and width, minus the binding margin. + Changing the trim does not increase or decrease the + final binding margin. A negative trim adds an empty + border on that side. Default value is 0 0 0 0""") args = parser.parse_args() @@ -59,8 +75,13 @@ def main(): smallwidth = fullheight / 2 smallheight = fullwidth # Convert mm to pixels at 72 dpi - bindingwidth = args.binding_margin * 72 / float(25.4) + bindingwidth = args.binding_margin * 72.0 / 25.4 smallblank = PageObject.create_blank_page(width=smallwidth - bindingwidth, height=smallheight) + + tt = args.trim[0] * 72.0 / 25.4 + tr = args.trim[1] * 72.0 / 25.4 + tb = args.trim[2] * 72.0 / 25.4 + tl = args.trim[3] * 72.0 / 25.4 # Read the input reader = PdfReader(input_name) @@ -80,24 +101,43 @@ def main(): 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) + def get_scaling(page): + sx = float(smallwidth - bindingwidth) / (float(page.mediabox.width) - tr - tl) + sy = float(smallheight) / (float(page.mediabox.height) - tt - tb) + return (sx, sy) 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 + (sx, sy) = get_scaling(pages[m-1-i]) + t = Transformation().scale(sx, sy).rotate(-90).translate(-tb * sy, fullheight + tl * sx) + pages[m-1-i].add_transformation(t) + pages[m-1-i].cropbox.upper_right = (smallheight, fullheight) + pages[m-1-i].cropbox.lower_left = (0, smallwidth + bindingwidth) + new_page.merge_page(pages[m-1-i]) + + (sx, sy) = get_scaling(pages[i]) + t = Transformation().scale(sx, sy).rotate(-90).translate(-tb * sy, smallwidth - bindingwidth + tl * sx) + pages[i].add_transformation(t) + pages[i].cropbox.upper_right = (smallheight, smallwidth - bindingwidth) + pages[i].cropbox.lower_left = (0, 0) + new_page.merge_page(pages[i]) else: - merge_srt_page(new_page, pages[m - 1 - i], 90, smallheight, smallwidth + bindingwidth) - merge_srt_page(new_page, pages[i], 90, smallheight, 0) + (sx, sy) = get_scaling(pages[m-1-i]) + t = Transformation().scale(sx, sy).rotate(90).translate(smallheight + tb * sy, smallwidth + bindingwidth - tl * sx) + pages[m-1-i].add_transformation(t) + pages[m-1-i].cropbox.upper_right = (smallheight, fullheight) + pages[m-1-i].cropbox.lower_left = (0, smallwidth + bindingwidth) + new_page.merge_page(pages[m-1-i]) + + (sx, sy) = get_scaling(pages[i]) + t = Transformation().scale(sx, sy).rotate(90).translate(smallheight + tb * sy, 0 - tl * sx) + pages[i].add_transformation(t) + pages[i].cropbox.upper_right = (smallheight, smallwidth - bindingwidth) + pages[i].cropbox.lower_left = (0, 0) + new_page.merge_page(pages[i]) output.add_page(new_page) prog(int(m/2), int(m/2))