diff --git a/foliator.py b/foliator.py index eca5949..9c09a75 100755 --- a/foliator.py +++ b/foliator.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 import argparse -from pypdf import PaperSize, PdfReader, PdfWriter, Transformation -from pypdf.annotations import Line +import numpy as np +from pypdf import PaperSize, PdfReader, PdfWriter, Transformation, PageObject from pypdf.generic import ArrayObject, FloatObject, NameObject +from pypdf.annotations import Line import math @@ -38,7 +39,7 @@ def append_folio_A6(input_pdf, offset, size, append_to): # num_sheets = max_folio_size * a + (max_folio_size - k) * b # where k is minimal. We let n = max_folio_size and L = num_sheets. # Note that when L > n^2, then k = 1 must succeed. -def find_partition(num_sheets, max_folio_size): +def find_partition_mink(num_sheets, max_folio_size): max_a = num_sheets // max_folio_size for k in range(1, max_folio_size): # We want to solve a*k = L (mod n-k). This happens iff @@ -57,7 +58,12 @@ def find_partition(num_sheets, max_folio_size): # substracting almost mprime. candidate = max_a - tosub if (candidate >= 0): - return (candidate, k) + b = (num_sheets - max_folio_size * candidate)//(max_folio_size - k) + return [max_folio_size] * candidate + [max_folio_size - k] * b + +def find_partition_greedy(num_sheets, max_folio_size): + q = num_sheets//max_folio_size + return [max_folio_size] * q + [num_sheets - q*max_folio_size] # Interprets input_pdf as a list of A6 pages, and appends to append_to with # A5 pages using the following rules: @@ -65,23 +71,29 @@ def find_partition(num_sheets, max_folio_size): # 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 +def foliate_A6(input_pdf, strat_func, max_folio_size, append_to=PdfWriter()): doc_length = len(input_pdf.pages) writer = append_to - if max_folio_size < 0: - max_folio_size = doc_length + + num_sheets = math.ceil(doc_length/4.0) + print("Using", num_sheets, "two-sided A5 sheets") + + L = [num_sheets] + if max_folio_size > 0: + L = strat_func(num_sheets, max_folio_size) + + if(np.sum(L) != num_sheets): + print("[ERROR] strategy gave", np.sum(L), " A5 sheets") + exit(1) 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) + current_page = 0 + for l in L: + # l is a number of _sheets_, each containing 4 pages + folio_page_size = min(doc_length - current_page, 4*l) 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 @@ -106,7 +118,7 @@ def blit_to_A4(input_pdf, append_to=PdfWriter()): writer.add_annotation(front_page, midline) front = input_pdf.pages[k] - back = input_pdf.pages[k+1] if (k+1