Compare commits

...

2 commits

Author SHA1 Message Date
Selene Corbineau
6566830258 Begin implementing strategy selection
Right now this is still unexposed to the users.
Pretty-printing the foliating plan is somewhat of
a problem. Hopefully they are always quite small.
2026-06-21 11:21:08 +02:00
Selene Corbineau
e3e84692e3 Fix import of create_blank_page 2026-06-21 11:20:44 +02:00
2 changed files with 29 additions and 16 deletions

View file

@ -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<L) else create_blank_page(None, PaperSize.A5.width, PaperSize.A5.height)
back = input_pdf.pages[k+1] if (k+1<L) else PageObject.create_blank_page(None, PaperSize.A5.width, PaperSize.A5.height)
front.mediabox = front_page.mediabox
back.mediabox = back_page.mediabox
@ -129,7 +141,7 @@ parser.add_argument("-fs", help="maximum folio size, in sheets",
args = parser.parse_args()
input_pdf = PdfReader(args.infile)
a5 = foliate_A6(input_pdf, args.fs)
a5 = foliate_A6(input_pdf, find_partition_greedy, args.fs)
if (args.a5):
a5.write(args.outfile)
else:

View file

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