Update zinemaker.pdf, shuffle code, inputs-outputs
This commit is contained in:
parent
66af9a655c
commit
026ea64007
11 changed files with 228 additions and 388 deletions
|
|
@ -127,7 +127,7 @@ from the terminal run:
|
|||
|
||||
`pdfunite covers/cover.pdf body/body.pdf colophons/colophon.pdf zines/final.pdf`
|
||||
|
||||
You shall substitute the file paths to the your own corresponding /path/filenames
|
||||
You shall substitute the file paths to your own corresponding /path/filenames
|
||||
|
||||
## See this readme as the generated screen version zine:
|
||||
open the file zines/zinemaker.pdf
|
||||
|
|
@ -140,7 +140,7 @@ open the file zines/zinemaker.pdf
|
|||
|
||||
Default parameters: as input "zines/zinemaker_screen.pdf" and as output "zinemaker{random_number}.pdf"
|
||||
Run it for your own pdf files as following:
|
||||
`python shuffle_pdf.py` zines/<input>.pdf zines/<output>.pdf`
|
||||
`python shuffle_pdf.py` <input_file>.pdf <output_file>.pdf`
|
||||
|
||||
In the printer settings opt-in for the following settings:
|
||||
- A4 Landscape
|
||||
|
|
|
|||
BIN
body/readme.pdf
BIN
body/readme.pdf
Binary file not shown.
32
colophon.py
32
colophon.py
|
|
@ -3,30 +3,28 @@ import random
|
|||
from zine_maker import Zine
|
||||
|
||||
|
||||
def make_colophon():
|
||||
|
||||
# Variables
|
||||
text_font_size = 12
|
||||
def make_colophon(inputfile, output):
|
||||
|
||||
# set font for all text
|
||||
zine = Zine(orientation="P", unit="mm", format="A5")
|
||||
|
||||
# cover font
|
||||
zine.add_font(
|
||||
'CasaleNBP', '', r"fonts/CasaletwoNbp-Bp4V.ttf", uni=True)
|
||||
cover_font = 'CasaleNBP'
|
||||
# you can change the font to text_font 1 or 2
|
||||
# or add your fonts
|
||||
|
||||
# text font
|
||||
# colophon font
|
||||
zine.add_font(
|
||||
'CasaleNBP', '', r"./fonts/CasaletwoNbp-Bp4V.ttf", uni=True)
|
||||
text_font1 = 'CasaleNBP'
|
||||
|
||||
# colophon font alternate
|
||||
zine.add_font(
|
||||
'Kpalter', '',
|
||||
r"fonts/KpProgrammerAlternatesNbp-Zg1q.ttf", uni=True)
|
||||
text_font = 'Kpalter'
|
||||
zine.set_font(text_font, '', size=text_font_size)
|
||||
# text_font2 = 'Kpalter'
|
||||
|
||||
# you can change the font to text_font
|
||||
# or add your fonts
|
||||
zine.colophon(inputfile, cover_font)
|
||||
zine.colophon(inputfile, text_font1)
|
||||
zine.output(output)
|
||||
print("PDF saved as {}".format(output))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
@ -36,7 +34,7 @@ if __name__ == '__main__':
|
|||
output = sys.argv[2]
|
||||
inputfile = sys.argv[1]
|
||||
else:
|
||||
inputfile = "./text/colophon.txt"
|
||||
output = "./colophones/colophon{}.pdf".format(random.randint(1, 40))
|
||||
inputfile = "./text/colophon_readme.txt"
|
||||
output = "./colophons/colophon_readme.pdf".format(random.randint(1, 40))
|
||||
|
||||
make_colophon()
|
||||
make_colophon(inputfile, output)
|
||||
|
|
|
|||
BIN
colophons/colophon_readme.pdf
Normal file
BIN
colophons/colophon_readme.pdf
Normal file
Binary file not shown.
25
cover.py
25
cover.py
|
|
@ -1,27 +1,18 @@
|
|||
import sys
|
||||
import random
|
||||
from zine_maker import Zine
|
||||
|
||||
|
||||
def make_cover():
|
||||
# Variables
|
||||
text_font_size = 12
|
||||
|
||||
def make_cover(finput, foutput):
|
||||
# set font for all text
|
||||
zine = Zine(orientation="P", unit="mm", format="A5")
|
||||
|
||||
# cover font
|
||||
zine.add_font('CasaleNBP', '', r"fonts/CasaletwoNbp-Bp4V.ttf", uni=True)
|
||||
zine.add_font('CasaleNBP', '', r"./fonts/CasaletwoNbp-Bp4V.ttf", uni=True)
|
||||
cover_font = 'CasaleNBP'
|
||||
|
||||
# text font
|
||||
zine.add_font(
|
||||
'Kpalter', '', r"fonts/KpProgrammerAlternatesNbp-Zg1q.ttf", uni=True)
|
||||
text_font = 'Kpalter'
|
||||
zine.set_font(text_font, '', size=text_font_size)
|
||||
|
||||
zine.cover(inputfile, cover_font, max_height=140)
|
||||
zine.output(output)
|
||||
zine.cover(finput, cover_font, max_height=140)
|
||||
zine.output(foutput)
|
||||
print("PDF saved as {}".format(foutput))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
@ -31,7 +22,7 @@ if __name__ == '__main__':
|
|||
output = sys.argv[2]
|
||||
inputfile = sys.argv[1]
|
||||
else:
|
||||
inputfile = "./text/cover.txt"
|
||||
output = "./covers/cover{}.pdf".format(random.randint(1, 40))
|
||||
inputfile = "./text/cover_readme.txt"
|
||||
output = "./covers/cover_readme.pdf"
|
||||
|
||||
make_cover()
|
||||
make_cover(inputfile, output)
|
||||
|
|
|
|||
33
doc_pdf.py
33
doc_pdf.py
|
|
@ -1,13 +1,10 @@
|
|||
import sys
|
||||
import random
|
||||
from zine_maker import Zine
|
||||
|
||||
|
||||
def make():
|
||||
def make(inputfile, output):
|
||||
# Variables
|
||||
header_font = 'helvetica'
|
||||
header_font_size = 14
|
||||
text_font_size = 11
|
||||
text_font_size = 10
|
||||
|
||||
top_margin = 20
|
||||
left_margin = 20
|
||||
|
|
@ -15,27 +12,22 @@ def make():
|
|||
left_max_margin = 160
|
||||
|
||||
max_height = 190
|
||||
left_x = 20
|
||||
top_y = 30
|
||||
cell_width = 110
|
||||
cell_header_height = 16
|
||||
cell_height = 6
|
||||
cell_header_height = 26
|
||||
cell_height = 8
|
||||
|
||||
# set font for all text
|
||||
zine = Zine(orientation="P", unit="mm", format="A5")
|
||||
|
||||
# cover font
|
||||
zine.add_font(
|
||||
'CasaleNBP', '', r"fonts/CasaletwoAlternatesNbp-RgRM.ttf", uni=True
|
||||
)
|
||||
cover_font = 'CasaleNBP'
|
||||
|
||||
# text font
|
||||
zine.add_font(
|
||||
'Kpalter', '',
|
||||
r"fonts/KpProgrammerAlternatesNbp-Zg1q.ttf", uni=True
|
||||
)
|
||||
text_font = 'Kpalter'
|
||||
zine.add_font('CasaleNBP', '', r"./fonts/CasaletwoNbp-Bp4V.ttf", uni=True)
|
||||
header_font = 'CasaleNBP'
|
||||
#header_font = 'Kpalter'
|
||||
text_font = 'helvetica'
|
||||
zine.set_font(text_font, '', size=text_font_size)
|
||||
|
||||
zine.create_pages(inputfile, max_height, left_margin,
|
||||
|
|
@ -44,16 +36,19 @@ def make():
|
|||
header_font, text_font, text_font_size)
|
||||
|
||||
zine.output(output)
|
||||
print("PDF saved as {}".format(output))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# input text and output pdf
|
||||
if len(sys.argv) > 1:
|
||||
if len(sys.argv) == 2:
|
||||
output = "./body/readme.pdf"
|
||||
if len(sys.argv) == 3:
|
||||
output = sys.argv[2]
|
||||
inputfile = sys.argv[1]
|
||||
else:
|
||||
inputfile = "./text/oulipo1.txt"
|
||||
output = "./body/body{}.pdf".format(random.randint(1, 40))
|
||||
inputfile = "./text/readme"
|
||||
output = "./body/readme.pdf"
|
||||
|
||||
make()
|
||||
make(inputfile, output)
|
||||
|
|
|
|||
307
shuffle_pdf.py
307
shuffle_pdf.py
|
|
@ -4,298 +4,39 @@ A script for generating A5 size pdf zines
|
|||
with a text-file input, under development,
|
||||
GPL3 Licence, Mara Karagianni May 2021
|
||||
"""
|
||||
import glob
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
from fpdf import FPDF
|
||||
# ref https://pyfpdf.readthedocs.io/en/latest/
|
||||
|
||||
# Variables
|
||||
header_font = 'helvetica'
|
||||
header_font_size = 14
|
||||
text_font_size = 12
|
||||
|
||||
top_margin = 20
|
||||
left_margin = 20
|
||||
right_margin = 20
|
||||
left_max_margin = 160
|
||||
|
||||
max_height = 190
|
||||
left_x = 20
|
||||
top_y = 30
|
||||
cell_width = 110
|
||||
cell_header_height = 16
|
||||
cell_height = 6
|
||||
|
||||
# Image variables
|
||||
img_x = 20
|
||||
img_y = 80
|
||||
img_len = 120
|
||||
|
||||
|
||||
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,
|
||||
cell_width, cell_height, cell_header_height,
|
||||
header_font, text_font):
|
||||
chapter = 0
|
||||
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>"):
|
||||
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(255, 0, 255)
|
||||
self.set_font(text_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("<b>"):
|
||||
line = re.sub('((<b>)|(</b>$))', '', line)
|
||||
self.set_font(text_font, '', size=18)
|
||||
self.cell(cell_width, cell_height, line,
|
||||
0, ln=1, align='L')
|
||||
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("<conf>"):
|
||||
#line = re.sub('(<conf>$)', '', line)
|
||||
self.set_font('helvetica', 'B', size=9)
|
||||
self.set_text_color(0,80,115)
|
||||
self.multi_cell(cell_width, cell_height, line,
|
||||
0, align='L')
|
||||
elif line.startswith("</conf>"):
|
||||
#line = re.sub('(</conf>$)', '', 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())
|
||||
|
||||
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())
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
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, 255)
|
||||
from zine_maker import Zine
|
||||
|
||||
|
||||
def shuffle_zine(finput, foutput):
|
||||
# set font for all text
|
||||
zine = Zine(orientation="P", unit="mm", format="A5")
|
||||
chapter_list = zine.shuffle_chapters(finput)
|
||||
proc = subprocess.Popen(
|
||||
["pdfunite"] + chapter_list + [foutput],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
out, err = proc.communicate()
|
||||
if err:
|
||||
print("Something went wrong!", err.decode('utf-8'), sep="\n")
|
||||
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"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):
|
||||
# Go to 1.5 cm from bottom
|
||||
self.set_y(-15)
|
||||
# Select Arial italic 8
|
||||
#self.set_font('Arial', 'I', 8)
|
||||
self.set_text_color(0, 0, 0)
|
||||
self.set_font(text_font, '', size=text_font_size)
|
||||
# Print current and total page numbers
|
||||
self.cell(0, 10, '%s' % self.page_no(), 0, 0, 'C')
|
||||
|
||||
print("PDF saved as {}".format(foutput))
|
||||
os.system("mv ./*_chapter.pdf ./tmp")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# file to get the text
|
||||
if len(sys.argv) > 1:
|
||||
if len(sys.argv) == 3:
|
||||
output = sys.argv[2]
|
||||
filename = sys.argv[1]
|
||||
else:
|
||||
filename = "./finals/test.pdf"
|
||||
output = './finals/trial.pdf'
|
||||
filename = "./zines/zinemaker_screen.pdf"
|
||||
output = "./zines/zinemaker{}.pdf".format(random.randint(1, 40))
|
||||
|
||||
# set font for all text
|
||||
zine = Zine(orientation="P", unit="mm", format="A5")
|
||||
|
||||
# cover font
|
||||
zine.add_font('CasaleNBP', '', r"fonts/CasaletwoNbp-Bp4V.ttf", uni=True)
|
||||
cover_font = 'CasaleNBP'
|
||||
|
||||
# text font
|
||||
zine.add_font(
|
||||
'Kpalter', '', r"fonts/KpProgrammerAlternatesNbp-Zg1q.ttf", uni=True)
|
||||
text_font = 'Kpalter'
|
||||
zine.set_font(text_font, '', size=text_font_size)
|
||||
|
||||
chapter_list = zine.shuffle_chapters(filename)
|
||||
subprocess.Popen(["pdfunite"] + chapter_list + [output])
|
||||
shuffle_zine(filename, output)
|
||||
|
|
|
|||
135
text/readme
135
text/readme
|
|
@ -1,5 +1,17 @@
|
|||
## To Download the project, near the top of the page, click on the download icon next to "WEB IDE".
|
||||
You can choose which type of archived folder you want, and then open it in your filesystem.
|
||||
# Introduction
|
||||
|
||||
This zine helps in navigating the zine_maker code, a small software tool derived from pyPDF library. The code is written in Python, and provides a few scripts for creating covers, colophons, content, and also signatures for preparing a PDF for the printer. The scripts run with python version 3.x.x and we can feed to the scripts inputs and outputs. As an input, we give the path to a text file, which shall create the text and images content of the zine, and as an output we give a the path/filename of our choice. We can also run the scripts with no input nor output, in which case, they take as default parameters the readme text from the text/ folder and produce an output to either of the folders covers, colophons, body, or zines, depending on which script we are running each time.
|
||||
|
||||
# Get the code
|
||||
|
||||
## Download the source code
|
||||
As of 2021-2022, the code is under active development by the author and can be cloned and/or downloaded from https://git.systerserver.net/mara/zine_maker.
|
||||
To download the project, near the top of the gitlab page, click on the download icon next to "Find file".
|
||||
You can choose which type of archived folder you want, and then open it in your filesystem, by right clicking the archived folder, or from the terminal:
|
||||
```
|
||||
tar -xvf zine_maker.tar -C /home/user/destination
|
||||
unzip zinme_maker.zip -d /home/user/destination
|
||||
```
|
||||
|
||||
## OR use git clone:
|
||||
```
|
||||
|
|
@ -7,65 +19,130 @@ git clone https://zine:DskM_8XxtKt-Wym1xHd1@git.systerserver.net/mara/zine_maker
|
|||
cd zine_maker
|
||||
```
|
||||
|
||||
# Requirements
|
||||
|
||||
## Requirements
|
||||
You need either python2 or python3 running on the computer
|
||||
Basic requirements are listed here.
|
||||
Python3 should be installed on the computer
|
||||
https://www.python.org/downloads/
|
||||
|
||||
And also the pip command
|
||||
And also the pip command if it didn't get installed with Python
|
||||
https://pip.pypa.io/en/stable/installation/
|
||||
|
||||
Once these are installed, from within zine_maker run:
|
||||
Once these are installed, from within zine_maker folder run:
|
||||
|
||||
`pip install -r requirements.txt`
|
||||
|
||||
## For merging the cover.pdf, body.pdf and colophon.pdf there are many pdf merger tools,
|
||||
one that is command line based is pdfunite
|
||||
# Miscellaneous
|
||||
|
||||
## Fonts
|
||||
The source code comes with some fonts under the fonts folder. You can use your
|
||||
fonts of preference by adding them either in the fonts folder and edit the
|
||||
files cover.py, colophon.py and doc_pdf.py to give the new names. Or add your
|
||||
absolute font path directly to the python scripts.
|
||||
|
||||
## Text
|
||||
The input texts should be clean from characters added by some text editors or
|
||||
Operating Systems. Use the cat command to check your text is ready as input
|
||||
with:
|
||||
`cat --show-nonprinting input.txt`
|
||||
|
||||
Symbols such as M-oM-;M or ^M (carriage Return / line feed) need to be removed.
|
||||
A cool tool for that is dos2unix, which is available as command line, but needs
|
||||
to be installed:
|
||||
`dos2unix filename`
|
||||
|
||||
Or with the sed command:
|
||||
`sed -e "s/\r//g" file > newfile`
|
||||
|
||||
Extensive info can be find at:
|
||||
https://www.cyberciti.biz/faq/sed-remove-m-and-line-feeds-under-unix-linux-bsd-appleosx/
|
||||
|
||||
## Layout
|
||||
All the font styling happens in the zine_maker function create_pages(). The
|
||||
input text is parsed for specific tags or symbols in the begining of each line
|
||||
and changes to the font color and size happen accordingly. We can add more or edit
|
||||
existing rules, directly in the zine_maker code.
|
||||
|
||||
## Parameters
|
||||
The python scripts cover.py, colophon.py and doc_pdf.py take a text input and an output filename. If we give no input/output, the default input is the related readme files under covers/body/colophons/
|
||||
|
||||
## Merge
|
||||
For merging the cover, body and colophon pdf files, there are many pdf merger tools. One that is command line based and is used in this tutorial is pdfunite
|
||||
http://linux-commands-examples.com/pdfunite
|
||||
|
||||
from the terminal run:
|
||||
|
||||
`pdfunite cover.pdf body.pdf colophon.pdf output.pdf`
|
||||
|
||||
## For shuffling the final pdf and prepare it for printing you need the pdfseparate command
|
||||
## Print
|
||||
For shuffling the final pdf and prepare it for printing you need the pdfseparate command
|
||||
http://www.linux-commands-examples.com/pdfseparate
|
||||
it is used inside the shuffle_pdf.py file (see details at the end of this Readme)
|
||||
it is used inside the shuffle_pdf.py file (see details at the end of this README).
|
||||
|
||||
## For making use of images in the script, image magick needs to be installed
|
||||
## Images
|
||||
For making use of images in the script
|
||||
image magick needs to be installed
|
||||
http://www.imagemagick.org/
|
||||
|
||||
## To make the content of the pdf
|
||||
# Run the code!
|
||||
|
||||
## Make the content of the pdf
|
||||
The default parameters included in the script would create a zine from this
|
||||
readme:
|
||||
`python doc_pdf.py `
|
||||
|
||||
OR
|
||||
OR you can experiment with the other sample text found in this repository.
|
||||
|
||||
`python doc_pdf.py text/images.txt body/images.pdf`
|
||||
|
||||
OR add your text file and replace respectively
|
||||
OR get real and add your own text file and replace respectively the input and
|
||||
output filenames.
|
||||
|
||||
`python doc_pdf.py text/<your_file>.txt body/<output-name>.pdf`
|
||||
|
||||
## To make the cover of the pdf
|
||||
## Make the cover of the pdf
|
||||
Same, the default parameters included in the script would create the cover for the zine_maker:
|
||||
`python cover.py`
|
||||
|
||||
OR
|
||||
OR try-out the other cover samples:
|
||||
|
||||
`python cover.py text/cover.txt covers/cover.pdf`
|
||||
|
||||
OR add your text file and replace respectively
|
||||
OR add your cover text file and replace respectively:
|
||||
|
||||
`python cover.py text/<your-cover>.txt covers/<cover-name>.pdf`
|
||||
|
||||
## To make the colophon of the pdf
|
||||
`python cover.py `
|
||||
## Make the colophon of the pdf
|
||||
Same, the default parameters included in the script would create the colophon for the zine_maker:
|
||||
`python colophon.py `
|
||||
|
||||
OR
|
||||
OR try-out the other colophon samples:
|
||||
|
||||
`python cover.py text/colophon.txt colophones/colophon.pdf`
|
||||
`python colophon.py text/colophon.txt colophons/colophon.pdf`
|
||||
|
||||
OR add your text file and replace respectively
|
||||
OR add your own colophon text file and replace respectively:
|
||||
|
||||
`python cover.py text/<your-colophon>.txt colophones/<output-colophon>.pdf`
|
||||
`python colophon.py text/<your-colophon>.txt colophons/<output-colophon>.pdf`
|
||||
|
||||
## To prepare signatures for printing a small booklet
|
||||
`python shuffle_pdf.py final.pdf final_shuffled.pdf`
|
||||
# Make a screen PDF
|
||||
|
||||
## For the final screen version
|
||||
from the terminal run:
|
||||
|
||||
`pdfunite covers/cover.pdf body/body.pdf colophons/colophon.pdf zines/final.pdf`
|
||||
|
||||
You shall substitute the file paths to your own corresponding /path/filenames
|
||||
|
||||
## See this readme as the generated screen version zine:
|
||||
open the file zines/zinemaker.pdf
|
||||
|
||||
# Make a zine
|
||||
|
||||
## Prepare signatures for printing
|
||||
|
||||
<img>./thumbs/printer_settings.png<img>
|
||||
|
||||
Default parameters: as input "zines/zinemaker_screen.pdf" and as output "zinemaker{random_number}.pdf"
|
||||
Run it for your own pdf files as following:
|
||||
`python shuffle_pdf.py` zines/<input_file>.pdf zines/<output_file>.pdf`
|
||||
|
||||
In the printer settings opt-in for the following settings:
|
||||
- A4 Landscape
|
||||
- Two pages per side
|
||||
- Double side - short edge
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ based on pyFPDF.
|
|||
GPL3 License, Mara Karagianni May 2021
|
||||
"""
|
||||
import glob
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
from fpdf import FPDF
|
||||
|
|
@ -29,7 +30,7 @@ class Zine(FPDF):
|
|||
|
||||
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",
|
||||
["identify", "-format", "%[fx:w/150] by %[fx:h/150] inches",
|
||||
"%s" % img_filename],
|
||||
stdout=subprocess.PIPE, text=True)
|
||||
|
||||
|
|
@ -58,8 +59,10 @@ class Zine(FPDF):
|
|||
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"],
|
||||
["pdfseparate", "%s" % pdfinput, "./%02d_chapter.pdf"],
|
||||
stdout=subprocess.PIPE, text=True)
|
||||
pages = glob.glob("./*_chapter.pdf")
|
||||
pages.sort()
|
||||
|
|
@ -87,8 +90,8 @@ class Zine(FPDF):
|
|||
text_font = args[4]
|
||||
text_font_size = args[5]
|
||||
|
||||
lines = open(filename).readlines()
|
||||
print(filename)
|
||||
f = open(filename, 'rt')
|
||||
lines = f.readlines()
|
||||
|
||||
# first page
|
||||
print("FIRST PAGE")
|
||||
|
|
@ -119,7 +122,6 @@ class Zine(FPDF):
|
|||
elif line.startswith("<h2>"):
|
||||
line = re.sub('((<h2>)|(</h2>$))', '', 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)
|
||||
|
|
@ -149,14 +151,41 @@ class Zine(FPDF):
|
|||
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)
|
||||
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)
|
||||
|
|
@ -200,12 +229,13 @@ class Zine(FPDF):
|
|||
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 = 15
|
||||
import random
|
||||
margin = 5
|
||||
self.set_margins(margin, margin, margin)
|
||||
self.add_page()
|
||||
try:
|
||||
|
|
@ -218,10 +248,12 @@ class Zine(FPDF):
|
|||
if self.get_y() >= max_height:
|
||||
self.set_xy(margin+col, margin)
|
||||
col += 40
|
||||
size = random.randrange(30, 50, 15)
|
||||
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(
|
||||
"LETTER {}, POSITION Y {}".format(letter, self.get_y())
|
||||
)
|
||||
print("VAR X {}".format(variable_x))
|
||||
self.set_xy(variable_x, self.get_y())
|
||||
|
||||
|
|
@ -241,24 +273,30 @@ class Zine(FPDF):
|
|||
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, cover_font):
|
||||
lines = open(text, 'r').readlines()
|
||||
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(cover_font, '', size)
|
||||
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_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')
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue