Coverage for bookbuilderpy/preprocessor_input.py: 94%
36 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-17 23:15 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-17 23:15 +0000
1"""A preprocessor that loads one root file and resolves are relative inputs."""
3from os.path import dirname
4from typing import Final
6import bookbuilderpy.constants as bc
7from bookbuilderpy.logger import logger
8from bookbuilderpy.path import Path
9from bookbuilderpy.preprocessor_commands import create_preprocessor
10from bookbuilderpy.strings import enforce_non_empty_str, get_prefix_str
12#: the common prefix
13__REL_PREFIX: Final[str] = "\\" + get_prefix_str([bc.CMD_RELATIVE_CODE,
14 bc.CMD_RELATIVE_FIGURE,
15 bc.CMD_INPUT])
18def __load_input(input_file: str,
19 input_dir: str,
20 lang_id: str | None) -> str:
21 """
22 Recursively load an input file.
24 :param input_file: the input file
25 :param input_dir: the base directory
26 :param lang_id: the language to use
27 :return: the fully-resolved input
28 """
29 in_file = Path.file(input_file)
30 in_dir = Path.directory(input_dir)
31 in_dir.enforce_contains(in_file)
32 logger(f"now loading file '{in_file}'.")
34 text = in_file.read_all_str()
36 if __REL_PREFIX not in text:
37 return text
39 def __relative_input(_in_file: str,
40 _in_dir: Path = in_dir,
41 _lang: str | None = lang_id) -> str:
42 the_file = _in_dir.resolve_input_file(_in_file, _lang)
43 the_dir = Path.directory(dirname(the_file))
44 _in_dir.enforce_contains(the_dir)
45 return __load_input(the_file, the_dir, _lang)
47 rel_input = create_preprocessor(name=bc.CMD_INPUT,
48 func=__relative_input,
49 n=1,
50 strip_white_space=True,
51 wrap_in_newlines=2)
53 def __relative_code(_label: str,
54 _caption: str,
55 _in_file: str,
56 _lines: str,
57 _labels: str,
58 _args: str,
59 _in_dir: Path = in_dir,
60 _lang: str | None = lang_id) -> str:
61 f = _in_dir.resolve_input_file(_in_file, _lang)
62 return (f"\\{bc.CMD_ABSOLUTE_CODE}{{{_label}}}{{{_caption}}}"
63 f"{{{f}}}{{{_lines}}}{{{_labels}}}{{{_args}}}")
65 rel_code = create_preprocessor(name=bc.CMD_RELATIVE_CODE,
66 func=__relative_code,
67 n=6,
68 strip_white_space=True)
70 def __relative_figure(_label: str,
71 _caption: str,
72 _in_file: str,
73 _args: str,
74 _in_dir: Path = in_dir,
75 _lang: str | None = lang_id) -> str:
76 f = _in_dir.resolve_input_file(_in_file, _lang)
77 return (f"\\{bc.CMD_ABSOLUTE_FIGURE}{{{_label}}}{{{_caption}}}"
78 f"{{{f}}}{{{_args}}}")
80 rel_fig = create_preprocessor(name=bc.CMD_RELATIVE_FIGURE,
81 func=__relative_figure,
82 n=4,
83 strip_white_space=True)
85 return rel_input(rel_code(rel_fig(text)))
88def load_input(input_file: str,
89 input_dir: str,
90 lang_id: str | None) -> str:
91 """
92 Recursively load an input file.
94 :param input_file: the input file
95 :param input_dir: the base directory
96 :param lang_id: the language to use
97 :return: the fully-resolved input
98 """
99 logger(f"beginning to load file '{input_file}' from input dir "
100 f"'{input_dir}' under lang id '{lang_id}'.")
101 res = enforce_non_empty_str(enforce_non_empty_str(
102 __load_input(input_file=input_file,
103 input_dir=input_dir,
104 lang_id=lang_id)).strip())
105 logger(f"done loading input file '{input_file}' from input dir "
106 f"'{input_dir}' under lang id '{lang_id}', found {len(res)} "
107 f"characters.")
108 return res