diff --git a/PyTeX/format/formatting_config.py b/PyTeX/format/formatting_config.py index 38afef3..d585433 100644 --- a/PyTeX/format/formatting_config.py +++ b/PyTeX/format/formatting_config.py @@ -32,6 +32,10 @@ class FormattingConfig(Config): self._escape_character: Optional[str] = None + @classmethod + def from_yaml(cls, yaml): + pass + def merge_with(self, other, strict: bool = False): """ Merges the other config into this one diff --git a/PyTeX/format/pytex_formatter.py b/PyTeX/format/pytex_formatter.py index a98abd9..163cfcd 100644 --- a/PyTeX/format/pytex_formatter.py +++ b/PyTeX/format/pytex_formatter.py @@ -4,6 +4,9 @@ from .formatting_config import FormattingConfig from .enums import TeXType, TeXFlavour from .formatterif import FormatterIF from .generic_text import GenericText +import re +from .constants import * +from ..logger import logger class PyTeXFormatter(FormatterIF): @@ -12,17 +15,74 @@ class PyTeXFormatter(FormatterIF): input_file: Optional[Path] = None, config: Optional[FormattingConfig] = None, tex_type: Optional[TeXType] = None, - tex_flavour: Optional[TeXFlavour] = None + tex_flavour: Optional[TeXFlavour] = None, + locate_file_config: bool = True, + allow_infile_config: bool = True ): super().__init__( input_file=input_file, config=config ) - self._config: Optional[FormattingConfig] = self._config + self._config: Optional[FormattingConfig] = self._config # for type-hinting self._tex_type: Optional[TeXType] = tex_type self._tex_flavour: Optional[TeXFlavour] = tex_flavour + self._allow_infile_config = allow_infile_config self._header: Optional[GenericText] = None - self._formatted_header: Optional[str] = None + if locate_file_config: + file_config = self.parse_file_config() + if allow_infile_config: + infile_config = self.parse_infile_config() + self._config = \ + file_config.merge_with( + infile_config, + strict=True + ).merge_with(self._config, strict=False) + else: + self._config = file_config.merge_with(self._config) + else: + if allow_infile_config: + infile_config = self.parse_infile_config() + self._config = infile_config.merge_with(self._config) + + def parse_file_config(self) -> Optional[FormattingConfig]: + config_file = self.input_file.with_name(self.input_file.name + PYTEX_CONFIG_FILE_EXTENSION) + if config_file.exists(): + with open(config_file, 'r') as file: + config = file.readlines() + try: + return FormattingConfig.from_yaml(config) + except: + raise NotImplementedError # Invalid yaml file format + else: + return None + + def parse_infile_config(self) -> Optional[FormattingConfig]: + with open(self._input_file, "r") as file: + line = file.readline() + if re.match(self.config.escape_character + INFILE_CONFIG_BEGIN_CONFIG, line): + if not line.strip().lstrip('%').strip() == self.config.escape_character + INFILE_CONFIG_BEGIN_CONFIG: + logger.warning( + "File {file}: Start of infile config invalid." + ) + config = [] + while True: + line = file.readline() + if re.match(self.config.escape_character + INFILE_CONFIG_END_CONFIG, line): + if not line.strip().lstrip( + '%').strip() == self.config.escape_character + INFILE_CONFIG_END_CONFIG: + logger.warning( + "File {file}: End of infile config invalid." + ) + break + if line == '': + raise NotImplementedError # No matching end block + config.append(line.lstrip('%').rstrip()) + try: + return FormattingConfig.from_yaml(config) + except: + raise NotImplementedError # Invalid yaml file format + else: + return None @property def config(self) -> FormattingConfig: @@ -33,13 +93,13 @@ class PyTeXFormatter(FormatterIF): @property def header(self) -> GenericText: if self._header is None: - if not( - self.config.include_extra_header - or self.config.include_build_time - or self.config.include_pytex_version - or self.config.include_pytex_info_text - or self.config.include_repo_version - or self.config.include_repo_info_text + if not ( + self.config.include_extra_header + or self.config.include_build_time + or self.config.include_pytex_version + or self.config.include_pytex_info_text + or self.config.include_repo_version + or self.config.include_repo_info_text ): self._header = GenericText([]) else: