#!/usr/bin/env python3 import argparse import pathlib from pathlib import Path from typing import MutableMapping import yaml CARD_TEMPLATE = \ """\\documentclass{{standalone}} \\input{{common.tex}} \\begin{{document}} \\begin{{tikzpicture}} {0} \\cardborder \\end{{tikzpicture}} \\end{{document}}""" SET_SYMBOLS = { 'base': 'base', 'magic': 'magic', 'equipments': 'equipments', 'nautics': 'nautics', 'misc': '', 'kraken': 'kraken', 'exp1': 'exp1' } SCRIPT_PATH = Path(__file__).parent GAME_ROOT = SCRIPT_PATH.parent ASSETS_DIR = GAME_ROOT / 'assets' # all keys known by the rules KEYS = [ 'type', 'token', 'buy', 'upkeep', 'play', 'ai', 'health', 'movement', 'attack', 'full_action', 'effect' ] FORMATTED_KEYS = { 'en': { 'ai': 'AI', 'full_action': 'Full Action' }, 'de': { 'ai': 'KI', 'full_action': 'Volle-Aktion', 'type': 'Typ', 'buy': 'Kauf-Kosten', 'upkeep': 'Unterhalts-Kosten', 'play': 'Aktivierungs-Kosten', 'health': 'Leben', 'movement': 'Bewegung', 'attack': 'Angriff', 'effect': 'Effekt', 'durability': 'Haltbarkeit', } } def file_for_card(card_name: str, suffix='.tex') -> pathlib.Path: """Return the corresponding latex file name for a card""" return pathlib.Path(f'{card_name.lower().replace(" ", "_")}{suffix}') def get_field(card: MutableMapping, field: str, language='en') -> str: """Return the internationalized field value from a card""" value = card[field] if isinstance(value, dict): value = value.get(language, value['en']) return value def get_formatted_key(key: str, language='en') -> str: """Return the internationalized formatted version for key""" return FORMATTED_KEYS[language].get(key, key.capitalize()) def get_latex_field(card: MutableMapping, field: str, language='en') -> (str, bool): """Return the latex_ prefixed field from card or the field itself""" latex_field = f'latex_{field}' value = card.get(latex_field, card[field]) # internationalize if isinstance(value, dict): value = value.get(language, value['en']) return value, latex_field in card def generate_markdown(card: MutableMapping, language='en', indentation=3): """Output a markdown enumeration""" name = get_field(card, 'name', language) print(f'{"#" * indentation} {name}') # always use the englisch name as file name file_name = file_for_card(get_field(card, 'name', 'en'), "") yml_card_path = f'../cards-data/{card["set"]}/{file_name}.yml' built_card_path = f'../cards/{language}/{card["set"]}/{file_name}' print( f'\n[pdf]({built_card_path}.pdf) [png]({built_card_path}.png) [yml]({yml_card_path})\n' ) for key in KEYS: if key in card: formatted_key = get_formatted_key(key, language) value = get_field(card, key, language) print(f'* **{formatted_key}**: {value}') def generate_latex(card: MutableMapping, language='en'): """Generate a standalone tikz picture with the card data""" card_content = "" name, _ = get_latex_field(card, 'name', language) card_file = file_for_card(name) for ext in ['.jpg', '.png']: image_file = ASSETS_DIR / card_file.with_suffix(ext) if image_file.exists(): card_content += f'\\cardbackground{{{image_file.name}}}\n' break card_content += f'\\cardtype{card["type"].capitalize()}{"Token" if "token" in card else ""}{{{name}}}\n' if 'buy' in card: card_content += f'\\cardbuycost{{{card["buy"]}}}\n' if card['type'] == 'unit': stats = [] abilities = [] for key in ['ai', 'health', 'movement', 'attack']: if key in card: formatted_key = get_formatted_key(key, language) value = get_field(card, key, language) stats.append(f'{formatted_key}: {value}') if 'effect' in card: effect, _ = get_latex_field(card, 'effect', language) abilities.append(effect) if 'full_action' in card: full_action, is_latex = get_latex_field(card, 'full_action', language) if not is_latex: full_action = f'\\faRedo: {full_action}' abilities.append(full_action) stats_str = '\\\\'.join(stats) ability_block = '\\\\ \\vspace{0.2cm} '.join(abilities) if stats and abilities: card_content += f'\\cardsplitcontent{{{stats_str}}}{{{ability_block}}}' elif stats: card_content += f'\\cardcontent{{{stats_str}}}' card_content += '\n' if 'upkeep' in card: card_content += f'\\cardplaycost{{{card["upkeep"]}}}' elif card['type'] in ['spell', 'artifact']: effect, _ = get_latex_field(card, 'effect', language) assert effect is not None card_content += f'\\cardcontent{{{effect}}}\n' elif card['type'] == 'equipment': formatted_durability = get_formatted_key('durability') durability = get_field(card, 'durability', language) stats = f'{formatted_durability}: {durability}' effect, _ = get_latex_field(card, 'effect', language) card_content += f'\\cardsplitcontent{{{stats}}}{{{effect}}}\n' else: print(f'WARNING: unknown card type {card["type"]}!') if 'play' in card: card_content += f'\\cardplaycost{{{card["play"]}}}\n' if card['set'] in SET_SYMBOLS: card_content += f'\\cardmodule{{{SET_SYMBOLS[card["set"]]}}}' else: print(f'WARNING unknown set: {card["set"]}') print(CARD_TEMPLATE.format(card_content)) def main(): """Generate one standalone tikz picture for each card in the input data""" parser = argparse.ArgumentParser( description='generate latex standalone cards') parser.add_argument( 'data', help= 'yaml file or directory containing yaml files defining the cards to generate' ) parser.add_argument('--format', choices=['latex', 'markdown'], default='latex', help='output format') parser.add_argument('--language', choices=['en', 'de'], default='en', help='the language of the card text') args = parser.parse_args() data_files = [args.data] data_path = pathlib.Path(args.data) if data_path.is_dir(): data_files = data_path.glob('*.yml') card_set = data_path.stem else: card_set = data_path.parent.stem for data_file in data_files: with open(data_file, 'r') as yaml_file: card = yaml.full_load(yaml_file) card['set'] = card_set if args.format == 'latex': generate_latex(card, language=args.language) elif args.format == 'markdown': generate_markdown(card, language=args.language) if __name__ == '__main__': main()