Functional imposition

This commit is contained in:
Maximilian Friedersdorff 2023-06-12 23:10:58 +01:00
parent a7fc1e047c
commit fd0b82aa6c

81
pympose.py Normal file → Executable file
View file

@ -1,18 +1,23 @@
import pypdf #!/usr/bin/env python3
import argparse
from pypdf import PdfReader, PdfWriter, Transformation, PageObject, PaperSize
def main(source, out, section_length): def double_folio(source, out, section_length, outsize="A4", extra_scale=1):
assert section_length % 4 == 0 assert section_length % 4 == 0
in_reader = pypdf.PdfReader(source) in_reader = PdfReader(source)
out_writer = pypdf.PdfWriter() out_writer = PdfWriter()
to_add = section_length - len(in_reader.pages) % section_length to_add = section_length - len(in_reader.pages) % section_length
add_before = to_add // 2 add_before = to_add // 2
add_after = to_add - add_before add_after = to_add - add_before
pages = [pypdf.PageObject.create_blank_page(in_reader) for _ in range(add_before)] out_size = getattr(PaperSize, outsize)
pages = [PageObject.create_blank_page(width=out_size.width, height=out_size.height) for _ in range(add_before)]
pages += in_reader.pages pages += in_reader.pages
pages += [pypdf.PageObject.create_blank_page(in_reader) for _ in range(add_after)] pages += [PageObject.create_blank_page(width=out_size.width, height=out_size.height) for _ in range(add_after)]
for sig_start in range(0, len(in_reader.pages), section_length): for sig_start in range(0, len(in_reader.pages), section_length):
for side in range(section_length // 4): for side in range(section_length // 4):
@ -21,24 +26,66 @@ def main(source, out, section_length):
sig_start + side, sig_start + side,
] ]
bottom = [ bottom = [
sig_start + section_length // 2 + side, sig_start + (section_length // 2) + side,
sig_start + section_length // 2 + side - 1, sig_start + (section_length // 2) - side - 1
] ]
if side % 2 != 0: if side % 2 != 0:
top = list(reversed(top)) top = list(reversed(top))
bottom = list(reversed(bottom)) bottom = list(reversed(bottom))
imposed_page = PageObject.create_blank_page(width=out_size.width, height=out_size.height)
print(top) scale = Transformation().scale(0.5 * extra_scale, 0.5 * extra_scale)
print(bottom) up = Transformation().translate(ty=extra_scale * out_size.height / 2)
right = Transformation().translate(tx=extra_scale * out_size.width / 2)
rot = Transformation().rotate(180)
continue tl = pages[top[0]]
for si, pi in enumerate(range(sig_start, sig_start + section_length)): tl.add_transformation(scale)
page_box = pages[pi] tl.add_transformation(up)
trans = pypdf.Transformation() imposed_page.merge_page(tl)
if si >= section_length // 4 and si < 3 * section_length // 4: tr = pages[top[1]]
trans = trans.rotate(180) tr.add_transformation(scale)
tr.add_transformation(up)
tr.add_transformation(right)
imposed_page.merge_page(tr)
trans = trans.scale(0.5, 0.5) bl = pages[bottom[0]]
bl.add_transformation(scale)
bl.add_transformation(rot)
bl.add_transformation(up)
bl.add_transformation(right)
imposed_page.merge_page(bl)
br = pages[bottom[1]]
br.add_transformation(scale)
br.add_transformation(rot)
br.add_transformation(right)
br.add_transformation(right)
br.add_transformation(up)
imposed_page.merge_page(br)
out_writer.add_page(imposed_page)
with open(out, "wb") as fp:
out_writer.write(fp)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="pympose",
description="Impose pages for printing"
)
parser.add_argument('action', type=str, help="What to do")
parser.add_argument('infile', type=str, help="Input file")
parser.add_argument('outfile', type=str, help="Output file")
parser.add_argument('section_size', type=int, help="Size of sections")
parser.add_argument('--outsize', type=str, help="Output Size", default="A4")
parser.add_argument('--extra-scale', type=float, help="Extra Scale factor", default=1)
args = parser.parse_args()
if args.action == "double_folio":
double_folio(args.infile, args.outfile, args.section_size, args.outsize, args.extra_scale)