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

1"""A preprocessor that loads one root file and resolves are relative inputs.""" 

2 

3from os.path import dirname 

4from typing import Final 

5 

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 

11 

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]) 

16 

17 

18def __load_input(input_file: str, 

19 input_dir: str, 

20 lang_id: str | None) -> str: 

21 """ 

22 Recursively load an input file. 

23 

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}'.") 

33 

34 text = in_file.read_all_str() 

35 

36 if __REL_PREFIX not in text: 

37 return text 

38 

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) 

46 

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) 

52 

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}}}") 

64 

65 rel_code = create_preprocessor(name=bc.CMD_RELATIVE_CODE, 

66 func=__relative_code, 

67 n=6, 

68 strip_white_space=True) 

69 

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}}}") 

79 

80 rel_fig = create_preprocessor(name=bc.CMD_RELATIVE_FIGURE, 

81 func=__relative_figure, 

82 n=4, 

83 strip_white_space=True) 

84 

85 return rel_input(rel_code(rel_fig(text))) 

86 

87 

88def load_input(input_file: str, 

89 input_dir: str, 

90 lang_id: str | None) -> str: 

91 """ 

92 Recursively load an input file. 

93 

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