diff --git a/signprinter_latex.py b/signprinter_latex.py index 6c71fa7..bf84d38 100644 --- a/signprinter_latex.py +++ b/signprinter_latex.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -"""Create a printable webpage for bike part signs.""" +"""Create a latex document with signs (For printing and glueing to boxes).""" import os.path import logging -from typing import Union +from typing import Union, Sequence +from thing import Thing -TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "signtemplate_latex") +TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "thingtemplate_latex") TEMPLATE_PRE = "signlist-header.tex" TEMPLATE_POST = "signlist-footer.tex" TEMPLATE_SIGN = "sign.tex" @@ -66,7 +67,7 @@ def sanitize_latex_code(latex: Union[str, int, float]): class SignPrinterLaTeX: # pylint: disable=too-many-instance-attributes - """Class encapsulating algorithm for creating printable signs from parts list. + """Class encapsulating algorithm for creating printable signs from thing list. Bad design choice: you have to create an object but actually this object is never used, could all just be module or class functions. @@ -97,15 +98,15 @@ class SignPrinterLaTeX: filecontents.append(file.read()) return filecontents - def if_use_landscape_template(self, part): - """Return if we want to use the landscape template for this part.""" + def if_use_landscape_template(self, thing): + """Return if we want to use the landscape template for this thing.""" try: - return part.sign.landscape + return thing.sign.landscape except AttributeError: - width, height = part.sign.size + width, height = thing.sign.size return width >= height * LANDSCAPE_MIN_RATIO - def guess_fontsize(self, part): + def guess_fontsize(self, thing): """Guess good fontsize. Based on the length of the name and the size of the sign. @@ -114,16 +115,16 @@ class SignPrinterLaTeX: guessed fontsize german, guessed fontsize english in UNIT """ # at first we do not support landscape signs - #if self.if_use_landscape_template(part): - # return self.guess_fontsize_landscape(part) - return self.guess_fontsize_portrait(part) + #if self.if_use_landscape_template(thing): + # return self.guess_fontsize_landscape(thing) + return self.guess_fontsize_portrait(thing) - def guess_fontsize_landscape(self, part): + def guess_fontsize_landscape(self, thing): """Guess good fontsizes for the landscape template.""" # for simplicity assume only one line - width, height = part.sign.size + width, height = thing.sign.size used_width = width - height # that is approximately the part the image uses - german, english = part.sign.display_name + german, english = thing.sign.display_name german_expected_width_at_standard = len(german) * STANDARD_LETTER_LENGTH german_max_by_width = (STANDARD_FONTSIZE_GERMAN * used_width / german_expected_width_at_standard) @@ -140,7 +141,7 @@ class SignPrinterLaTeX: return (min(german_max_by_width, german_max_by_height), min(english_max_by_width, english_max_by_height)) - def guess_fontsize_portrait(self, part): + def guess_fontsize_portrait(self, thing): # pylint: disable=too-many-locals """Guess what a good fontsize is for this sign. @@ -149,7 +150,7 @@ class SignPrinterLaTeX: Returns: guessed fontsize german, guessed fontsize english in UNIT """ - german, english = part.sign.display_name + german, english = thing.sign.display_name german_words = german.replace('-', "- ").split() german_words = german_words if len(german_words) > 0 else [' '] english_words = english.replace('-', " ").split() @@ -161,9 +162,9 @@ class SignPrinterLaTeX: ENGLISH_INDEX = 1 # pylint: disable=invalid-name SUM_INDEX = 2 # pylint: disable=invalid-name # self.logger.debug("g: {}; e: {}, width: {}, heigth: {}".format( - # german, english, *part.sign.size # unpacking pair + # german, english, *thing.sign.size # unpacking pair # )) - width, height = part.sign.size + width, height = thing.sign.size for german_number_lines, english_number_lines, case in [ (1, 1, 0), (1, 2, 1), (2, 1, 2), (2, 2, 3)]: german_length = max(max(len(word) for word in german_words) @@ -217,54 +218,54 @@ class SignPrinterLaTeX: # self.logger.debug("used fs: g: {:.3f}, e: {:.3f}".format(german_max, english_max)) return german_max, english_max - def get_fontsize(self, part): - """Determine font size of sign for part. + def get_fontsize(self, thing): + """Determine font size of sign for thing. - Take font size in the part. + Take font size in the thing. Guess font size if not specified. Returns: (german font size, english font size) """ try: - german_font_size = part.sign.fontsize_de + german_font_size = thing.sign.fontsize_de except AttributeError: german_font_size = None try: - english_font_size = part.sign.fontsize_en + english_font_size = thing.sign.fontsize_en except AttributeError: english_font_size = None if german_font_size is None and english_font_size is None: - german_font_size, english_font_size = self.guess_fontsize(part) + german_font_size, english_font_size = self.guess_fontsize(thing) elif german_font_size is None: # guessing guesses both together, not build for single guess # if you start to wriggle by hand with the font sizes, just do both german_font_size = STANDARD_FONTSIZE_GERMAN elif english_font_size is None: english_font_size = STANDARD_FONTSIZE_ENGLISH - logging.info(f"{part.name} font factor: (de) {german_font_size} (en) {english_font_size}") + logging.info(f"{thing.name} font factor: (de) {german_font_size} (en) {english_font_size}") return german_font_size, english_font_size - def create_latex(self, parts): + def create_latex(self, things): """Create latex code (as str) that shows all signs. Arguments: - parts: list of parts to be described + things: list of things to be described """ content_latex = [self.pre] current_line_filled_width = 0 - for part in [tmp_part for tmp_part in parts if tmp_part.sign.should_be_printed()]: - if current_line_filled_width + part.sign.size[0] > PAPER_TEXT_WIDTH: + for thing in [tmp_thing for tmp_thing in things if tmp_thing.sign.should_be_printed()]: + if current_line_filled_width + thing.sign.size[0] > PAPER_TEXT_WIDTH: content_latex.append("") # empty line in code makes new line (= row) in pdf current_line_filled_width = 0 - content_latex.append(self.create_sign(part)) - current_line_filled_width += part.sign.size[0] + content_latex.append(self.create_sign(thing)) + current_line_filled_width += thing.sign.size[0] content_latex.append(self.post) # type change of variable!: content_latex = "\n".join(content_latex) return content_latex - def get_values_for_template(self, part): + def get_values_for_template(self, thing): """Get values for the insertion into the templates. Only the values that are common for portrait @@ -278,13 +279,13 @@ class SignPrinterLaTeX: imageheight location """ - german, english = part.sign.display_name + german, english = thing.sign.display_name - width, height = part.sign.size + width, height = thing.sign.size width = width - 0.14 # todo: fix latex template or create constant insertions = {"GermanName": sanitize_latex_code(german), "EnglishName": sanitize_latex_code(english), - "location": sanitize_latex_code(str(part.where)), + "location": sanitize_latex_code(str(thing.where)), "height": height, "widthAdjusted": width} @@ -301,53 +302,53 @@ class SignPrinterLaTeX: insertions["vspace"] = "1pt" # at first only portrait sign, landscape sign can be implemented later - #if self.if_use_landscape_template(part): # would need different condition + #if self.if_use_landscape_template(thing): # would need different condition rel_path_to_image_dir = os.path.relpath( self.image_dir_landscape if insertions["imageheight"] < insertions['widthAdjusted'] else self.image_dir_portrait, self.output_dir) try: - insertions["imagepath"] = os.path.join(rel_path_to_image_dir, part.image) + insertions["imagepath"] = os.path.join(rel_path_to_image_dir, thing.image) except AttributeError: if insertions['imageheight'] > 0: # otherwise no image is printed and we do not need an unneccessary warning - logging.getLogger(__name__).warning(f'Missing image for {part.name} ' + logging.getLogger(__name__).warning(f'Missing image for {thing.name} ' f'(looking in {rel_path_to_image_dir}).') insertions["imagepath"] = os.path.join(TEMPLATE_DIR, DUMMY_IMAGE) - fontsizes = self.get_fontsize(part) + fontsizes = self.get_fontsize(thing) insertions["textscaleGerman"] = fontsizes[0] # /12 insertions["textscaleEnglish"] = fontsizes[1] # /12 try: - insertions["locationShiftDown"] = part.sign.location_shift_down + insertions["locationShiftDown"] = thing.sign.location_shift_down except AttributeError: insertions["locationShiftDown"] = STANDARD_LOCATION_SHIFT_DOWN return insertions - def create_sign(self, part): + def create_sign(self, thing): """Create a sign based on the template sign.tex.""" # text that is to be inserted into the template - insertions = self.get_values_for_template(part) + insertions = self.get_values_for_template(thing) # no landscape yet - #if self.if_use_landscape_template(part): + #if self.if_use_landscape_template(thing): # return self.signhtml_landscape.format( # **insertions # unpacking dictionary # ) return self.sign.format(**insertions) - def save_signs_latex(self, parts: Sequence[Part]): + def save_signs_latex(self, things: Sequence[Thing]): """Save signs as tex-file to file path. - Ignore parts that should not be printed as saved in part.sign.printed. + Ignore things that should not be printed as saved in things.sign.printed. Arguments: - parts: list of parts to visualize + things: list of things to visualize """ - parts.sort(key=lambda p: p.sign.size[1]) + things.sort(key=lambda p: p.sign.size[1]) file_signs = os.path.join(self.output_dir, self.signs_file) print(f"Print LaTeX file to {file_signs}.") with open(file_signs, mode="w", encoding="UTF-8") as latex_file: - latex_file.write(self.create_latex(parts)) + latex_file.write(self.create_latex(things)) diff --git a/signtemplate/header.css b/thingtemplate/header.css similarity index 100% rename from signtemplate/header.css rename to thingtemplate/header.css diff --git a/signtemplate/paper.css b/thingtemplate/paper.css similarity index 100% rename from signtemplate/paper.css rename to thingtemplate/paper.css diff --git a/signtemplate/sign.html b/thingtemplate/sign.html similarity index 100% rename from signtemplate/sign.html rename to thingtemplate/sign.html diff --git a/signtemplate/sign_landscape.html b/thingtemplate/sign_landscape.html similarity index 100% rename from signtemplate/sign_landscape.html rename to thingtemplate/sign_landscape.html diff --git a/signtemplate/template.html b/thingtemplate/template.html similarity index 100% rename from signtemplate/template.html rename to thingtemplate/template.html diff --git a/signtemplate_latex/.gitignore b/thingtemplate_latex/.gitignore similarity index 100% rename from signtemplate_latex/.gitignore rename to thingtemplate_latex/.gitignore diff --git a/signtemplate_latex/dummyImage.jpg b/thingtemplate_latex/dummyImage.jpg similarity index 100% rename from signtemplate_latex/dummyImage.jpg rename to thingtemplate_latex/dummyImage.jpg diff --git a/signtemplate_latex/sign.tex b/thingtemplate_latex/sign.tex similarity index 100% rename from signtemplate_latex/sign.tex rename to thingtemplate_latex/sign.tex diff --git a/signtemplate_latex/signlist-footer.tex b/thingtemplate_latex/signlist-footer.tex similarity index 100% rename from signtemplate_latex/signlist-footer.tex rename to thingtemplate_latex/signlist-footer.tex diff --git a/signtemplate_latex/signlist-header.tex b/thingtemplate_latex/signlist-header.tex similarity index 100% rename from signtemplate_latex/signlist-header.tex rename to thingtemplate_latex/signlist-header.tex diff --git a/signtemplate_latex/signs-example.tex b/thingtemplate_latex/signs-example.tex similarity index 100% rename from signtemplate_latex/signs-example.tex rename to thingtemplate_latex/signs-example.tex