Compare commits
2 commits
03dbe317c5
...
6566830258
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6566830258 | ||
|
|
e3e84692e3 |
2 changed files with 29 additions and 16 deletions
44
foliator.py
44
foliator.py
|
|
@ -1,9 +1,10 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from pypdf import PaperSize, PdfReader, PdfWriter, Transformation
|
import numpy as np
|
||||||
from pypdf.annotations import Line
|
from pypdf import PaperSize, PdfReader, PdfWriter, Transformation, PageObject
|
||||||
from pypdf.generic import ArrayObject, FloatObject, NameObject
|
from pypdf.generic import ArrayObject, FloatObject, NameObject
|
||||||
|
from pypdf.annotations import Line
|
||||||
import math
|
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
|
# 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(num_sheets, max_folio_size):
|
def find_partition_mink(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
|
||||||
|
|
@ -57,7 +58,12 @@ def find_partition(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):
|
||||||
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
|
# 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:
|
||||||
|
|
@ -65,23 +71,29 @@ def find_partition(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, max_folio_size=-1, append_to=PdfWriter()):
|
def foliate_A6(input_pdf, strat_func, max_folio_size, 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:
|
|
||||||
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
|
folio_page_size = 0
|
||||||
while(current_page < doc_length):
|
current_page = 0
|
||||||
# max_folio_size is a number of _sheets_, each containing 4 pages
|
for l in L:
|
||||||
folio_page_size = min(doc_length - current_page, 4*max_folio_size)
|
# 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)
|
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
|
||||||
|
|
@ -106,7 +118,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 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
|
front.mediabox = front_page.mediabox
|
||||||
back.mediabox = back_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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
input_pdf = PdfReader(args.infile)
|
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):
|
if (args.a5):
|
||||||
a5.write(args.outfile)
|
a5.write(args.outfile)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ pkgs.mkShell {
|
||||||
packages = [
|
packages = [
|
||||||
(pkgs.python3.withPackages (pythonPackages: with python3Packages; [
|
(pkgs.python3.withPackages (pythonPackages: with python3Packages; [
|
||||||
pypdf
|
pypdf
|
||||||
|
numpy
|
||||||
]))
|
]))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue