220 lines
6.7 KiB
Python
Executable File
220 lines
6.7 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='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:
|
|
#TODO: if number of pages%16 != 0 : fill up with blank pages
|
|
# in loop:
|
|
# if i > len(pages): insert blank? or terminate orderly
|
|
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)
|