Add support for max_folio_size
This commit is contained in:
parent
0731eef783
commit
7fab01aeca
1 changed files with 39 additions and 16 deletions
55
foliator.py
55
foliator.py
|
|
@ -6,21 +6,16 @@ from pypdf.annotations import Line
|
||||||
from pypdf.generic import ArrayObject, FloatObject, NameObject
|
from pypdf.generic import ArrayObject, FloatObject, NameObject
|
||||||
import math
|
import math
|
||||||
|
|
||||||
# Interprets input_pdf as a list of A6 pages, and appends to append_to with
|
|
||||||
# A5 pages using the following rules:
|
|
||||||
# a. Odd/even page pairs correspond to front/back pages of a single sheet, printed
|
|
||||||
# with "mirror around **short** edge"
|
|
||||||
# b. when grouped as consecutive sequences of max_folio_size or less, the printed
|
|
||||||
# sheets can be folded in the middle and assembled as a folio
|
|
||||||
# FIXME: currently max_folio_size is ignored, and the output is one large folio.
|
|
||||||
def foliate_A6(input_pdf, max_folio_size=-1, append_to=PdfWriter()):
|
|
||||||
num_A5 = math.ceil(len(input_pdf.pages)/4.0) * 2
|
|
||||||
writer = append_to
|
|
||||||
|
|
||||||
|
def append_folio_A6(input_pdf, offset, size, append_to):
|
||||||
|
# Handles edge case where folio has 1 page
|
||||||
|
num_A5 = min(math.ceil(size / 4.0) * 2, size)
|
||||||
|
writer = append_to
|
||||||
|
w_offset = len(writer.pages)
|
||||||
for i in range(num_A5):
|
for i in range(num_A5):
|
||||||
dpage = writer.add_blank_page(width=PaperSize.A5.height,
|
dpage = writer.add_blank_page(width=PaperSize.A5.height,
|
||||||
height=PaperSize.A5.width)
|
height=PaperSize.A5.width)
|
||||||
ipage = input_pdf.pages[i]
|
ipage = input_pdf.pages[i+offset]
|
||||||
ipage.mediabox = dpage.mediabox
|
ipage.mediabox = dpage.mediabox
|
||||||
|
|
||||||
if i % 2 == 0: # Even pages are filled right to left
|
if i % 2 == 0: # Even pages are filled right to left
|
||||||
|
|
@ -28,10 +23,10 @@ def foliate_A6(input_pdf, max_folio_size=-1, append_to=PdfWriter()):
|
||||||
0))
|
0))
|
||||||
dpage.merge_page(ipage)
|
dpage.merge_page(ipage)
|
||||||
|
|
||||||
# Now for the fun part: work backwards to fill the remaining pages
|
# Now for the fun part: work backwards to fill the remaining pages
|
||||||
for j in range(len(input_pdf.pages) - num_A5):
|
for j in range(size - num_A5):
|
||||||
dpage = writer.pages[num_A5 - 1 - j]
|
dpage = writer.pages[w_offset + num_A5 - 1 - j]
|
||||||
ipage = input_pdf.pages[num_A5+j]
|
ipage = input_pdf.pages[num_A5+j+offset]
|
||||||
ipage.mediabox = dpage.mediabox
|
ipage.mediabox = dpage.mediabox
|
||||||
if (num_A5 - 1 - j) % 2 == 1:
|
if (num_A5 - 1 - j) % 2 == 1:
|
||||||
ipage.add_transformation(Transformation().translate(PaperSize.A6.width,
|
ipage.add_transformation(Transformation().translate(PaperSize.A6.width,
|
||||||
|
|
@ -39,6 +34,32 @@ def foliate_A6(input_pdf, max_folio_size=-1, append_to=PdfWriter()):
|
||||||
dpage.merge_page(ipage)
|
dpage.merge_page(ipage)
|
||||||
return writer
|
return writer
|
||||||
|
|
||||||
|
|
||||||
|
# Interprets input_pdf as a list of A6 pages, and appends to append_to with
|
||||||
|
# A5 pages using the following rules:
|
||||||
|
# a. Odd/even page pairs correspond to front/back pages of a single sheet, printed
|
||||||
|
# with "mirror around **short** edge"
|
||||||
|
# b. when grouped as consecutive sequences of max_folio_size or less, the printed
|
||||||
|
# sheets can be folded in the middle and assembled as a folio
|
||||||
|
def foliate_A6(input_pdf, max_folio_size=-1, append_to=PdfWriter()):
|
||||||
|
current_page = 0
|
||||||
|
doc_length = len(input_pdf.pages)
|
||||||
|
writer = append_to
|
||||||
|
if max_folio_size < 0:
|
||||||
|
max_folio_size = doc_length
|
||||||
|
|
||||||
|
folio_page_size = 0
|
||||||
|
while(current_page < doc_length):
|
||||||
|
# max_folio_size is a number of _sheets_, each containing 4 pages
|
||||||
|
folio_page_size = min(doc_length - current_page, 4*max_folio_size)
|
||||||
|
append_folio_A6(input_pdf, current_page, folio_page_size, append_to)
|
||||||
|
current_page += folio_page_size
|
||||||
|
|
||||||
|
print("Dangling folio has",folio_page_size,"pages",
|
||||||
|
"(",int(math.ceil(folio_page_size/4.0)),"sheets).")
|
||||||
|
|
||||||
|
return writer
|
||||||
|
|
||||||
# Take an A5 printing plan, with odd/even pages being understood
|
# Take an A5 printing plan, with odd/even pages being understood
|
||||||
# as front/back pairs of sheets, short edge mirroring. Produces an A4 printing plan
|
# as front/back pairs of sheets, short edge mirroring. Produces an A4 printing plan
|
||||||
# containing two A5 panels per sheet, long edge mirroring.
|
# containing two A5 panels per sheet, long edge mirroring.
|
||||||
|
|
@ -79,10 +100,12 @@ parser.add_argument("infile", help="input document, A6 pages")
|
||||||
parser.add_argument("outfile", help="output document")
|
parser.add_argument("outfile", help="output document")
|
||||||
parser.add_argument("-a5", help="output as a5, reverse on short edge",
|
parser.add_argument("-a5", help="output as a5, reverse on short edge",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
|
parser.add_argument("-fs", help="maximum folio size, in sheets",
|
||||||
|
action="store", default=-1, type=int)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
input_pdf = PdfReader(args.infile)
|
input_pdf = PdfReader(args.infile)
|
||||||
a5 = foliate_A6(input_pdf)
|
a5 = foliate_A6(input_pdf, args.fs)
|
||||||
if (args.a5):
|
if (args.a5):
|
||||||
a5.write(args.outfile)
|
a5.write(args.outfile)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue