import sys import re import json import sys import jinja2 import os import contextlib from jinja2 import Template import argparse from functools import lru_cache @lru_cache(maxsize=5) def get_template(name): latex_jinja_env = jinja2.Environment( block_start_string="\\BLOCK{", block_end_string="}", variable_start_string="\\VAR{", variable_end_string="}", comment_start_string="\\#{", comment_end_string="}", line_statement_prefix="%%", line_comment_prefix="%#", trim_blocks=True, autoescape=False, loader=jinja2.FileSystemLoader( os.path.abspath(os.path.join(os.path.dirname(__file__), "templates/")) ), ) template = latex_jinja_env.get_template(f"{name}.tex.jinja") return template def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--spells", "-f", type=str, nargs="+") parser.add_argument("characterclass", type=str, default="All") parser.add_argument("--sort", "-s", type=str, default="level") parser.add_argument("--twosided", "-2", action="store_true") parser.add_argument("--output", "-o", nargs="?") return parser.parse_args() def spell_sorter(sortby): def sort_spell(x): srt = "" for elem in sortby: srt += str(x[1][elem]) return srt return sort_spell def main(): args = parse_args() spells = {} for f in args.spells: with open(f) as jf: spells.update(json.load(jf)) if args.characterclass != "All": spells = dict( filter(lambda x: args.characterclass in x[1]["classes"], spells.items()) ) spells = dict(sorted(spells.items(), key=spell_sorter(args.sort.split(",")))) pages = generate_pages(spells, args.twosided) filename = args.output if args.output is not None else args.characterclass write_doc(filename, pages) def write_doc(filename, pages): with open(f"{filename}.tex", "w+") as of: of.write(get_template("spelldeck").render(content="".join(pages))) def generate_pages(spells, twosided=False): spellpages = [] back = get_template("spellcard_back").render() for i in range(0, len(spells) + 9, 10): spellpages.append(generate_page(list(spells.items())[i : i + 10])) if twosided: spellpages.append(back) if not twosided: spellpages.append(back) return spellpages def generate_page(spells): pagetemplate = get_template("spellpage") data = {} for i, spell in enumerate(spells): data[f"spell{i}"] = generate_spell(*spell) return pagetemplate.render(**data) def generate_spell(spellname, spell): template = get_template("spellcard") spell["text"] = latex_format(spell["text"]) if "text_card" in spell: spell["text_card"] = latex_format(spell["text_card"]) return template.render(title=spellname, **spell) def latex_format(text): text = re.sub(r"\*(?! )(([^*])*?)(?! )\*", r"\\textbf{\1}", text) text = re.sub( r"(\s|\()([0-9]*W(?:4|6|8|10|12|20)(?:\s*\+[0-9]+)?)", r"\1\\textbf{\2}", text ) text = re.sub(r"([0-9]+)\sm", r"\1~m", text) text = re.sub(r"&", r"\&", text) return text if __name__ == "__main__": main()