#!/bin/python """ A module for generating A5 size pdf zines based on pyFPDF. GPL3 License, Mara Karagianni May 2021 """ import glob import re import subprocess from fpdf import FPDF # ref https://pyfpdf.readthedocs.io/en/latest/ class Zine(FPDF): def add_new_signature(self, top_margin, left_margin, right_margin): # create new page/signature self.add_page() self.set_margins(left_margin, top_margin, right_margin) self.set_xy(left_margin, top_margin) print('NEW SIGNATURE') def move_to_page_right(self, top_margin, left_max_margin, right_margin): print('*****') print("BOTTOM OF LEFT PAGE, height is {}".format(self.get_y())) print('*****') self.set_margins(top_margin, left_max_margin, right_margin) self.set_xy(left_max_margin, top_margin) def position_img(self, img_filename, img_x, img_y, **kwargs): img_size = subprocess.run( ["identify", "-format", "%[fx:w/72] by %[fx:h/72] inches", "%s" % img_filename], stdout=subprocess.PIPE, text=True) img_height_inches = img_size.stdout.split(' ')[2] img_width_inches = img_size.stdout.split(' ')[0] img_height_mm = float(img_height_inches) * float(24.5) img_width_mm = float(img_width_inches) * float(24.5) if kwargs: max_height = kwargs["max_height"] left_margin = kwargs["left_margin"] top_margin = kwargs["top_margin"] if self.get_y() + img_height_mm >= max_height: self.add_page() self.set_xy(left_margin, top_margin) img_y = top_margin previous_y = self.get_y() # center image img_x = (150 - img_width_mm) / 2 self.image(img_filename, img_x, img_y, img_width_mm) # move y at the bottom of the image # TODO check if get_y() would do the same job self.set_xy(self.get_x(), previous_y+img_height_mm) def shuffle_chapters(self, pdfinput): subprocess.run( ["pdfseparate", "./%s" % pdfinput, "./%02d_chapter.pdf"], stdout=subprocess.PIPE, text=True) pages = glob.glob("./*_chapter.pdf") pages.sort() print("CHAPTERS {}".format(pages)) shuffled_list = [] count = 0 while count < (len(pages))/2: shuffled_list.append(pages[-(count+1)]) shuffled_list.append(pages[count]) count += 1 # reverse if count != len(pages)/2: shuffled_list.append(pages[count]) shuffled_list.append(pages[-(count+1)]) count += 1 return shuffled_list def create_pages(self, filename, max_height, left_margin, left_max_margin, top_margin, right_margin, *args): if args: cell_width = args[0] cell_height = args[1] cell_header_height = args[2] header_font = args[3] text_font = args[4] text_font_size = args[5] lines = open(filename).readlines() print(filename) # first page print("FIRST PAGE") self.set_margins(left_margin, top_margin, right_margin) self.set_xy(left_margin, top_margin) self.add_page() for line in lines: if ">>" in line: self.set_font(text_font, '', size=16) self.cell(cell_width, cell_height, line, 0, ln=1, align='L') self.set_font(text_font, '', size=text_font_size) # check if we have an image elif line.startswith(""): img_filename = line.split("")[1] kwargs = { "max_height": max_height, "left_margin": left_margin, "top_margin": top_margin } self.position_img( img_filename, self.get_x(), self.get_y(), **kwargs) # check if we have a title elif line.startswith("

"): line = re.sub('((

)|(

$))', '', line) self.set_text_color(130, 50, 250) # self.set_text_color(255, 0, 255) self.set_font(header_font, size=22) if self.get_y() > top_margin: self.set_xy(left_margin, top_margin+9) self.add_page() self.cell(cell_width, cell_header_height, line, 0, ln=1, align='C') left_x = self.get_x() top_y = self.get_y() self.dashed_line( left_x, top_y, left_x+cell_width, top_y, dash_length=3, space_length=3) self.set_text_color(0, 0, 0) self.set_font(text_font, size=text_font_size) elif line.startswith(""): line = re.sub('(()|($))', '', line) self.set_font('helvetica', 'I', size=19) self.multi_cell(cell_width, cell_height, line, 0, align='L') self.set_font(text_font, '', size=text_font_size) elif line.startswith(""): line = re.sub('(()|($))', '', line) self.set_font('helvetica', 'B', size=13) self.cell(cell_width, cell_height, line, 0, ln=1, align='C') self.set_font(text_font, '', size=text_font_size) elif line.startswith("#"): self.set_font('helvetica', 'B', size=9) self.set_text_color(209, 17, 65) self.multi_cell(cell_width, cell_height, line, 0, align='L') # go back to text font self.set_text_color(0, 0, 0) self.set_font(text_font, '', size=text_font_size) elif line.startswith("$") or line.startswith("(venv)"): self.set_font('helvetica', 'B', size=9) self.set_text_color(0, 30, 255) self.multi_cell(cell_width, cell_height, line, 0, align='L') # go back to text font self.set_text_color(0, 0, 0) self.set_font(text_font, '', size=text_font_size) elif line.startswith(""): line = re.sub('($)', '', line) self.set_font(text_font, '', size=13) self.set_text_color(0, 80, 115) self.multi_cell(cell_width, cell_height, line, 0, align='C') elif line.startswith(""): line = re.sub('($)', '', line) self.multi_cell(cell_width, cell_height, line, 0, align='L') self.set_font(text_font, '', text_font_size) self.set_text_color(0, 0, 0) elif "" in line: line = re.sub('($)', '', line) self.set_font(text_font, '', size=18) self.set_text_color(0, 0, 0) self.set_text_color(41, 98, 255) self.cell(cell_width/8, cell_height, line, 0, align='C') elif "" in line: line = re.sub('($)', '', line) self.set_font(text_font, '', size=text_font_size) self.set_text_color(0, 0, 0) self.multi_cell(cell_width, cell_height, line, 0, align='L') else: # check if we need the following variable_x = self.get_x() self.multi_cell(cell_width, cell_height, line, 0, align='L') self.set_xy(variable_x, self.get_y()) # self.footer() def cover(self, title, cover_font, max_height): col = 10 margin = 15 import random self.set_margins(margin, margin, margin) self.add_page() for letter in title: if self.get_y() >= max_height: self.set_xy(margin+col, margin) col += 40 size = random.randrange(30, 50, 15) self.set_font(cover_font, '', size) variable_x = margin+col print("LETTER {}, POSITION Y {}".format(letter, self.get_y())) print("VAR X {}".format(variable_x)) self.set_xy(variable_x, self.get_y()) self.cell(size, size, letter) self.line(size, size, self.get_x(), self.get_y()) if(size % 2 == 0): var = "DF" # r = 138, 43, 226 R = random.randrange(30, 255, 40) G = random.randrange(0, 55, 55) B = random.randrange(0, 155, 50) self.set_fill_color(R, G, B) else: var = "D" print(var) self.rect( float(self.get_x()), float(self.get_y()), float(size/2), float(size*4), style=var) self.ln(size/2) def colophon(self, text): lines = open(text, 'r').readlines() top_margin = 20 margin = 25 self.add_font( 'CasaleNBP', '', r"/home/mara/.fonts/CasaletwoNbp-Bp4V.ttf", uni=True) self.set_margins(margin, top_margin, margin) size = 13 cover_font = 'CasaleNBP' self.set_font(cover_font, '', size) self.add_page() for line in lines: self.multi_cell(100, size, line, 0, align='C') def footer(self): text_font = 'Helvetica' # Go to 1.5 cm from bottom self.set_y(-12) self.set_text_color(0, 0, 0) self.set_font(text_font, '', size=7) # Print current page number # self.cell(0, 7, '%s' % self.page_no(), 0, 0, 'C') self.cell(0, 7, '%s' % self.page_no(), 0, 0, 'C')