pytex/PyTeX/build/build/pytex_file.py

88 lines
3 KiB
Python

from pathlib import Path
from typing import Optional, List, Dict, Tuple, Union
from .relative_path import RelativePath
from PyTeX.format.formatterif import FormatterIF
from PyTeX.build.build.enums import PyTeXFileType
from .hashing import md5
from ...exceptions import PyTeXException
from ...format.errors import PyTeXError
from ...format.formatting_config import FormattingConfig
from ...format.auto_format import formatter_from_file_extension
from ...format.git_version_info import GitVersionInfo
class PyTeXSourceFile:
def __init__(
self,
relative_path: RelativePath,
formatter: Optional[FormatterIF] = None,
default_config: Optional[FormattingConfig] = None,
git_version_info: Optional[GitVersionInfo] = None,
pytex_file_type: Optional[PyTeXFileType] = None
):
self._relative_path: RelativePath = relative_path
if formatter is not None:
self._formatter: FormatterIF = formatter
else:
self._formatter = formatter_from_file_extension(
relative_path.path,
config=default_config,
git_version_info=git_version_info,
locate_file_config=True,
allow_infile_config=True
)
self._pytex_file_type: Optional[PyTeXFileType] = pytex_file_type
self._file_hash: Optional[str] = None
@property
def file_hash(self) -> str:
if self._file_hash is None:
self.update_file_hash()
return self._file_hash
def update_file_hash(self):
self._file_hash = md5(self._relative_path.path)
@property
def relative_path(self) -> RelativePath:
return self._relative_path
@property
def pytex_file_type(self) -> Optional[PyTeXFileType]:
return self._pytex_file_type
@property
def output_files(self) -> List[RelativePath]:
if self._formatter is None:
raise NotImplementedError # TODO
files: List[str] = self._formatter.output_files
paths = [
RelativePath(self._relative_path.root_dir, self._relative_path.with_name(filename))
for filename in files
]
return paths
@property
def formatter(self) -> Optional[FormatterIF]:
return self._formatter
@formatter.setter
def formatter(self, formatter):
self._formatter = formatter
def format(self, target_root: Union[Path, RelativePath]) -> List[Tuple[RelativePath, FormattingConfig]]:
if self._formatter is None:
raise NotImplementedError # TODO
try:
configs = self._formatter.format(
target_root.path if isinstance(target_root, RelativePath) else target_root
)
except PyTeXError as e:
e.add_explanation(f'while processing {str(self.relative_path.path)}')
raise e
rel_configs = [
(self._relative_path.with_name(filename), config)
for [filename, config] in configs
]
return rel_configs