#!/usr/bin/env python3 import argparse import math import operator import fpdf import strictyaml class Chart: COLUMNS=4 ROWS=16 INDEX_COLS=6 def __init__(self): self.parser = self.get_parser() self.args = self.parser.parse_args() self.data = strictyaml.load(self.args.chart_data.read()).data def get_parser(self): parser = argparse.ArgumentParser() parser.add_argument( "chart_data", type=argparse.FileType("r") ) return parser def get_arranged_cells(self): per_page = self.COLUMNS * self.ROWS padded = self.data["colours"] + [{}] * ( per_page - len(self.data["colours"]) % per_page ) pages = [ padded[i * per_page:i * per_page + per_page] for i in range(len(padded) // per_page) ] cells = [ [ [p[i + self.ROWS * j] for j in range(self.COLUMNS)] for i in range(len(p) // self.COLUMNS) ] for p in pages ] return(cells) def get_index(self): index = [ (c["label"], i // self.ROWS) for i, c in enumerate(self.data["colours"]) ] index.sort(key=operator.itemgetter(0)) return index def write_pdf(self, fname): pdf = fpdf.FPDF(format="A5") pdf.add_font( family="FreeSans", fname="/usr/share/fonts/opentype/freefont/FreeSans.otf", ) pdf.add_font( family="FreeSans", style="B", fname="/usr/share/fonts/opentype/freefont/FreeSansBold.otf", ) pdf.add_font( family="FreeSerif", fname="/usr/share/fonts/opentype/freefont/FreeSerif.otf", ) for p_num, page in enumerate(self.get_arranged_cells()): pdf.add_page() pdf.set_font("FreeSerif", size=12) pdf.cell(64, 8, self.data["title"], align="C") pdf.ln() pdf.set_font("FreeSans", "B", 12) for j in range(self.COLUMNS): pdf.cell(16, 8, str(j + p_num * self.COLUMNS),) pdf.cell(16, 8, "") pdf.ln() for row in page: for cell in row: if cell: pdf.set_fill_color(255,255,255) if cell.get("bg"): pdf.set_fill_color(*map(int, cell["bg"].split())) pdf.cell(16, 8, "", border=1, fill=True) pdf.cell(16, 8, cell["label"], ) pdf.ln(10) pdf.set_font("FreeSerif", size=10) with pdf.text_columns( ncols=self.INDEX_COLS, balance=True, gutter=4, text_align="RIGHT", ) as cols: for c in self.get_index(): pdf.set_font("FreeSerif", size=10) cols.write(str(c[0])) cols.write(" ") pdf.set_font("FreeSans", "B", size=10) cols.write(str(c[1])) cols.ln() pdf.output(fname) if __name__ == "__main__": Chart().write_pdf("asd.pdf")