zine_maker/zine_maker.py
2021-12-13 02:28:26 +02:00

304 lines
12 KiB
Python

#!/bin/python
"""
A module for generating A5 size pdf zines
based on pyFPDF.
GPL3 License, Mara Karagianni May 2021
"""
import glob
import random
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/150] by %[fx:h/150] 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):
# TODO add 2 blank pages after the cover and colophon
# check if we have an odd number of pages
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]
f = open(filename, 'rt')
lines = f.readlines()
# 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>"):
img_filename = line.split("<img>")[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("<h2>"):
line = re.sub('((<h2>)|(</h2>$))', '', line)
self.set_text_color(130, 50, 250)
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("<i>"):
line = re.sub('((<i>)|(</i>$))', '', 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("<b>"):
line = re.sub('((<b>)|(</b>$))', '', 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("# "):
if self.get_y() > top_margin:
self.set_xy(left_margin, top_margin+9)
self.add_page()
self.set_font(header_font, size=25)
self.set_text_color(255, 0, 0)
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)
subheader_font = "helvetica"
self.set_font(subheader_font, size=18)
self.set_text_color(0, 0, 0)
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("```"):
self.set_font('helvetica', '', size=11)
self.set_text_color(0, 30, 255)
line = re.sub('((`)|(```))', '', line)
self.multi_cell(cell_width, cell_height, line,
0, align='L')
elif len(line.strip()) == 0:
# 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("<quote>"):
line = re.sub('(<quote>$)', '', 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("</quote>"):
line = re.sub('(</quote>$)', '', 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 "<index>" in line:
line = re.sub('(<index>$)', '', 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 "</index>" in line:
line = re.sub('(</index>$)', '', 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())
# close file
f.close()
# self.footer()
def cover(self, file_title, cover_font, max_height):
col = 10
margin = 5
self.set_margins(margin, margin, margin)
self.add_page()
try:
title = open(file_title, 'r')
except Exception as e:
print(e, "Make sure the path and the file exists!", end="\n")
else:
for line in title.readlines():
for letter in line:
if self.get_y() >= max_height:
self.set_xy(margin+col, margin)
col += 40
size = random.randrange(15, 30, 10)
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 = 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)
# close the file
title.close()
self.set_text_color(0, 0, 0, 0)
def colophon(self, text, colophon_font):
f = open(text, 'r')
lines = f.readlines()
top_margin = 20
margin = 25
self.set_margins(margin, top_margin, margin)
size = 13
self.set_font(colophon_font, '', size)
self.set_text_color(0, 0, 0)
self.add_page()
for line in lines:
self.multi_cell(100, size, line, 0, align='C')
# close the file
f.close()
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')