From 6a09adac85591c1d0c75623db987789030f67185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ke=C3=9Fler?= Date: Sun, 6 Feb 2022 16:50:09 +0100 Subject: [PATCH] implement dict formatter --- PyTeX/format/constants.py | 2 + PyTeX/format/dict_formatter.py | 89 ++++++++++++++++++++++++++++++++-- PyTeX/format/formatterif.py | 7 +-- PyTeX/format/generic_text.py | 10 +++- 4 files changed, 100 insertions(+), 8 deletions(-) diff --git a/PyTeX/format/constants.py b/PyTeX/format/constants.py index f709b3a..e7f1a41 100644 --- a/PyTeX/format/constants.py +++ b/PyTeX/format/constants.py @@ -1,3 +1,5 @@ INFILE_CONFIG_BEGIN_CONFIG = 'config' INFILE_CONFIG_END_CONFIG = 'endconfig' PYTEX_CONFIG_FILE_EXTENSION = '.conf' +DICTIONARY_KEY_COLUMN_NAME = 'key' +DICTIONARY_NAMING_PATTERN = 'translator-{dict_name}-dictionary-{language}.dict' diff --git a/PyTeX/format/dict_formatter.py b/PyTeX/format/dict_formatter.py index 0eda931..1ff5c91 100644 --- a/PyTeX/format/dict_formatter.py +++ b/PyTeX/format/dict_formatter.py @@ -1,5 +1,88 @@ -from .formatterif import FormatterIF +from pathlib import Path +from typing import List, Dict, Tuple, Optional +import csv +from .pytex_formatter import PyTeXFormatter +from .constants import * +from ..logger import logger -class DictFormatter(FormatterIF): - pass +class DictFormatter(PyTeXFormatter): + def __init__(self, *args, **kwargs): + super(DictFormatter, self).__init__(*args, **kwargs) + with open(self.input_file, 'r') as file: + line = file.readline() + parts = [entry.strip() for entry in line.split(',')] + if not len(parts) >= 1: + raise NotImplementedError + if not parts[0] == DICTIONARY_KEY_COLUMN_NAME: + raise NotImplementedError + self._languages = parts[1:] + self._dict_name = self.input_file.name.split('.')[0] + self._translations = None + + @property + def translations(self) -> Dict: + if self._translations is None: + self._translations = self.parse() + return self._translations + + def output_files(self) -> List[str]: + return [ + DICTIONARY_NAMING_PATTERN.format( + dict_name=self._dict_name, + language=language + ) + for language in self._languages + ] + + def parse(self) -> Dict: + with open(self.input_file, newline='') as csvfile: + spamreader = csv.reader(csvfile, delimiter=',', quotechar='|') + next(spamreader) # Skip languages line + translations = {} + for language in self._languages: + translations[language] = {} + for line in spamreader: + if not len(line) == len(self._languages) + 1: + raise NotImplementedError # Invalid file format + for n in range(1, len(line)): + translations[self._languages[n]][line[0]] = line[n] + return translations + + def format(self, build_dir: Path, overwrite: bool = False) -> Optional[List[Tuple[str, Dict]]]: + build_dir.mkdir(parents=True, exist_ok=True) + self.format_header() + for language in self._languages: + lines = [self.header, ''] + lines += r'\ProvidesDictionary{{{dict_name}}}{{{language}}}'.format( + dict_name=self._dict_name, + language=language + ) + lines += ['\n']*2 + for key in self.translations[language].keys(): + if self.translations[language][key].strip() != '': + lines += r'\providetranslation{{{key}}}{{{translation}}}'.format( + key=key.strip(), + translation=self.translations[language][key].strip() + ) + lines += '\n' + else: + logger.warning( + 'Empty translation key found in {filename}'.format( + filename=self.input_file.name + ) + ) + output_file = build_dir / DICTIONARY_NAMING_PATTERN.format( + language=language, + dict_name=self._dict_name + ) + if not overwrite and output_file.exists(): + raise NotImplementedError + else: + output_file.write_text( + '\n'.join(lines) + ) + logger.info( + f'Successfully wrote dictionary file {output_file.name}.' + ) + return None # No future configuration needed diff --git a/PyTeX/format/formatterif.py b/PyTeX/format/formatterif.py index dcce840..916fe28 100644 --- a/PyTeX/format/formatterif.py +++ b/PyTeX/format/formatterif.py @@ -19,14 +19,15 @@ class FormatterIF: self._input_file: Optional[Path] = input_file self._config: Optional[Config] = config - def format(self, build_dir: Path) -> Optional[List[Tuple[str, Dict]]]: + def format(self, build_dir: Path, overwrite: bool = False) -> Optional[List[Tuple[str, Dict]]]: """ :param build_dir: Directory where output files are written to + :param overwrite: overwrite existing files :return: When configuration files are needed for a future build of the output files, a list of the file names and their needed configurations. Else None. """ - pass + raise NotImplementedError @property def output_files(self) -> List[str]: @@ -34,7 +35,7 @@ class FormatterIF: :return: List of files that will be built when the formatter is invoked """ - pass + raise NotImplementedError @property def input_file(self) -> Path: diff --git a/PyTeX/format/generic_text.py b/PyTeX/format/generic_text.py index 3445fa1..40a0780 100644 --- a/PyTeX/format/generic_text.py +++ b/PyTeX/format/generic_text.py @@ -1,5 +1,6 @@ from pathlib import Path from typing import Union, List, Optional +from ..logger import logger class GenericText: @@ -33,12 +34,17 @@ class GenericText: self._path = content def format(self, **kwargs) -> str: + lines = [] for line in self._content: try: - line = line.format(**kwargs) + line = '% ' + line.format(**kwargs).rjust(77) + '%' + if len(line) > 80: + logger.warning( + 'Line too long') # TODO + lines.append(line) except ValueError: raise NotImplementedError - return '\n'.join(self._content) + return '\n'.join(lines) def __add__(self, other): if isinstance(other, GenericText):