By cropping with -c and studying the results, define the areas of the input PDF's pages you want visible. Then, with--nup4, map those areas onto 4 input pages per 1 output page, arranged in such a way that double-sided print-out of those output pages can be cut, folded, and bound (helped by addition of stencils for small incisions to carry rubber bands or the like) into a small A6 book. Each unit of 8 pages from the input PDF is mapped by --nup4 onto two pages representing two sides of a (no-tumble-duplex-printed) A4 paper:
+-------=-------+ __________________
- (front) (back) | 4 | 1 = 2 | 3 | 4 /=|===|============
+ (front) (back) | 3 | 0 = 1 | 2 | 3 /=|===|============
+-------=-------+ ==> +-------=-------+ ===> _/|\_ v >=|===|============
-| 4 | 1 = 2 | 3 | / | \_ \=|===|============
-|-------=-------| +-------=-------+ 1-> | 2 | 3 | | \ / <- cut out!
-| 8 | 5 = 6 | 7 | ==> | 8 | 5 = 6 | 7 | | _/ \_ | | \ |
-+-------=-------+ +-------=-------+ |/ \| | \| (p. 5)
+| 3 | 0 = 1 | 2 | / | \_ \=|===|============
+|-------=-------| +-------=-------+ 0-> | 1 | 2 | | \ / <- cut out!
+| 7 | 4 = 5 | 6 | ==> | 7 | 4 = 5 | 6 | | _/ \_ | | \ |
++-------=-------+ +-------=-------+ |/ \| | \| (p. 4)
-To turn this paper into a small 8-pages book, first cut it into two A5 papers along its horizontal middle. Fold both A5's by their vertical middles, with pages 2-3 and 7-6 on the folds' insides. You now have two 4-page A6 "books" of pages 1-4 and pages 5-8. Fold both closed and (counter-intuitively) stack the second one on top of the first one (creating a temporary page order of 5,6,7,8,1,2,3,4). This reveals a small stencil on the top left of page 5 – cut it out, with all other pages folded and aligned under it, creating a small notch in the upper "inner" corner of all pages. Turn around the stack to find a mirror stencil on the bottom and repeat the cutting. Each page now has cuts on top and bottom of its inner margins into which a rubber band can be hooked, or through which a string may be looped and tied, to bind the page's inner margins into a kind of book spine. You may now swap the order of the 4-page books back into a proper final page order (of 1,2,3,4,5,6,7,8) and repeat the whole process for each further --nup4 output paper.
+To turn this paper into a small 8-pages book, first cut it into two A5 papers along its horizontal middle. Fold both A5's by their vertical middles, with pages 1-2 and 6-5 on the folds' insides. You now have two 4-page A6 "books" of pages 0-3 and pages 4-7. Fold both closed and (counter-intuitively) stack the second one on top of the first one (creating a temporary page order of 4,5,6,7,0,1,2,3). This reveals a small stencil on the top left of page 4 – cut it out, with all other pages folded and aligned under it, creating a small notch in the upper "inner" corner of all pages. Turn around the stack to find a mirror stencil on the bottom and repeat the cutting. Each page now has cuts on top and bottom of its inner margins into which a rubber band can be hooked, or through which a string may be looped and tied, to bind the page's inner margins into a kind of book spine. You may now swap the order of the 4-page books back into a proper final page order (of 0,1,2,3,4,5,6,7) and repeat the whole process for each further --nup4 output paper.
COMMAND EXAMPLES:
bookmaker.py -i INPUT.pdf --page_range 3-7 -o OUTPUT.pdf
Produce COMBINED.pdf from A.pdf's first 7 pages, B.pdf's pages except its first two, and all pages of C.pdf:
- bookmaker.py -i A.pdf -p start-7 -i B.pdf -p 3-end -i C.pdf -o COMBINED.pdf
+ bookmaker.py -i A.pdf -p start-6 -i B.pdf -p 2-end -i C.pdf -o COMBINED.pdf
Crop each page 5cm from the left, 10cm from the bottom, 2cm from the right, and 0cm from the top:
bookmaker.py -i INPUT.pdf -o OUTPUT.pdf --crops "5,10,2,0"
FURTHER NOTES:
-For arguments like -p, page numbers are assumed to start with 1 (not 0, which is treated as an invalid page number value).
+For arguments like -p, page numbers are assumed to start with 0 (i.e. first page at 0, second page at 1 …).
If -p defines a page range beyond the source document's last page, the remaining pages will be created blank.
except ValueError:
self._fail('carries value neither integer, nor '
f'"{_TOK_RANGE_START}", nor "{_TOK_RANGE_END}"')
- if int(token) < 1:
- self._fail('carries page number <1')
str_start, str_end = self._code.split('-')
if str_end not in {'', _TOK_RANGE_END}:
self.end = int(str_end)
if str_start not in {'', _TOK_RANGE_START}:
- self.start = int(str_start) - 1
+ self.start = int(str_start)
def _fail(
self,
if args.rotate_page:
arg_char = 'r'
for r in args.rotate_page:
- if r < 1:
- raise MsgFail('value must not be <1: {r}')
+ if r < 0:
+ raise MsgFail('value must not be <0: {r}')
except MsgFail as e:
raise ArgFail(arg_char, e.msg) from e
try:
f'cannot interpret {path} as PDF file') from e
page_range = (args_page_range[i] if len(args_page_range) > i
else PageRange(None))
- page_range.to_max(len(reader.pages))
+ page_range.to_max(len(reader.pages)-1)
for old_page_num in page_range.ranging():
- new_page_num += 1
page = (Page.new_blank() if old_page_num >= len(reader.pages)
else Page(reader.pages[old_page_num]))
self.pages += [page]
if do_analyze:
page.draw_borders((0.75, 0.0, 0.0))
- print(f'-i, -p: read in {path} page number {old_page_num+1} '
+ print(f'-i, -p: read in {path} page number {old_page_num} '
f'as new page {new_page_num}')
+ new_page_num += 1
self._writer = PdfWriter()
def __len__(
) -> None:
'For .pages numbered in args_rotate_page, rotate by 90°.'
for rotate_page in args_rotate_page or []:
- page = self.pages[rotate_page - 1]
+ page = self.pages[rotate_page]
page.translate(tx=-A4_WIDTH/2, ty=-A4_HEIGHT/2)
page.rotate(-90)
page.translate(tx=A4_WIDTH/2, ty=A4_HEIGHT/2)
for c_string in args_crops:
range_code, crops = split_crops_string(c_string)
page_range = PageRange(range_code)
- page_range.to_max(len(self))
+ page_range.to_max(len(self)-1)
prefix = '-c, -t' if args_symmetry else '-c'
suffix = ((' (but alternating left and right crop '
'between even and odd pages)') if args_symmetry
else '')
page_crop = PageCrop(*(float(crop)
for crop in crops.split(',')))
- print(f'{prefix}: to pages {page_range.start + 1}:'
+ print(f'{prefix}: to pages {page_range.start}:'
f'{page_range.end} applying crop: '
f'{page_crop.format_in_cm}{suffix}')
for idx in page_range.ranging():
if arg_analyze:
page.draw_borders((0.0, 0.0, 0.75))
page.add_to_writer(self._writer)
- print(f'built page number {i+1} (of {len(self)})')
+ print(f'built page number {i} (of {len(self)})')
def build_nup4_output(
self,
for page in self.pages:
page.nup4_transforms(nup4_geometry, nup4_i)
new_page.merge_page(page)
- page_count += 1
print(f'merged page number {page_count} (of {len(self)})')
+ page_count += 1
nup4_i += 1
if nup4_i > 3:
new_page.ornate_nup4(is_front_page, nup4_geometry, arg_analyze)