md2tex/pdf2book.py

202 lines
6.2 KiB
Python
Executable File

#!/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='AQOABA')
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 positive 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
# s| 1 | 2 | 3 | 4 |
#-----------------------
#p | | | |
# 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 |
# -------------------------
#
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 :
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)