Compare commits

..

No commits in common. "6566830258ed6721c7f5427b57f0efe3772290c0" and "03dbe317c5d6ec1464b900c325907d0820985696" have entirely different histories.

2 changed files with 16 additions and 29 deletions

View file

@ -1,10 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import numpy as np from pypdf import PaperSize, PdfReader, PdfWriter, Transformation
from pypdf import PaperSize, PdfReader, PdfWriter, Transformation, PageObject
from pypdf.generic import ArrayObject, FloatObject, NameObject
from pypdf.annotations import Line from pypdf.annotations import Line
from pypdf.generic import ArrayObject, FloatObject, NameObject
import math import math
@ -39,7 +38,7 @@ def append_folio_A6(input_pdf, offset, size, append_to):
# num_sheets = max_folio_size * a + (max_folio_size - k) * b # 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. # 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. # Note that when L > n^2, then k = 1 must succeed.
def find_partition_mink(num_sheets, max_folio_size): def find_partition(num_sheets, max_folio_size):
max_a = num_sheets // max_folio_size max_a = num_sheets // max_folio_size
for k in range(1, max_folio_size): for k in range(1, max_folio_size):
# We want to solve a*k = L (mod n-k). This happens iff # We want to solve a*k = L (mod n-k). This happens iff
@ -58,12 +57,7 @@ def find_partition_mink(num_sheets, max_folio_size):
# substracting almost mprime. # substracting almost mprime.
candidate = max_a - tosub candidate = max_a - tosub
if (candidate >= 0): if (candidate >= 0):
b = (num_sheets - max_folio_size * candidate)//(max_folio_size - k) return (candidate, 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 # Interprets input_pdf as a list of A6 pages, and appends to append_to with
# A5 pages using the following rules: # A5 pages using the following rules:
@ -71,29 +65,23 @@ def find_partition_greedy(num_sheets, max_folio_size):
# with "mirror around **short** edge" # with "mirror around **short** edge"
# b. when grouped as consecutive sequences of max_folio_size or less, the printed # 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 # sheets can be folded in the middle and assembled as a folio
def foliate_A6(input_pdf, strat_func, max_folio_size, append_to=PdfWriter()): def foliate_A6(input_pdf, max_folio_size=-1, append_to=PdfWriter()):
current_page = 0
doc_length = len(input_pdf.pages) doc_length = len(input_pdf.pages)
writer = append_to writer = append_to
if max_folio_size < 0:
num_sheets = math.ceil(doc_length/4.0) max_folio_size = doc_length
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 folio_page_size = 0
current_page = 0 while(current_page < doc_length):
for l in L: # max_folio_size is a number of _sheets_, each containing 4 pages
# l is a number of _sheets_, each containing 4 pages folio_page_size = min(doc_length - current_page, 4*max_folio_size)
folio_page_size = min(doc_length - current_page, 4*l)
append_folio_A6(input_pdf, current_page, folio_page_size, append_to) append_folio_A6(input_pdf, current_page, folio_page_size, append_to)
current_page += folio_page_size current_page += folio_page_size
print("Dangling folio has",folio_page_size,"pages",
"(",int(math.ceil(folio_page_size/4.0)),"sheets).")
return writer return writer
# Take an A5 printing plan, with odd/even pages being understood # Take an A5 printing plan, with odd/even pages being understood
@ -118,7 +106,7 @@ def blit_to_A4(input_pdf, append_to=PdfWriter()):
writer.add_annotation(front_page, midline) writer.add_annotation(front_page, midline)
front = input_pdf.pages[k] front = input_pdf.pages[k]
back = input_pdf.pages[k+1] if (k+1<L) else PageObject.create_blank_page(None, PaperSize.A5.width, PaperSize.A5.height) back = input_pdf.pages[k+1] if (k+1<L) else create_blank_page(None, PaperSize.A5.width, PaperSize.A5.height)
front.mediabox = front_page.mediabox front.mediabox = front_page.mediabox
back.mediabox = back_page.mediabox back.mediabox = back_page.mediabox
@ -141,7 +129,7 @@ parser.add_argument("-fs", help="maximum folio size, in sheets",
args = parser.parse_args() args = parser.parse_args()
input_pdf = PdfReader(args.infile) input_pdf = PdfReader(args.infile)
a5 = foliate_A6(input_pdf, find_partition_greedy, args.fs) a5 = foliate_A6(input_pdf, args.fs)
if (args.a5): if (args.a5):
a5.write(args.outfile) a5.write(args.outfile)
else: else:

View file

@ -6,7 +6,6 @@ pkgs.mkShell {
packages = [ packages = [
(pkgs.python3.withPackages (pythonPackages: with python3Packages; [ (pkgs.python3.withPackages (pythonPackages: with python3Packages; [
pypdf pypdf
numpy
])) ]))
]; ];
} }