X-Git-Url: https://plomlompom.com/repos/foo.html?a=blobdiff_plain;f=bookmaker.py;h=1c7240a8fd8c5d29d6357d57e54a2affee2e65b4;hb=71280964e196003c0198eb3c418f28ec32f5be78;hp=25e85994f125b785fbe3537cf84fce0a75cdd599;hpb=2180d2073c33449159b2bf4ff0289ab809ae2f95;p=misc diff --git a/bookmaker.py b/bookmaker.py index 25e8599..1c7240a 100755 --- a/bookmaker.py +++ b/bookmaker.py @@ -73,15 +73,21 @@ try: except ImportError: handled_error_exit("Can't run at all without pypdf installed.") -# some constants +# some general paper geometry constants POINTS_PER_CM = 10 * 72 / 25.4 A4_WIDTH = 21 * POINTS_PER_CM A4_HEIGHT = 29.7 * POINTS_PER_CM A4 = (A4_WIDTH, A4_HEIGHT) + +# constants specifically for --nup4 +A4_HALF_WIDTH = A4_WIDTH / 2 +A4_HALF_HEIGHT = A4_HEIGHT / 2 CUT_DEPTH = 1.95 * POINTS_PER_CM CUT_WIDTH = 1.05 * POINTS_PER_CM MIDDLE_POINT_DEPTH = 0.4 * POINTS_PER_CM SPINE_LIMIT = 1 * POINTS_PER_CM +QUARTER_SCALE_FACTOR = 0.5 +PAGE_ORDER = (3,0,7,4,1,2,5,6) # some helpers class HandledException(Exception): @@ -138,6 +144,15 @@ def parse_page_range(range_string, pages): end_page = int(end) return start_page, end_page +def draw_cut(canvas, x_spine_limit, direction): + outer_start_x = x_spine_limit - 0.5 * CUT_WIDTH * direction + inner_start_x = x_spine_limit + 0.5 * CUT_WIDTH * direction + middle_point_y = A4_HALF_HEIGHT + MIDDLE_POINT_DEPTH * direction + end_point_y = A4_HALF_HEIGHT + CUT_DEPTH * direction + canvas.line(inner_start_x, A4_HALF_HEIGHT, x_spine_limit, end_point_y) + canvas.line(x_spine_limit, end_point_y, x_spine_limit, middle_point_y) + canvas.line(x_spine_limit, middle_point_y, outer_start_x, A4_HALF_HEIGHT) + def parse_args(): parser = argparse.ArgumentParser(description=__doc__, epilog=help_epilogue, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("-i", "--input_file", action="append", required=True, help="input PDF file") @@ -317,17 +332,14 @@ def main(): print(f"built page number {i+1} (of {len(pages_to_add)})") else: + # --nup4 output print("-n: building 4-input-pages-per-output-page book") print(f"-m: applying printable-area margin of {args.print_margin}cm") if args.analyze: print("-a: drawing page borders, spine limits") - n_pages_per_axis = 2 printable_margin = args.print_margin * POINTS_PER_CM - printable_scale = (A4_WIDTH - 2*printable_margin)/A4_WIDTH - half_width = A4_WIDTH / n_pages_per_axis - half_height = A4_HEIGHT / n_pages_per_axis - section_scale_factor = 1 / n_pages_per_axis - spine_part_of_page = (SPINE_LIMIT / half_width) / printable_scale + printable_scale = (A4_WIDTH - 2 * printable_margin)/A4_WIDTH + spine_part_of_page = (SPINE_LIMIT / A4_HALF_WIDTH) / printable_scale bonus_shrink_factor = 1 - spine_part_of_page new_page_order = [] new_i_order = [] @@ -341,23 +353,10 @@ def main(): i += 1 if i == 8: i = 0 - new_i_order += [8 * n_eights + 3, - 8 * n_eights + 0, - 8 * n_eights + 7, - 8 * n_eights + 4, - 8 * n_eights + 1, - 8 * n_eights + 2, - 8 * n_eights + 5, - 8 * n_eights + 6] + for n in PAGE_ORDER: + new_i_order += [8 * n_eights + n] + new_page_order += [eight_pack[n]] n_eights += 1 - new_page_order += [eight_pack[3]] # page front, upper left - new_page_order += [eight_pack[0]] # page front, upper right - new_page_order += [eight_pack[7]] # page front, lower left - new_page_order += [eight_pack[4]] # page front, lower right - new_page_order += [eight_pack[1]] # page back, upper left - new_page_order += [eight_pack[2]] # page back, upper right - new_page_order += [eight_pack[5]] # page back, lower left - new_page_order += [eight_pack[6]] # page back, lower right i = 0 page_count = 0 front_page = True @@ -382,23 +381,23 @@ def main(): page.add_transformation(pypdf.Transformation().translate(ty=(1-bonus_shrink_factor)*A4_HEIGHT)) if i == 0 or i == 1: y_section = A4_HEIGHT - page.mediabox.bottom = half_height + page.mediabox.bottom = A4_HALF_HEIGHT page.mediabox.top = A4_HEIGHT if i == 2 or i == 3: y_section = 0 page.mediabox.bottom = 0 - page.mediabox.top = half_height + page.mediabox.top = A4_HALF_HEIGHT if i == 0 or i == 2: x_section = 0 page.mediabox.left = 0 - page.mediabox.right = half_width + page.mediabox.right = A4_HALF_WIDTH if i == 1 or i == 3: page.add_transformation(pypdf.Transformation().translate(tx=(1-bonus_shrink_factor)*A4_WIDTH)) x_section = A4_WIDTH - page.mediabox.left = half_width + page.mediabox.left = A4_HALF_WIDTH page.mediabox.right = A4_WIDTH page.add_transformation(pypdf.Transformation().translate(tx=x_section, ty=y_section)) - page.add_transformation(pypdf.Transformation().scale(section_scale_factor, section_scale_factor)) + page.add_transformation(pypdf.Transformation().scale(QUARTER_SCALE_FACTOR, QUARTER_SCALE_FACTOR)) new_page.merge_page(page) page_count += 1 print(f"merged page number {page_count} (of {len(pages_to_add)})") @@ -410,10 +409,10 @@ def main(): c = reportlab.pdfgen.canvas.Canvas(packet, pagesize=A4) c.setLineWidth(0.1) c.line(0, A4_HEIGHT, A4_WIDTH, A4_HEIGHT) - c.line(0, half_height, A4_WIDTH, half_height) + c.line(0, A4_HALF_HEIGHT, A4_WIDTH, A4_HALF_HEIGHT) c.line(0, 0, A4_WIDTH, 0) c.line(0, A4_HEIGHT, 0, 0) - c.line(half_width, A4_HEIGHT, half_width, 0) + c.line(A4_HALF_WIDTH, A4_HEIGHT, A4_HALF_WIDTH, 0) c.line(A4_WIDTH, A4_HEIGHT, A4_WIDTH, 0) c.save() new_pdf = pypdf.PdfReader(packet) @@ -422,34 +421,20 @@ def main(): printable_offset_y = printable_margin * A4_HEIGHT / A4_WIDTH new_page.add_transformation(pypdf.Transformation().scale(printable_scale, printable_scale)) new_page.add_transformation(pypdf.Transformation().translate(tx=printable_offset_x, ty=printable_offset_y)) - x_left_SPINE_LIMIT = half_width * bonus_shrink_factor - x_right_SPINE_LIMIT = A4_WIDTH - x_left_SPINE_LIMIT + x_left_spine_limit = A4_HALF_WIDTH * bonus_shrink_factor + x_right_spine_limit = A4_WIDTH - x_left_spine_limit if args.analyze or front_page: packet = io.BytesIO() c = reportlab.pdfgen.canvas.Canvas(packet, pagesize=A4) if args.analyze: # spine lines c.setLineWidth(0.1) - c.line(x_left_SPINE_LIMIT, A4_HEIGHT, x_left_SPINE_LIMIT, 0) - c.line(x_right_SPINE_LIMIT, A4_HEIGHT, x_right_SPINE_LIMIT, 0) + c.line(x_left_spine_limit, A4_HEIGHT, x_left_spine_limit, 0) + c.line(x_right_spine_limit, A4_HEIGHT, x_right_spine_limit, 0) if front_page: c.setLineWidth(0.2) - # cut upper left - start_up_left_left_x = x_left_SPINE_LIMIT - 0.5 * CUT_WIDTH - start_up_left_right_x = x_left_SPINE_LIMIT + 0.5 * CUT_WIDTH - middle_point_up_left_y = half_height + MIDDLE_POINT_DEPTH - end_point_up_left_y = half_height + CUT_DEPTH - c.line(start_up_left_right_x, half_height, x_left_SPINE_LIMIT, end_point_up_left_y) - c.line(x_left_SPINE_LIMIT, end_point_up_left_y, x_left_SPINE_LIMIT, middle_point_up_left_y) - c.line(x_left_SPINE_LIMIT, middle_point_up_left_y, start_up_left_left_x, half_height) - # cut lower right - start_down_right_left_x = x_right_SPINE_LIMIT - 0.5 * CUT_WIDTH - start_down_right_right_x = x_right_SPINE_LIMIT + 0.5 * CUT_WIDTH - middle_point_down_right_y = half_height - MIDDLE_POINT_DEPTH - end_point_down_right_y = half_height - CUT_DEPTH - c.line(start_down_right_left_x, half_height, x_right_SPINE_LIMIT, end_point_down_right_y) - c.line(x_right_SPINE_LIMIT, end_point_down_right_y, x_right_SPINE_LIMIT, middle_point_down_right_y) - c.line(x_right_SPINE_LIMIT, middle_point_down_right_y, start_down_right_right_x, half_height) + draw_cut(c, x_left_spine_limit, (1)) + draw_cut(c, x_right_spine_limit, (-1)) if args.analyze or front_page: c.save() new_pdf = pypdf.PdfReader(packet)