From f95a2449b39f2bdb240076d3b42b795b0a4ff6f1 Mon Sep 17 00:00:00 2001 From: "uni@bor.mac" Date: Mon, 9 Jun 2025 16:00:55 +0200 Subject: [PATCH] pdfbook.py: add --- pdf2book.py | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100755 pdf2book.py diff --git a/pdf2book.py b/pdf2book.py new file mode 100755 index 0000000..9878f56 --- /dev/null +++ b/pdf2book.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 + +from pypdf import PaperSize, PdfReader, PdfWriter, Transformation +from pypdf.generic import RectangleObject + + +import argparse +parser = argparse.ArgumentParser( + prog='pdf2book', + description='pdf2book rearranges pages for signature printing ', + epilog='onipa') + +parser.add_argument('pdf_file') # positional argument +#parser.add_argument('pages', type=int) # positional argument +#parser.add_argument('-s', '--signature') # option that takes a value +parser.add_argument('-v', '--verbose', action='store_true') # on/off flag +parser.add_argument('-z', '--zine', action='store_true', help='Input pdf needs to be 16 pages') +parser.add_argument('-s', '--signature', + dest='signature', + type=int, + action='store', + default=0, + help='') +args = parser.parse_args() + +signature_size=args.signature +if signature_size < 0 : +# print("signature size must be greater than 0!") + print("signature size must be non-negative integer!") + exit(1) + +reader = PdfReader(args.pdf_file) +number_of_pages = len(reader.pages) +#page = reader.pages[0] +#text = page.extract_text() + +pages=number_of_pages +#print(pages) + +lst=[] + +def get_reorder(number_of_pages: int, signature_size: int): + panu=number_of_pages + sisi=signature_size + + #p\s| 1 | 2 | 3 | 4 | + #----------------------- + # 1 | 4 | 8 | 12 | 16 | + # 2 | 4 | 8 | 12 | 16 | + # 3 | 4 | 8 | 12 | 16 | + # 4 | 4 | 8 | 12 | 16 | + # 5 | 8 | 8 | 12 | 16 | + # 6 | 8 | 8 | 12 | 16 | + # 7 | 8 | 8 | 12 | 16 | + # 8 | 8 | 8 | 12 | 16 | + # 9 | 12 | 16 | 12 | 16 | + #10 | 12 | 16 | 12 | 16 | + #11 | 12 | 16 | 12 | 16 | + #12 | 12 | 16 | 12 | 16 | + #13 | 16 | 16 | 24 | 16 | + + p=number_of_pages + s=signature_size + if signature_size == 0: + signature_size=1 + pages_filled= ( int((number_of_pages-1)/(4*signature_size)) +1 )*4*signature_size + signature_size=int(pages_filled/4) + pages_filled= ( int((number_of_pages-1)/(4*signature_size)) +1 )*4*signature_size + + signature_count=int( pages_filled/signature_size/4 ) + #print(signature_count) + for i in range(signature_count): + # print("i=",i) + down=(i+1)*4*signature_size + # print("down=",down) + up= (i*4*signature_size)+1 + # print("up",up) + for count in range(signature_size): + # print("count=",count) + lst.append(down); down -= 1 + lst.append(up); up += 1 + lst.append(up); up += 1 + lst.append(down); down -= 1 + # print(lst) + #print(lst) + #print(len(lst)) + return lst + +def print_signatures(lst: list,signature_size: int): + if signature_size==0: signature_size=1 + for i in range( len( lst ) ): + if ( (i+1) % (4*signature_size) == 0 ): + print(lst[i]) + elif ( (i+1) % (4) == 0 ): + print(lst[i], end=' ') + else: + print(lst[i],end='.') + +# REARRANGING OF PAGES +def rearrange_pages(reader, lst): + writer = PdfWriter() + for page in lst: +# print(page) + if page > len(reader.pages): + writer.add_blank_page(width=reader.pages[0].mediabox.width,height=reader.pages[0].mediabox.height) + else: + writer.add_page(reader.pages[page-1]) + return writer + +def make_zine(reader, lst): +# _____________________ +# | 1r | 8r | 7r | 6r | +# --------------------- +# | 2 | 3 | 4 | 5 | +# --------------------- +# +# _________________________ +# | 9r | 16r | 15r | 14r | +# ------------------------- +# | 10 | 11 | 12 | 13 | +# ------------------------- +# +# todo +# - [ ] alternative folding 1 for zine +# _____________________ +# | 3r | 2r | 1r | 8r | +# --------------------- +# | 4 | 5 | 6 | 7 | +# --------------------- +# _________________________ +# | 11r | 10r | 9r | 16r | +# ------------------------- +# | 12 | 13 | 14 | 15 | +# ------------------------- +# + page_order=[ + 2, 3, 4, 5, + 1, 8, 7, 6, + 10,11,12,13, + 9,16,15,14 + ] + print("zine") + # Create a destination file, and add a blank page to it + writer = PdfWriter() + # Copy source page to destination page, several times + for i in range(2): + destpage = writer.add_blank_page( + width=PaperSize.A4.height, + height=PaperSize.A4.width + ) + for y in range(2): + for x in range(4): + pageposition=8*i+4*y+x + sourcepage=reader.pages[page_order[pageposition]-1] + mb=sourcepage.mediabox + sourcepage.cropbox = RectangleObject(( + -2*mb.right, + -4*mb.top, + 2*mb.right, + 2*mb.top + )) + if y == 1: + transformation = Transformation().rotate(180) + r="r" + sourcepage.add_transformation(transformation) + tx_val=(1*x+1) * sourcepage.mediabox.width + ty_val=2*y * sourcepage.mediabox.height + else: + tx_val=x * sourcepage.mediabox.width + ty_val=2*y * sourcepage.mediabox.height + r=" " + if x==3: + print(page_order[pageposition],r) + else: + print(page_order[pageposition],r,end=' ') + destpage.merge_transformed_page( + sourcepage, + Transformation( + ).translate( + tx=tx_val, + ty=ty_val, + ).scale( + sx=0.5, + sy=0.5 + ) + , expand=True + ) +# destpage. + destpage.mediabox = RectangleObject(( + 0, + 0, + 2*mb.right, + 1*mb.top + )) + #writer.add_page(destpage) + # destpage = writer.add_blank_page( + # width=PaperSize.A4.height, + # height=PaperSize.A4.width + # ) + return writer + +lst=get_reorder(number_of_pages, signature_size) +if args.zine : + if number_of_pages != 16: + print("Error... when using '--zine' the input pdf must have 16 pages!") + exit(1) + writer=make_zine(reader, lst) +# signature_size=zine + outfile=args.pdf_file.split(".pdf")[0]+"_zine.pdf" +else: + print_signatures(lst,signature_size) + writer=rearrange_pages(reader,lst) + outfile=args.pdf_file.split(".pdf")[0]+"_book_s"+str(signature_size)+".pdf" +# SAVE FILE TO DISK +with open(outfile, "wb") as fp: + writer.write(fp)